Support use Node.js API in Electron-Renderer
English | 简体中文
Warning
nodeIntegration is not recommended in Electron, and this plugin is not a solution to the security issues it may cause. If you want to use this plugin, please make sure you understand the security implications of enabling nodeIntegration and take appropriate measures to mitigate potential risks.
In short, vite-plugin-electron-renderer is responsible for polyfilling Electron, Node.js built-in modules and other npm packages for the Renderer process.
npm i vite-plugin-electron-renderer -DImportant
This plugin is currently in v1 beta development. Use it at your own risk.
Breaking change (v1):
- Drop Vite < 8 support.
resolve.*.type: 'esm'now usescreateRequire()for pure-ESM packages. Electron 35+ (Node 22+) is required;prebuildEsm: trueis the compatibility option for Electron < 35.
For old behavior, use v0.14.7 instead.
- This just modifies some of Vite's default config to make the Renderer process works.
import renderer from 'vite-plugin-electron-renderer'
export default {
plugins: [renderer()],
}- Using the third-part
C/C++,esmpackage in the Renderer process.
import renderer from 'vite-plugin-electron-renderer'
export default {
plugins: [
renderer({
// Compatibility option for Electron < 35
prebuildEsm: true,
resolve: {
// C/C++ modules should stay on require()
serialport: { type: 'cjs' },
// Pure ESM modules can be loaded through dynamic import()
got: { type: 'esm' },
// Pure CJS modules can opt into production bundling
somePureCjsPackage: { type: 'cjs', bundle: true },
},
}),
],
}By default,
type: 'cjs'modules stay on runtimerequire()and should be put intodependencies.type: 'esm'modules are bundled in production builds unlessbundle: falseis set.
renderer(options: RendererOptions)
export interface RendererOptions {
/**
* Compatibility option for Electron < 35.
* Pre-build `resolve.*.type = 'esm'` deps to CJS during dev so the shim can
* stay on plain `require()`.
*/
prebuildEsm?: boolean
/**
* Explicitly tell Vite how to load modules, which is very useful for C/C++ and `esm` modules
*
* - `type.cjs` loads through `require()` and exposes statically known names when possible
* - `type.esm` loads through `createRequire()` and exposes statically known names when possible (falls back to dynamic `export *` when introspection fails)
*
* @experimental
*/
resolve?: {
[module: string]: {
type: 'cjs' | 'esm'
/**
* Whether this dependency should be bundled in production builds.
*
* Defaults to `true` for `type: 'esm'`, and `false` for `type: 'cjs'`.
*/
bundle?: boolean
/** Full custom how to generate the shim module */
build?: (args: {
cjs: (module: string) => Promise<string>
esm: (module: string) => Promise<string>
}) => Promise<string>
}
}
}Load Electron and Node.js cjs-packages/built-in-modules (Schematic)
┏————————————————————————————————————————┓ ┏—————————————————┓
│ import { ipcRenderer } from 'electron' │ │ Vite dev server │
┗————————————————————————————————————————┛ ┗—————————————————┛
│ │
│ 1. Generate electron shim on first resolve │
│ node_modules/.vite-electron-renderer/electron │
│ │
│ 2. HTTP(Request): electron module │
│ ————————————————————————————————————————————————> │
│ │
│ 3. resolveId() redirects to │
│ node_modules/.vite-electron-renderer/electron │
│ ↓ │
│ const { ipcRenderer } = require('electron') │
│ export { ipcRenderer } │
│ │
│ 4. HTTP(Response): electron module │
│ <———————————————————————————————————————————————— │
│ │
┏————————————————————————————————————————┓ ┏—————————————————┓
│ import { ipcRenderer } from 'electron' │ │ Vite dev server │
┗————————————————————————————————————————┛ ┗—————————————————┛
In general. Vite will pre-bundle all third-party modules in a Web-based usage format, but it can not adapt to Electron Renderer process especially C/C++ modules. So we must be make a little changes for this.
const _M_ = require('serialport')
export default _M_.default || _M_
export const SerialPort = _M_.SerialPort
// export other members ...Modules configured as esm are bundled in production builds by default. Set bundle: false to keep them on the runtime shim path, where they are wrapped with createRequire() (Electron's embedded Node 22+ supports require(esm)) and re-exported with their statically introspected names. If introspection fails at build time, the shim falls back to a dynamic export *.
prebuildEsm: true is a compatibility option for Electron < 35. In that mode, the plugin reuses its internal dependency build path to pre-build configured type: 'esm' dependencies to CJS during dev, then serves the usual renderer shim on top of that CJS output.
| Classify | e.g. | dependencies | devDependencies |
|---|---|---|---|
| Node.js C/C++ native modules | serialport, sqlite3 | ✅ | ❌ |
| Node.js CJS packages | electron-store | ✅ | ✅ |
| Node.js ESM packages | execa, got, node-fetch | ✅ | ✅ (Recommend) |
| Web packages | Vue, React | ✅ | ✅ (Recommend) |
Doing so will reduce the size of the packaged APP by electron-builder.