Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions packages/plugin-rsc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,54 @@ and React client environments in the browser.

## Tips

### Stable client chunks

You can use Rolldown's `codeSplitting.groups` option to keep React and Vite runtime code in stable client chunks. This allows browsers to reuse these chunks when application code changes.

```ts
import { fileURLToPath } from 'node:url'
import rsc from '@vitejs/plugin-rsc'
import { defineConfig, normalizePath } from 'vite'

const reactServerDom = normalizePath(
fileURLToPath(import.meta.resolve('@vitejs/plugin-rsc/react/browser')),
)

export default defineConfig({
plugins: [rsc()],
environments: {
client: {
build: {
rolldownOptions: {
output: {
codeSplitting: {
groups: [
{
name: 'lib-react',
test(id) {
return (
id.includes('/node_modules/react/') ||
id.includes('/node_modules/react-dom/') ||
id.includes(reactServerDom)
)
},
},
{
name: 'lib-vite',
test: (id) => id === '\0vite/preload-helper.js',
},
],
},
},
},
},
},
},
})
```

Use a function for the `lib-react` group test so the React Server Components runtime is included even when the CommonJS plugin adds a proxy suffix to its module ID, such as `?commonjs-es-import`.

### CSS Support

The plugin automatically handles CSS code-splitting and injection for server components. This eliminates the need to manually call [`import.meta.viteRsc.loadCss()`](#importmetaviterscloadcss) in most cases.
Expand Down
53 changes: 39 additions & 14 deletions packages/plugin-rsc/examples/basic/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url'
import tailwindcss from '@tailwindcss/vite'
import react from '@vitejs/plugin-react'
import rsc from '@vitejs/plugin-rsc'
import * as vite from 'vite'
import { type Plugin, type Rollup, defineConfig, normalizePath } from 'vite'

export default defineConfig({
Expand Down Expand Up @@ -123,29 +124,53 @@ export default defineConfig({
'@vitejs/plugin-rsc/react/browser',
)

return {
environments: {
client: {
build: {
const isReactChunk = (id: string) =>
id.includes('node_modules/react/') ||
id.includes('node_modules/react-dom/') ||
id.includes(reactServerDom)
const isViteChunk = (id: string) => id === '\0vite/preload-helper.js'

const build =
'rolldownVersion' in vite
? {
rolldownOptions: {
Comment thread
hugosmoreira marked this conversation as resolved.
output: {
codeSplitting: {
groups: [
{
name: 'lib-react',
// use a function to handle commonjs plugin proxy modules
// e.g. `(id)?commonjs-es-import`
test: isReactChunk,
},
{
name: 'lib-vite',
test: isViteChunk,
},
],
},
},
},
}
: {
rollupOptions: {
output: {
manualChunks: (id) => {
// need to use functional form to handle commonjs plugin proxy module
// e.g. `(id)?commonjs-es-import`
if (
id.includes('node_modules/react/') ||
id.includes('node_modules/react-dom/') ||
id.includes(reactServerDom)
) {
manualChunks(id: string) {
if (isReactChunk(id)) {
return 'lib-react'
}
if (id === '\0vite/preload-helper.js') {
if (isViteChunk(id)) {
return 'lib-vite'
}
},
},
},
},
}

return {
environments: {
client: {
build,
},
},
}
Expand Down
Loading