1- import path from 'path' ;
2-
31import { defineConfig , loadEnv } from 'vite' ;
42import react from '@vitejs/plugin-react' ;
53import eslint from '@nabla/vite-plugin-eslint' ;
64
7- /**
8- * Rolldown (Vite 8 dep pre-bundler) has a bug: when @mui/material and any
9- * @mui /material/* subpath are both dep-optimization entries, Rolldown creates
10- * shared chunks that CALL init_*() functions without defining or importing
11- * them — causing ReferenceErrors in the browser.
12- *
13- * This plugin fixes that in two passes over the generateBundle output:
14- * Pass 1 — catalogue every init_* definition and export across all chunks
15- * Pass 2 — for each chunk with dangling init_* calls:
16- * a) if the function is already exported elsewhere → add import
17- * b) if the function is defined but unexported elsewhere →
18- * add an export to that chunk, then add the import here
19- */
20- const fixRolldownDanglingInits = {
21- name : 'fix-rolldown-dangling-inits' ,
22- generateBundle ( _opts : unknown , bundle : Record < string , any > ) {
23- type InitInfo = { file : string ; exported : boolean ; alias : string } ;
24- // localName → { file, exported, alias }
25- const initMap = new Map < string , InitInfo > ( ) ;
26-
27- // ── Pass 1: catalogue ──────────────────────────────────────────────────
28- for ( const [ fileName , chunk ] of Object . entries ( bundle ) ) {
29- if ( chunk . type !== 'chunk' ) continue ;
30- const code : string = chunk . code ?? '' ;
31-
32- // Collect all var init_XXX = __esmMin(...) definitions (unexported by default)
33- for ( const m of code . matchAll ( / \b v a r ( i n i t _ \w + ) \s * = \s * _ _ e s m M i n / g) ) {
34- const name = m [ 1 ] ;
35- if ( ! initMap . has ( name ) ) {
36- initMap . set ( name , { file : fileName , exported : false , alias : name } ) ;
37- }
38- }
39-
40- // Mark exported ones and record their export alias
41- for ( const exportMatch of code . matchAll ( / e x p o r t \s * \{ ( [ ^ } ] + ) \} / g) ) {
42- for ( const item of exportMatch [ 1 ] . split ( ',' ) . map ( ( s ) => s . trim ( ) ) ) {
43- const m = item . match ( / ^ ( \w + ) \s + a s \s + ( \w + ) $ / ) ;
44- if ( m && m [ 1 ] . startsWith ( 'init_' ) ) {
45- const entry = initMap . get ( m [ 1 ] ) ;
46- if ( entry ) {
47- entry . exported = true ;
48- entry . alias = m [ 2 ] ;
49- } else {
50- initMap . set ( m [ 1 ] , {
51- file : fileName ,
52- exported : true ,
53- alias : m [ 2 ] ,
54- } ) ;
55- }
56- } else if ( / ^ \w + $ / . test ( item ) && item . startsWith ( 'init_' ) ) {
57- const entry = initMap . get ( item ) ;
58- if ( entry ) {
59- entry . exported = true ;
60- entry . alias = item ;
61- } else {
62- initMap . set ( item , {
63- file : fileName ,
64- exported : true ,
65- alias : item ,
66- } ) ;
67- }
68- }
69- }
70- }
71- }
72-
73- // ── Pass 2: fix dangling calls ─────────────────────────────────────────
74- for ( const [ , chunk ] of Object . entries ( bundle ) ) {
75- if ( chunk . type !== 'chunk' ) continue ;
76- const code : string = chunk . code ?? '' ;
77-
78- const importLines = code
79- . split ( '\n' )
80- . filter ( ( l : string ) => l . trimStart ( ) . startsWith ( 'import ' ) ) ;
81-
82- const calledInits = new Set (
83- [ ...code . matchAll ( / \b ( i n i t _ \w + ) \( \) / g) ] . map ( ( m ) => m [ 1 ] )
84- ) ;
85-
86- const toAdd : string [ ] = [ ] ;
87-
88- for ( const initName of calledInits ) {
89- const defined =
90- code . includes ( `var ${ initName } =` ) ||
91- code . includes ( `function ${ initName } (` ) ;
92- const imported = importLines . some ( ( l : string ) => l . includes ( initName ) ) ;
93- if ( defined || imported ) continue ; // already ok
94-
95- const info = initMap . get ( initName ) ;
96- if ( ! info ) continue ;
97-
98- // Ensure the function is exported from its source chunk
99- if ( ! info . exported ) {
100- const srcChunk = bundle [ info . file ] ;
101- if ( srcChunk ?. type === 'chunk' ) {
102- srcChunk . code =
103- ( srcChunk . code as string ) + `\nexport { ${ initName } };\n` ;
104- srcChunk . map = null ;
105- info . exported = true ;
106- info . alias = initName ; // use full name since we control the export
107- }
108- }
109-
110- if ( info . exported ) {
111- const stmt = `import { ${ info . alias } as ${ initName } } from "./${ info . file } ";` ;
112- if ( ! toAdd . includes ( stmt ) ) toAdd . push ( stmt ) ;
113- }
114- }
115-
116- if ( toAdd . length > 0 ) {
117- chunk . code = toAdd . join ( '\n' ) + '\n' + code ;
118- chunk . map = null ;
119- }
120- }
121- } ,
122- } ;
123-
1245export default ( { mode } : any ) => {
1256 // Load app-level env vars to node-level env vars.
1267 process . env = { ...process . env , ...loadEnv ( mode , process . cwd ( ) ) } ;
@@ -136,26 +17,6 @@ export default ({ mode }: any) => {
13617 } ,
13718 resolve : {
13819 tsconfigPaths : true ,
139- alias : {
140- // Rolldown (Vite 8) doesn't auto-synthesize CJS default exports;
141- // redirect all @mui /icons-material sub-path imports to the ESM build.
142- '@mui/icons-material' : path . resolve (
143- __dirname ,
144- 'node_modules/@mui/icons-material/esm'
145- ) ,
146- screens : path . resolve ( __dirname , './src/screens' ) ,
147- } ,
148- } ,
149- optimizeDeps : {
150- include : [
151- '@emotion/react' ,
152- '@emotion/styled' ,
153- '@emotion/cache' ,
154- '@mui/material' ,
155- ] ,
156- rolldownOptions : {
157- plugins : [ fixRolldownDanglingInits ] ,
158- } ,
15920 } ,
16021 build : {
16122 outDir : 'build' ,
0 commit comments