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

如何修复CRA+Electron引入ipcRenderer时fs.existsSync不是函数的错误

问题原因

你遇到的报错是因为CRA(Create React App)默认会把所有依赖打包到前端bundle中,你在渲染层代码里require("electron")时,webpack直接引入了node_modules/electron下的源码,该源码依赖Node.js的fs模块,但前端打包后的代码运行在浏览器沙箱环境中,没有fs相关API,所以触发了报错。即使你开启了nodeIntegration,也会因为webpack提前打包了electron模块导致无法调用Electron运行时暴露的原生API。

解决方案

推荐使用更安全的**预加载脚本(Preload)**方案,不需要开启不安全的Node集成,符合Electron官方最佳实践,操作步骤如下:

步骤1:修改主进程窗口配置

修改main.js中BrowserWindow的webPreferences配置,指定预加载脚本路径,保留默认安全配置:

const path = require("path");
// ...其余原有代码
function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      // 新增预加载脚本配置,填你实际存放preload.js的路径
      preload: path.join(__dirname, "preload.js"),
      // 保留默认安全配置,无需开启nodeIntegration
      contextIsolation: true,
      nodeIntegration: false
    }
  });
  // ...其余原有窗口加载逻辑
}

步骤2:创建预加载脚本

在main.js同级目录新建preload.js,通过contextBridge将需要用到的IPC能力暴露给渲染进程:

const { contextBridge, ipcRenderer } = require("electron");

contextBridge.exposeInMainWorld("electronAPI", {
  // 触发Playwright自动化任务
  runAutomation: (taskParams) => ipcRenderer.invoke("run-automation", taskParams),
  // 接收自动化任务进度回调,可根据需要扩展
  onTaskProgress: (callback) => ipcRenderer.on("task-progress", (_, data) => callback(data))
});

步骤3:主进程封装自动化逻辑并监听IPC事件

修改main.js,将你原有写死的Playwright逻辑封装成可调用的函数,同时监听渲染进程的IPC调用:

const { ipcMain } = require("electron");
const { firefox } = require('playwright');

// 封装自动化任务逻辑
async function runAutomation(taskParams) {
  // taskParams可以接收渲染层传过来的账号、密码、操作参数等
  const { email, password } = taskParams;
  try {
    const browser = await firefox.launch({ headless: false, slowMo: 50 });
    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto('你的目标网站地址');
    await page.waitForTimeout(2000);
    await page.waitForLoadState('load');

    const input1 = await page.$('[id ="exampleInputEmail1"]');
    await input1.type(email)
    await page.waitForTimeout(2000);

    const input2 = await page.$('[id ="exampleInputPassword1"]');
    await input2.type(password)
    await page.waitForTimeout(2000);

    await page.click('"Sign In and Continue"')
    await page.waitForTimeout(2000);

    // 其余自动化逻辑

    return { success: true };
  } catch (e) {
    return { success: false, error: e.message };
  }
}

// 监听渲染进程的自动化调用请求
ipcMain.handle("run-automation", async (_, taskParams) => {
  return await runAutomation(taskParams);
});

步骤4:渲染层调用IPC方法

现在渲染层不需要再引入electron,直接通过全局暴露的electronAPI调用即可:

// 渲染层触发自动化的代码示例
async function startAutoTask() {
  const result = await window.electronAPI.runAutomation({
    email: "你的账号",
    password: "你的密码"
  });
  console.log("任务执行结果:", result);
}
快速适配方案(不推荐,仅用于快速验证)

如果你暂时不需要考虑安全问题,想要快速适配现有代码,可以按以下操作:

  1. 安装react-app-rewired和customize-cra修改CRA默认webpack配置:
npm install react-app-rewired customize-cra --save-dev
  1. 项目根目录新建config-overrides.js,配置electron为外部依赖不打包:
const { override, addWebpackExternals } = require('customize-cra');

module.exports = override(
  addWebpackExternals({
    electron: 'commonjs electron'
  })
);
  1. 修改package.json的scripts字段,将react-scripts替换为react-app-rewired:
"scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test": "react-app-rewired test",
  "eject": "react-scripts eject"
}
  1. 修改main.js的webPreferences配置:
webPreferences: {
  nodeIntegration: true,
  contextIsolation: false
}

完成后你在渲染层const { ipcRenderer } = require("electron")就不会报错了。

内容的提问来源于stack exchange,提问作者MartinDuo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:06:08