You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 09:42:03