Electron中ESM需分主进程与渲染进程适配:主进程须用.mjs或"type":"module"且禁用require/__dirname;渲染进程类浏览器,需contextBridge桥接Node能力;禁止CommonJS与ESM混用。

Electron 中引入 ES Modules(ESM)需要严格匹配 Node.js 和 Chromium 的加载规则,不能简单照搬浏览器或纯 Node 项目的方式。关键在于:主进程用 Node.js 的 ESM 加载器,渲染进程用 Chromium 的 ESM 加载器,二者行为不同、限制不同。
主进程启用 ESM 的硬性条件
主进程文件(如 main.mjs 或带 "type": "module" 的 main.js)要被识别为 ESM,必须同时满足:
- 文件扩展名是
.mjs,或者 -
package.json中明确声明"type": "module" - 文件内不能出现
require()、__dirname、__filename、module.exports - 所有导入路径必须带后缀(如
import { app } from './app.mjs',不能写./app)
preload 脚本必须用 .mjs 后缀
即使主进程用了 CommonJS,只要 preload 脚本想用 ESM 语法,就必须:
- 重命名为
preload.mjs - 在
BrowserWindow配置中显式指向该文件:preload: path.join(__dirname, 'preload.mjs') - 确保
contextIsolation: true(推荐),且nodeIntegration: false(默认已禁用)
否则会报错 require() of ES Module ... not supported 或 Unable to load preload script。
渲染进程的 ESM 使用更接近浏览器
在 HTML 中通过 <script type="module"></script> 引入的 JS,走的是 Chromium 的 ESM 加载器:
- 支持
import,但无法直接访问 Node.js 内置模块(如fs、path) - 不能在模块顶层使用
require,也不能用__dirname - 若需调用主进程能力,必须通过
contextBridge暴露有限接口,再由 preload 脚本桥接 - 动态导入
import('./xxx.js')可用于按需加载,但路径必须是相对或绝对 URL 形式
避免混用 CommonJS 和 ESM
同一个项目里不要让部分文件用 require、部分用 import,尤其不要在 ESM 文件里 require('./commonjs-file.js') —— Node.js 不允许这种跨模块系统调用。如果依赖的第三方库是 CommonJS(如早期 wallpaper),而你的入口又是 ESM,常见解法是:
- 改用打包工具(如 webpack、Vite)统一处理,把所有模块转成兼容格式
- 或降级回 CommonJS 主进程(改
main.js全部用require,不设"type": "module") - 或找该库的 ESM 兼容版本(看其
package.json是否同时提供exports字段)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











