Skip to content

Commit b0b9b2e

Browse files
authored
Merge pull request #53 from electron-vite/v0.13.12
V0.13.12
2 parents 19209fe + 45bce75 commit b0b9b2e

File tree

7 files changed

+136
-112
lines changed

7 files changed

+136
-112
lines changed

.gitignore

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,12 @@ dist
104104
.tern-port
105105

106106
.DS_Store
107-
.resolve
108107

109108
package-lock.json
110109
# pnpm-lock.yaml
111110
yarn.lock
112111

113-
/types
112+
/.resolve
114113
/builtins
115-
/index.mjs
116-
/index.cjs
117-
/index.js
114+
/dist
115+
/types

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
## 0.13.12 (2023-03-28)
2+
3+
- 7f6b3a4 fix: correctly path
4+
- a7b1132 docs: update
5+
- 6604d99 chore: `install.mjs` -> `install.js`
6+
- 2f70a9b refactor: separate cjs-shim.ts
7+
- 45fef6b refactor: cleanup, separate cjs-shim.ts
8+
9+
#### Main Changed
10+
11+
If you build in `cjs` format, you need to import the corresponding shim plugin
12+
13+
```js
14+
import cjsShim from 'vite-plugin-electron-renderer/dist/cjs-shim.mjs'
15+
16+
export default {
17+
plugins: [
18+
cjsShim(),
19+
],
20+
}
21+
```
22+
123
## 0.13.11 (2023-03-27)
224

325
- b0312e9 fix: use `__cjs_require` avoid esbuild parse `require`

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,15 @@ export interface RendererOptions {
7373
* 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' }`.
7474
*
7575
* If you know exactly how Vite works, you can customize the return snippets.
76-
* `e.g.`
76+
*
7777
* ```js
7878
* renderer({
79-
* resolve: (id) => `const lib = require("${id}");\nexport default lib.default || lib;`
79+
* resolve: {
80+
* // Use the serialport(C/C++) module as an example
81+
* serialport: () => ({ platform: 'node' }),
82+
* // Equivalent to
83+
* serialport: () => `const lib = require("serialport"); export default lib.default || lib;`,
84+
* },
8085
* })
8186
* ```
8287
*

install.mjs renamed to install.js

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
import fs from 'node:fs'
2-
import path from 'node:path'
3-
import { builtinModules } from 'node:module'
4-
import { fileURLToPath } from 'node:url'
5-
import libEsm from 'lib-esm'
1+
const fs = require('fs');
2+
const path = require('path');
3+
const { builtinModules } = require('module');
4+
const libEsm = require('lib-esm');
65

7-
var __dirname = path.dirname(fileURLToPath(import.meta.url))
8-
9-
export const builtins = builtinModules.filter(m => !m.startsWith('_'))
10-
export const builtins_dir = path.join(__dirname, 'builtins')
11-
export const electron = `
6+
const builtins = builtinModules.filter(m => !m.startsWith('_'));
7+
const builtins_dir = path.join(__dirname, 'builtins');
8+
const electron = `
129
const electron = typeof require !== 'undefined'
1310
// All exports module see https://www.electronjs.org -> API -> Renderer Process Modules
1411
? (function requireElectron() {
15-
const __cjs_require = require;
16-
return __cjs_require("electron");
12+
const avoid_parse_require = require;
13+
return avoid_parse_require("electron");
1714
}())
1815
: (function nodeIntegrationWarn() {
1916
console.error(\`If you need to use "electron" in the Renderer process, make sure that "nodeIntegration" is enabled in the Main process.\`);
@@ -71,31 +68,26 @@ export const nativeImage = electron.nativeImage;
7168
export const shell = electron.shell;
7269
export const webFrame = electron.webFrame;
7370
export const deprecate = electron.deprecate;
74-
`.trim()
75-
76-
export async function generateBuiltins() {
77-
fs.rmSync(builtins_dir, { recursive: true, force: true })
71+
`.trim();
7872

73+
function generateBuiltins() {
7974
// Node.js
8075
for (const module of builtins) {
81-
const filename = path.join(builtins_dir, module) + '.mjs'
82-
const dirname = path.dirname(filename)
83-
!fs.existsSync(dirname) && fs.mkdirSync(dirname, { recursive: true })
84-
85-
// [2023-03-09] `import('trace_events')` in [email protected] causes an error
86-
// Error: Trace events are unavailable
87-
// ❯ node:trace_events:25:9
76+
const filename = path.join(builtins_dir, module) + '.mjs';
77+
const dirname = path.dirname(filename);
78+
!fs.existsSync(dirname) && fs.mkdirSync(dirname, { recursive: true });
8879

89-
const { exports } = libEsm({ exports: Object.keys(await import(module)) })
90-
// Use "__cjs_require" avoid esbuild parse "require"
80+
const { exports } = libEsm({ exports: Object.keys(require(module)) });
9181
// TODO: better implements
92-
fs.writeFileSync(filename, `const __cjs_require = require; const _M_ = __cjs_require("${module}");\n${exports}`)
82+
fs.writeFileSync(filename, `const avoid_parse_require = require; const _M_ = avoid_parse_require("${module}");\n${exports}`);
9383
}
9484

9585
// Electron
96-
fs.writeFileSync(path.join(builtins_dir, 'electron.mjs'), electron)
86+
fs.writeFileSync(path.join(builtins_dir, 'electron.mjs'), electron);
9787

98-
console.log('[vite-plugin-electron-renderer] built-in module generation successful.\n')
88+
console.log('[vite-plugin-electron-renderer] built-in module generation successful.\n');
9989
}
10090

101-
generateBuiltins()
91+
// bootstrap
92+
fs.rmSync(builtins_dir, { recursive: true, force: true });
93+
generateBuiltins();

package.json

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
22
"name": "vite-plugin-electron-renderer",
3-
"version": "0.13.11",
3+
"version": "0.13.12",
44
"description": "Support use Node.js API in Electron-Renderer",
5-
"main": "index.js",
6-
"types": "types",
5+
"main": "./dist/index.js",
6+
"types": "./dist/index.d.ts",
77
"exports": {
88
".": {
9-
"import": "./index.mjs",
10-
"require": "./index.js"
9+
"types": "./dist/index.d.ts",
10+
"import": "./dist/index.mjs",
11+
"require": "./dist/index.js"
1112
},
1213
"./*": "./*"
1314
},
@@ -22,7 +23,7 @@
2223
"build": "vite build",
2324
"types": "tsc --emitDeclarationOnly",
2425
"prepublishOnly": "npm run test && npm run build",
25-
"postinstall": "node install.mjs",
26+
"postinstall": "node install.js",
2627
"test": "vitest run"
2728
},
2829
"dependencies": {
@@ -36,10 +37,8 @@
3637
"vitest": "^0.29.3"
3738
},
3839
"files": [
39-
"types",
40-
"index.mjs",
41-
"index.js",
42-
"install.mjs"
40+
"dist",
41+
"install.js"
4342
],
4443
"keywords": [
4544
"vite",

src/index.ts

Lines changed: 57 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ import type {
1010
} from 'vite'
1111
import type { RollupOptions } from 'rollup'
1212
import libEsm from 'lib-esm'
13-
import cjsShim from './cjs-shim'
1413

1514
const __dirname = path.dirname(fileURLToPath(import.meta.url))
1615
const builtins = builtinModules.filter(m => !m.startsWith('_')); builtins.push(...builtins.map(m => `node:${m}`))
1716
const electronBuiltins = ['electron', ...builtins]
17+
const PACKAGE_PATH = path.join(__dirname, '..')
1818
const BUILTIN_PATH = 'vite-plugin-electron-renderer/builtins'
1919
const 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-
9492
function 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
}

vite.config.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ export default defineConfig({
99
build: {
1010
minify: false,
1111
emptyOutDir: false,
12-
outDir: '',
1312
lib: {
14-
entry: 'src/index.ts',
13+
entry: {
14+
index: 'src/index.ts',
15+
'cjs-shim': 'src/cjs-shim.ts',
16+
},
1517
formats: ['cjs', 'es'],
1618
fileName: format => format === 'es' ? '[name].mjs' : '[name].js',
1719
},
@@ -32,7 +34,9 @@ export default defineConfig({
3234
name: 'generate-types',
3335
async closeBundle() {
3436
removeTypes()
35-
generateTypes()
37+
await generateTypes()
38+
moveTypesToDist()
39+
removeTypes()
3640
},
3741
}],
3842
})
@@ -55,3 +59,13 @@ function generateTypes() {
5559
cp.on('error', process.exit)
5660
})
5761
}
62+
63+
function moveTypesToDist() {
64+
const types = path.join(__dirname, 'types')
65+
const dist = path.join(__dirname, 'dist')
66+
const files = fs.readdirSync(types).filter(n => n.endsWith('.d.ts'))
67+
for (const file of files) {
68+
fs.copyFileSync(path.join(types, file), path.join(dist, file))
69+
console.log('[types]', `types/${file} -> dist/${file}`)
70+
}
71+
}

0 commit comments

Comments
 (0)