如何让webpack+React+Electron在安全上下文运行且不降低安全配置?
报错根因
打包后出现Uncaught ReferenceError: require is not defined的核心原因有两个:
- 关闭
nodeIntegration后,Electron渲染进程本身不存在全局require方法 - 你的webpack配置未区分主进程、渲染进程、预加载脚本的构建规则,或者渲染进程代码中直接调用了Node API/
require语法
解决方案(全程符合安全规范,无需修改nodeIntegration和contextIsolation默认安全配置)
1. 拆分webpack构建配置
主进程、渲染进程、预加载脚本分别使用不同的webpack构建目标:
- 主进程配置添加
target: 'electron-main',允许主进程代码调用Node API - 渲染进程配置添加
target: 'web',禁止渲染进程直接调用Node API - 预加载脚本配置添加
target: 'electron-preload',适配预加载脚本的执行环境
配置示例:
// webpack.main.config.js(主进程配置) module.exports = { entry: './src/main/index.js', target: 'electron-main', // 其余打包配置保持正常即可 } // webpack.renderer.config.js(渲染进程配置) module.exports = { entry: './src/renderer/index.js', target: 'web', // 其余打包配置保持正常即可 } // webpack.preload.config.js(预加载脚本配置,可单独配置也可嵌入forge配置) module.exports = { entry: './src/main/preload.js', target: 'electron-preload', }
2. 正确配置预加载脚本的能力桥接
预加载脚本是唯一可以同时访问DOM API和Node API的安全层,使用contextBridge仅暴露最小必要的能力给渲染进程,禁止直接暴露require或完整Node API:
// preload.js 代码 const { contextBridge, ipcRenderer } = require('electron') contextBridge.exposeInMainWorld('electronAPI', { // 按需添加你需要的能力,比如文件读写、系统信息获取等 readLocalFile: (filePath) => ipcRenderer.invoke('read-file', filePath), saveLocalFile: (filePath, content) => ipcRenderer.invoke('write-file', filePath, content) })
3. 主进程窗口配置保持安全规则
创建窗口时不需要修改默认安全配置,仅指定预加载脚本路径即可:
// 主进程窗口创建代码 const { BrowserWindow } = require('electron') const path = require('path') const mainWindow = new BrowserWindow({ width: 1200, height: 800, webPreferences: { // 保持默认安全配置即可,无需修改 nodeIntegration: false, contextIsolation: true, preload: path.join(__dirname, 'preload.js') } })
4. 调整渲染进程代码
渲染进程中不要直接调用require或Node API,所有需要Node能力的逻辑都调用预加载脚本暴露的window.electronAPI下的方法:
// 渲染进程代码示例 async function loadAppConfig() { const config = await window.electronAPI.readLocalFile('./app-config.json') // 后续业务逻辑 }
5. 修正Electron Forge打包配置
在forge.config.js中指定预加载脚本的打包规则,不要把预加载脚本和渲染进程代码打包到一起:
// forge.config.js 示例配置 module.exports = { packagerConfig: {}, rebuildConfig: {}, makers: [/* 你的打包生成配置 */], plugins: [ { name: '@electron-forge/plugin-webpack', config: { mainConfig: './webpack.main.config.js', renderer: { config: './webpack.renderer.config.js', entryPoints: [ { html: './src/renderer/index.html', js: './src/renderer/index.js', name: 'main_window', // 单独指定预加载脚本入口 preload: { js: './src/main/preload.js' } } ] } } } ] }
验证
完成以上配置后重新打包,即可消除require is not defined报错,同时完全符合Electron安全规范,不会引入额外安全漏洞。
内容的提问来源于stack exchange,提问作者LuckyLuke
相关产品推荐
相关产品推荐

