Electron编译Vue生产环境报错Cannot find module 'fs/promises'如何解决
问题原因
- 该问题属于Electron开发环境与生产环境配置差异导致的典型报错:
electron:serve开发环境默认开启Node集成、关闭上下文隔离,允许渲染进程直接调用fs、child_process等Node原生模块,不会触发报错;生产构建默认开启沙箱模式、关闭Node集成、开启上下文隔离,渲染进程无权限直接调用Node原生模块。 - 执行系统命令的相关代码直接写在渲染进程中,生产构建时前端打包工具会将Node核心模块识别为前端依赖进行打包,找不到对应资源就会抛出模块不存在的错误。
- 未按Electron安全规范配置预加载(preload)脚本,未将系统能力通过规范方式暴露给渲染进程,生产环境下被安全策略拦截。
修复方案
- 第一步:调整主进程窗口创建配置,关闭渲染进程Node集成、开启上下文隔离,配置预加载脚本路径,示例代码如下:
const path = require('path') const { BrowserWindow } = require('electron') const win = new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: false, contextIsolation: true, preload: path.join(__dirname, 'preload.js') } })
- 第二步:在对应路径新建
preload.js文件,通过contextBridge把执行系统命令的能力暴露给渲染进程,示例代码如下:
const { contextBridge, ipcRenderer } = require('electron') const { exec } = require('child_process') contextBridge.exposeInMainWorld('electronAPI', { runSystemCommand: (commandStr) => { return new Promise((resolve, reject) => { exec(commandStr, (error, stdout, stderr) => { if (error) return reject(error) resolve({ stdout, stderr }) }) }) } })
- 第三步:修改原有渲染进程中调用系统命令的代码,删除直接引入
child_process/fs等Node模块的逻辑,改为调用预加载脚本暴露的API,示例:
// 原有写法(直接调用Node模块,生产环境失效) // const { exec } = require('child_process') // exec('xxx命令') // 替换为新写法 window.electronAPI.runSystemCommand('xxx命令').then(res => { console.log('命令执行结果', res) }).catch(err => { console.error('命令执行失败', err) })
- 第四步:调整
vue.config.js配置,将预加载脚本加入Electron构建入口,避免生产打包时丢失文件,示例配置:
module.exports = { pluginOptions: { electronBuilder: { preload: 'src/preload.js', externals: ['child_process', 'fs'] } } }
- 第五步:重新执行
npm run electron:build即可正常构建生产版本。
内容的提问来源于stack exchange,提问作者stillborn1
相关产品推荐
相关产品推荐

