diff --git a/packages/plugin-rsc/examples/basic/vite.config.ts b/packages/plugin-rsc/examples/basic/vite.config.ts index 198838c1..a804fb84 100644 --- a/packages/plugin-rsc/examples/basic/vite.config.ts +++ b/packages/plugin-rsc/examples/basic/vite.config.ts @@ -2,9 +2,16 @@ import assert from 'node:assert' import rsc, { transformHoistInlineDirective } from '@vitejs/plugin-rsc' import tailwindcss from '@tailwindcss/vite' import react from '@vitejs/plugin-react' -import { type Plugin, defineConfig, normalizePath, parseAstAsync } from 'vite' +import { + type Plugin, + Rollup, + defineConfig, + normalizePath, + parseAstAsync, +} from 'vite' import inspect from 'vite-plugin-inspect' import path from 'node:path' +import { fileURLToPath } from 'node:url' // log unhandled rejection to debug e2e failures if (!(globalThis as any).__debugHandlerRegisterd) { @@ -104,6 +111,76 @@ export default defineConfig({ } }, }, + { + name: 'optimize-chunks', + apply: 'build', + config() { + const resolvePackageSource = (source: string) => + normalizePath(fileURLToPath(import.meta.resolve(source))) + + // TODO: this entrypoint shouldn't be a public API. + const pkgBrowserPath = resolvePackageSource( + '@vitejs/plugin-rsc/react/browser', + ) + + return { + environments: { + client: { + build: { + 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(pkgBrowserPath) + ) { + return 'lib-react' + } + if (id === '\0vite/preload-helper.js') { + return 'lib-vite' + } + }, + }, + }, + }, + }, + }, + } + }, + // verify chunks are "stable" + writeBundle(_options, bundle) { + if (this.environment.name === 'client') { + const entryChunks: Rollup.OutputChunk[] = [] + const vendorChunks: Rollup.OutputChunk[] = [] + for (const chunk of Object.values(bundle)) { + if (chunk.type === 'chunk') { + if (chunk.facadeModuleId?.endsWith('/src/client.tsx')) { + entryChunks.push(chunk) + } else if (chunk.name === 'lib-react') { + vendorChunks.push(chunk) + } + } + } + + // react vendor chunk has no import + assert.equal(vendorChunks.length, 1) + assert.deepEqual( + vendorChunks[0].imports.filter( + (f) => !f.includes('rolldown-runtime'), + ), + [], + ) + assert.deepEqual(vendorChunks[0].dynamicImports, []) + + // entry chunk has no export + assert.equal(entryChunks.length, 1) + assert.deepEqual(entryChunks[0].exports, []) + } + }, + }, { name: 'cf-build', enforce: 'post',