@@ -2,9 +2,16 @@ import assert from 'node:assert'
22import rsc , { transformHoistInlineDirective } from '@vitejs/plugin-rsc'
33import tailwindcss from '@tailwindcss/vite'
44import react from '@vitejs/plugin-react'
5- import { type Plugin , defineConfig , normalizePath , parseAstAsync } from 'vite'
5+ import {
6+ type Plugin ,
7+ type Rollup ,
8+ defineConfig ,
9+ normalizePath ,
10+ parseAstAsync ,
11+ } from 'vite'
612// import inspect from 'vite-plugin-inspect'
713import path from 'node:path'
14+ import { fileURLToPath } from 'node:url'
815
916export default defineConfig ( {
1017 clearScreen : false ,
@@ -88,6 +95,78 @@ export default defineConfig({
8895 }
8996 } ,
9097 } ,
98+ {
99+ name : 'optimize-chunks' ,
100+ apply : 'build' ,
101+ config ( ) {
102+ const resolvePackageSource = ( source : string ) =>
103+ normalizePath ( fileURLToPath ( import . meta. resolve ( source ) ) )
104+
105+ // TODO: this package entry isn't a public API.
106+ const reactServerDom = resolvePackageSource (
107+ '@vitejs/plugin-rsc/react/browser' ,
108+ )
109+
110+ return {
111+ environments : {
112+ client : {
113+ build : {
114+ rollupOptions : {
115+ output : {
116+ manualChunks : ( id ) => {
117+ // need to use functional form to handle commonjs plugin proxy module
118+ // e.g. `(id)?commonjs-es-import`
119+ if (
120+ id . includes ( 'node_modules/react/' ) ||
121+ id . includes ( 'node_modules/react-dom/' ) ||
122+ id . includes ( reactServerDom )
123+ ) {
124+ return 'lib-react'
125+ }
126+ if ( id === '\0vite/preload-helper.js' ) {
127+ return 'lib-vite'
128+ }
129+ } ,
130+ } ,
131+ } ,
132+ } ,
133+ } ,
134+ } ,
135+ }
136+ } ,
137+ // verify chunks are "stable"
138+ writeBundle ( _options , bundle ) {
139+ if ( this . environment . name === 'client' ) {
140+ const entryChunks : Rollup . OutputChunk [ ] = [ ]
141+ const libChunks : Record < string , Rollup . OutputChunk [ ] > = { }
142+ for ( const chunk of Object . values ( bundle ) ) {
143+ if ( chunk . type === 'chunk' ) {
144+ if ( chunk . isEntry ) {
145+ entryChunks . push ( chunk )
146+ }
147+ if ( chunk . name . startsWith ( 'lib-' ) ) {
148+ ; ( libChunks [ chunk . name ] ??= [ ] ) . push ( chunk )
149+ }
150+ }
151+ }
152+
153+ // react vendor chunk has no import
154+ assert . equal ( libChunks [ 'lib-react' ] . length , 1 )
155+ assert . deepEqual (
156+ // https://rolldown.rs/guide/in-depth/advanced-chunks#why-there-s-always-a-runtime-js-chunk
157+ libChunks [ 'lib-react' ] [ 0 ] . imports . filter (
158+ ( f ) => ! f . includes ( 'rolldown-runtime' ) ,
159+ ) ,
160+ [ ] ,
161+ )
162+ assert . deepEqual ( libChunks [ 'lib-react' ] [ 0 ] . dynamicImports , [ ] )
163+
164+ // entry chunk has no export
165+ assert . equal ( entryChunks . length , 1 )
166+ assert . deepEqual ( entryChunks [ 0 ] . exports , [ ] )
167+ }
168+ } ,
169+ } ,
91170 {
92171 name : 'cf-build' ,
93172 enforce : 'post' ,
0 commit comments