@@ -10,11 +10,11 @@ import type {
1010} from 'vite'
1111import type { RollupOptions } from 'rollup'
1212import libEsm from 'lib-esm'
13- import cjsShim from './cjs-shim'
1413
1514const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) )
1615const builtins = builtinModules . filter ( m => ! m . startsWith ( '_' ) ) ; builtins . push ( ...builtins . map ( m => `node:${ m } ` ) )
1716const electronBuiltins = [ 'electron' , ...builtins ]
17+ const PACKAGE_PATH = path . join ( __dirname , '..' )
1818const BUILTIN_PATH = 'vite-plugin-electron-renderer/builtins'
1919const RESOLVE_PATH = 'vite-plugin-electron-renderer/.resolve'
2020
@@ -24,10 +24,15 @@ export interface RendererOptions {
2424 * Most of the time, you don't need to use it when a module is a C/C++ module, you can load them by return `{ platform: 'node' }`.
2525 *
2626 * If you know exactly how Vite works, you can customize the return snippets.
27- * `e.g.`
27+ *
2828 * ```js
2929 * renderer({
30- * resolve: (id) => `const lib = require("${id}");\nexport default lib.default || lib;`
30+ * resolve: {
31+ * // Use the serialport(C/C++) module as an example
32+ * serialport: () => ({ platform: 'node' }),
33+ * // Equivalent to
34+ * serialport: () => `const lib = require("serialport"); export default lib.default || lib;`,
35+ * },
3136 * })
3237 * ```
3338 *
@@ -38,59 +43,52 @@ export interface RendererOptions {
3843 }
3944}
4045
41- export default function renderer ( options : RendererOptions = { } ) : VitePlugin [ ] {
42- return [
43- cjsShim ( ) ,
44- {
45- name : 'vite-plugin-electron-renderer:build-config' ,
46- async config ( config ) {
47- // Make sure that Electron can be loaded into the local file using `loadFile` after packaging
48- config . base ??= './'
49-
50- config . build ??= { }
51-
52- // TODO: init `config.build.target`
53- // https://github.com/vitejs/vite/pull/8843
54-
55- // https://github.com/electron-vite/electron-vite-vue/issues/107
56- config . build . cssCodeSplit ??= false
57-
58- // TODO: compatible with custom assetsDir
59- // This will guarantee the proper loading of static resources, such as images, `worker.js`
60- // The `.js` file can be loaded correctly with cjs-shim.ts
61- config . build . assetsDir ??= ''
62-
63- config . build . rollupOptions ??= { }
64- config . build . rollupOptions . output ??= { }
65-
66- // `fs-extra` will extend the `fs` module
67- setOutputFreeze ( config . build . rollupOptions )
68-
69- // Some third-party modules, such as `fs-extra`, extend the native module
70- // `__esModule` to bypass Rollup's `getAugmentedNamespace`
71- // see - https://github.com/rollup/plugins/blob/commonjs-v24.0.0/packages/commonjs/src/helpers.js#L38
72- withIgnore ( config . build )
73-
74- const resolveAliases = await buildResolve ( options )
75- const builtinAliases : Alias [ ] = electronBuiltins
76- . filter ( m => ! m . startsWith ( 'node:' ) )
77- . map < Alias > ( m => ( {
78- find : new RegExp ( `^(node:)?${ m } $` ) ,
79- // Vite's pre-bundle only recognizes bare-import
80- replacement : `${ BUILTIN_PATH } /${ m } ` ,
81- // TODO: must be use absolute path for `pnnpm` monorepo - `shamefully-hoist=true` 🤔
82- } ) )
83-
84- // Why is the builtin modules loaded by modifying `resolve.alias` instead of using the plugin `resolveId` + `load` hooks?
85- // `resolve.alias` can work in both the Renderer process and Web Worker, but not the plugin :(
86- // see - https://github.com/vitejs/vite/blob/v4.2.0/packages/vite/src/node/config.ts#L253-L256
87- modifyAlias ( config , [ ...resolveAliases , ...builtinAliases ] )
88- } ,
89- }
90- ]
46+ export default function renderer ( options : RendererOptions = { } ) : VitePlugin {
47+ return {
48+ name : 'vite-plugin-electron-renderer' ,
49+ async config ( config ) {
50+ // Make sure that Electron can be loaded into the local file using `loadFile()` after package
51+ config . base ??= './'
52+
53+ config . build ??= { }
54+
55+ // https://github.com/electron-vite/electron-vite-vue/issues/107
56+ config . build . cssCodeSplit ??= false
57+
58+ // This ensures that static resources are loaded correctly, such as images, `worker.js`
59+ // BWT, the `.js` file can be loaded correctly with './cjs-shim.ts'
60+ config . build . assetsDir ??= ''
61+ // TODO: compatible with custom assetsDir for static resources
62+
63+ config . build . rollupOptions ??= { }
64+
65+ // Some third-party modules, such as `fs-extra`, it will extend the nativ fs module, maybe we need to stop it
66+ // ① Avoid freeze Object
67+ setOutputFreeze ( config . build . rollupOptions )
68+ // ② Avoid not being able to set - https://github.com/rollup/plugins/blob/commonjs-v24.0.0/packages/commonjs/src/helpers.js#L55-L60
69+ withIgnore ( config . build )
70+
71+ const resolveAliases = await buildResolve ( options )
72+ const builtinAliases : Alias [ ] = electronBuiltins
73+ . filter ( m => ! m . startsWith ( 'node:' ) )
74+ . map < Alias > ( m => ( {
75+ find : new RegExp ( `^(node:)?${ m } $` ) ,
76+ // Vite's pre-bundle only recognizes bare-import
77+ replacement : `${ BUILTIN_PATH } /${ m } ` ,
78+ // TODO: must be use absolute path for `pnnpm` monorepo - `shamefully-hoist=true` 🤔
79+ } ) )
80+
81+ // Why is the builtin modules loaded by modifying `resolve.alias` instead of using the plugin `resolveId` + `load` hooks?
82+ // `resolve.alias` has a very high priority in Vite! it works on Pre-Bundling, build, serve, ssr etc. anywhere
83+ // secondly, `resolve.alias` can work in both the Renderer process and Web Worker, but not the plugin :(
84+ // ① Alias priority - https://github.com/vitejs/vite/blob/v4.2.0/packages/vite/src/node/plugins/index.ts#L45
85+ // ② Use in Pre-Bundling - https://github.com/vitejs/vite/blob/v4.2.0/packages/vite/src/node/optimizer/esbuildDepPlugin.ts#L199
86+ // ③ Worker does not share plugins - https://github.com/vitejs/vite/blob/v4.2.0/packages/vite/src/node/config.ts#L253-L256
87+ modifyAlias ( config , [ ...resolveAliases , ...builtinAliases ] )
88+ } ,
89+ }
9190}
9291
93-
9492function setOutputFreeze ( rollupOptions : RollupOptions ) {
9593 rollupOptions . output ??= { }
9694 if ( Array . isArray ( rollupOptions . output ) ) {
@@ -145,21 +143,17 @@ async function buildResolve(options: RendererOptions) {
145143 } else if ( result && typeof result === 'object' && result . platform === 'node' ) {
146144 const { exports } = libEsm ( { exports : Object . getOwnPropertyNames ( await import ( name ) ) } )
147145 snippets = `
148- // Use "__cjs_require" avoid esbuild parse "require"
149- // TODO: better implements
150- const __cjs_require = require;
151-
152- // If a module is a CommonJs, use the "require" loading it can bring better performance.
153- // Especially it is a C/C++ module, this can avoid a lot of trouble.
154- const _M_ = __cjs_require("${ name } ");
146+ // If a module is a CommonJs, use the \`require()\` load it can bring better performance,
147+ // especially it is a C/C++ module, this can avoid a lot of trouble.
148+ const avoid_parse_require = require; const _M_ = avoid_parse_require("${ name } ");
155149${ exports }
156150` . trim ( )
157151 }
158152
159153 if ( ! snippets ) continue
160154
161- const resolvePath = path . join ( __dirname , '.resolve' , name )
162- if ( ! /* reuse cache */ fs . existsSync ( resolvePath ) ) {
155+ const resolvePath = path . join ( PACKAGE_PATH , '.resolve' , name )
156+ if ( ! fs . existsSync ( /* reuse cache */ resolvePath ) ) {
163157 ensureDir ( path . dirname ( resolvePath ) )
164158 fs . writeFileSync ( resolvePath + '.mjs' , snippets )
165159 }
0 commit comments