From 635230d5072d98ae5318fcaa07ee06bc7456ca44 Mon Sep 17 00:00:00 2001 From: hugosmoreira Date: Sat, 25 Jul 2026 23:43:16 -0700 Subject: [PATCH 1/3] docs(rsc): document stable client chunks --- packages/plugin-rsc/README.md | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/packages/plugin-rsc/README.md b/packages/plugin-rsc/README.md index e2d11b867..41124fcb5 100644 --- a/packages/plugin-rsc/README.md +++ b/packages/plugin-rsc/README.md @@ -555,6 +555,48 @@ and React client environments in the browser. ## Tips +### Stable client chunks + +You can use Rollup's `manualChunks` 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: { + rollupOptions: { + output: { + manualChunks(id) { + if ( + id.includes('/node_modules/react/') || + id.includes('/node_modules/react-dom/') || + id.includes(reactServerDom) + ) { + return 'lib-react' + } + if (id === '\0vite/preload-helper.js') { + return 'lib-vite' + } + }, + }, + }, + }, + }, + }, +}) +``` + +Use the functional form of `manualChunks` 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. From 4ff312d8cb29816721a530bdb6eb488578b9597f Mon Sep 17 00:00:00 2001 From: hugosmoreira Date: Sun, 26 Jul 2026 20:24:26 -0700 Subject: [PATCH 2/3] docs(rsc): use Rolldown code splitting groups --- packages/plugin-rsc/README.md | 34 +++++++++++-------- .../plugin-rsc/examples/basic/vite.config.ts | 31 +++++++++-------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/packages/plugin-rsc/README.md b/packages/plugin-rsc/README.md index 41124fcb5..5180a6448 100644 --- a/packages/plugin-rsc/README.md +++ b/packages/plugin-rsc/README.md @@ -557,7 +557,7 @@ and React client environments in the browser. ### Stable client chunks -You can use Rollup's `manualChunks` option to keep React and Vite runtime code in stable client chunks. This allows browsers to reuse these chunks when application code changes. +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' @@ -573,19 +573,25 @@ export default defineConfig({ environments: { client: { build: { - rollupOptions: { + rolldownOptions: { output: { - manualChunks(id) { - if ( - id.includes('/node_modules/react/') || - id.includes('/node_modules/react-dom/') || - id.includes(reactServerDom) - ) { - return 'lib-react' - } - if (id === '\0vite/preload-helper.js') { - return 'lib-vite' - } + 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', + }, + ], }, }, }, @@ -595,7 +601,7 @@ export default defineConfig({ }) ``` -Use the functional form of `manualChunks` 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`. +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 diff --git a/packages/plugin-rsc/examples/basic/vite.config.ts b/packages/plugin-rsc/examples/basic/vite.config.ts index 36445f291..41dc9617c 100644 --- a/packages/plugin-rsc/examples/basic/vite.config.ts +++ b/packages/plugin-rsc/examples/basic/vite.config.ts @@ -137,21 +137,24 @@ export default defineConfig({ environments: { client: { build: { - rollupOptions: { + rolldownOptions: { 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) - ) { - return 'lib-react' - } - if (id === '\0vite/preload-helper.js') { - return 'lib-vite' - } + codeSplitting: { + groups: [ + { + name: 'lib-react', + // use a function to handle commonjs plugin proxy modules + // e.g. `(id)?commonjs-es-import` + test: (id) => + id.includes('node_modules/react/') || + id.includes('node_modules/react-dom/') || + id.includes(reactServerDom), + }, + { + name: 'lib-vite', + test: (id) => id === '\0vite/preload-helper.js', + }, + ], }, }, }, From eb747b6cdede07a0cd7f5a904b83a6ddc0258a62 Mon Sep 17 00:00:00 2001 From: hugosmoreira Date: Sun, 26 Jul 2026 20:56:29 -0700 Subject: [PATCH 3/3] test(rsc): support Vite 7 chunk config --- .../plugin-rsc/examples/basic/vite.config.ts | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/packages/plugin-rsc/examples/basic/vite.config.ts b/packages/plugin-rsc/examples/basic/vite.config.ts index 41dc9617c..a4c3596d1 100644 --- a/packages/plugin-rsc/examples/basic/vite.config.ts +++ b/packages/plugin-rsc/examples/basic/vite.config.ts @@ -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({ @@ -133,10 +134,15 @@ 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: { output: { codeSplitting: { @@ -145,20 +151,36 @@ export default defineConfig({ name: 'lib-react', // use a function to handle commonjs plugin proxy modules // e.g. `(id)?commonjs-es-import` - test: (id) => - id.includes('node_modules/react/') || - id.includes('node_modules/react-dom/') || - id.includes(reactServerDom), + test: isReactChunk, }, { name: 'lib-vite', - test: (id) => id === '\0vite/preload-helper.js', + test: isViteChunk, }, ], }, }, }, - }, + } + : { + rollupOptions: { + output: { + manualChunks(id: string) { + if (isReactChunk(id)) { + return 'lib-react' + } + if (isViteChunk(id)) { + return 'lib-vite' + } + }, + }, + }, + } + + return { + environments: { + client: { + build, }, }, }