electron-react模板调用dialog报Can't resolve 'fs'错误如何解决
报错根源
你遇到的Can't resolve 'fs'报错本质是:electron-react-boilerplate的渲染进程代码默认由webpack打包,webpack会尝试把你在渲染层引入的@electron/remote、electron等node模块打包到前端bundle中,但electron模块依赖fs等node原生核心模块,浏览器环境不存在这些模块,因此打包报错,和你配置的nodeIntegration、remote初始化逻辑暂时没有关系。
解决方案
方案1:推荐使用IPC通信(安全无风险,无需修改打包配置)
Electron官方当前更推荐通过「主进程处理系统API调用+预加载脚本暴露安全接口+渲染层调用接口」的IPC方案实现需求,不需要开启不安全的nodeIntegration: true配置,也不会触发打包报错,操作步骤如下:
- 主进程新增IPC事件监听,直接调用原生dialog组件
// main.ts 主进程代码 import { app, BrowserWindow, ipcMain, dialog } from 'electron'; // 监听渲染进程的文件选择请求 ipcMain.handle('dialog:openFile', async () => { const result = await dialog.showOpenDialog({ properties: ['openFile'], // 可自行补充filters、defaultPath等配置项 }); return result.filePaths; });
- 编辑预加载脚本preload.ts,给渲染层暴露调用入口
// preload.ts 预加载脚本 import { contextBridge, ipcRenderer } from 'electron'; contextBridge.exposeInMainWorld('electronAPI', { openFileDialog: () => ipcRenderer.invoke('dialog:openFile') });
- (可选,TS项目需要)新增类型声明文件,避免TS报错
在src目录下新建electron-api.d.ts:
export interface IElectronAPI { openFileDialog: () => Promise<string[]>; } declare global { interface Window { electronAPI: IElectronAPI; } }
- 修改App.tsx代码,直接调用暴露的接口即可
const Hello = () => { const readFromFile = async () => { const filePaths = await window.electronAPI.openFileDialog(); // 拿到选择的文件路径后处理后续逻辑 console.log(filePaths); }; return ( <> <button onClick={readFromFile} >Test</button> </> ); };
- 确认主进程创建窗口的webPreferences配置如下即可,无需修改安全配置
const mainWindow = new BrowserWindow({ // 其他窗口配置 webPreferences: { preload: path.join(__dirname, 'preload.js'), // 确保preload路径正确 contextIsolation: true, // 保持默认开启即可 nodeIntegration: false, // 不需要开启 } });
方案2:坚持使用@electron/remote的修复方法
如果一定要在渲染层直接调用@electron/remote,需要修改webpack配置排除electron相关模块的打包逻辑:
- 找到渲染进程的webpack配置文件(一般为
webpack.config.renderer.dev.ts、webpack.config.renderer.prod.ts),新增externals配置:
module.exports = { // 其他原有配置 externals: { electron: 'commonjs2 electron', '@electron/remote': 'commonjs2 @electron/remote' } }
- 主进程创建完窗口后,给对应窗口开启remote权限
// main.ts 中创建mainWindow后添加 import * as remoteMain from '@electron/remote/main'; remoteMain.enable(mainWindow.webContents);
注意:该方案需要开启
contextIsolation: false,存在安全风险,仅适合本地测试使用,不推荐生产环境使用。
内容的提问来源于stack exchange,提问作者schgab
相关产品推荐
相关产品推荐

