Electron React应用调用fs.readFileSync报错求助
Electron React应用在浏览器中调用
window.myFS.readFile时报错:Cannot read properties of undefined (reading 'readFile') 问题原因
报错仅在本地浏览器运行时出现,Electron桌面端正常,核心原因如下:
- 普通浏览器环境没有Electron的
contextBridge和preload机制,preload.js中通过contextBridge.exposeInMainWorld挂载的window.myFS对象,只有在Electron启动的窗口里才会存在。直接在浏览器访问http://localhost:3000时,preload脚本不会执行,window.myFS未定义,调用readFile自然触发类型错误。 - 你的代码还存在两个隐藏问题,即使在Electron中也会导致功能异常:
ipcMain.handle的回调参数错误:第一个参数是event对象,第二个才是传入的filePath,原代码直接把filePath作为第一个参数,会导致读取路径错误。ipcRenderer.invoke是异步操作,返回Promise,原代码直接将window.myFS.readFile()的返回值(实际为undefined)传给Rekognition的Bytes,无法获取正确的文件内容。
解决方案与代码修正
1. 修复Electron主进程与预加载脚本逻辑
修改main.js中的ipcMain.handle回调,正确接收参数:
// main.js app.whenReady().then(() => { // 修正参数:第一个参数是event,第二个是filePath ipcMain.handle("readFile", (event, filePath)=>{ return fs.readFileSync(filePath); }) createMainWindow() });
修改preload.js,让readFile返回Promise(适配ipcRenderer.invoke的异步特性):
// preload.js const {contextBridge, ipcRenderer} = require("electron"); contextBridge.exposeInMainWorld( "myFS", { readFile:(filePath) => { // 返回invoke的Promise,方便渲染进程异步处理 return ipcRenderer.invoke("readFile", filePath); } } );
2. 在React代码中增加环境判断与异步处理
修改Work.js,先判断是否在Electron环境,再调用myFS.readFile,同时处理异步逻辑:
import React from "react"; const Rekognition = require("aws-sdk"); export default function Work() { return ( <div> <button id="apibutton" onClick={credentials}> Try Amazon Rekognition! </button> </div> ) } async function credentials() { // 先判断是否在Electron环境 if (!window.myFS) { console.error("该功能仅在Electron桌面端可用"); alert("请使用Electron桌面端运行该功能"); return; } try { // 异步读取文件 const fileBytes = await window.myFS.readFile("./download.jpg"); const rekognition = new Rekognition.Rekognition({ region: 'ap-southeast-1' }); rekognition.detectFaces({ Attributes: ["ALL"], Image: { Bytes: fileBytes } }, (err, data) => { if (err) { console.log(err, err.stack); } else { // data是对象,不是JSON字符串,直接打印即可 console.log(data); } }) } catch (err) { console.error("读取文件失败:", err); } }
3. 可选:浏览器环境下模拟函数(开发调试用)
如果需要在浏览器中调试其他逻辑,不想被该报错打断,可以在React项目的入口文件(比如index.js)中添加模拟代码:
// src/index.js // 仅在非Electron环境下模拟myFS if (!window.myFS) { window.myFS = { readFile: async (filePath) => { console.warn("当前为浏览器环境,模拟读取文件"); // 可以返回测试用的二进制数据,或者抛出提示 throw new Error("浏览器环境不支持文件读取,请使用Electron"); } } }
总结
- 报错本质是浏览器环境缺少Electron预加载脚本注入的
window.myFS对象,通过环境判断即可避免。 - 同时要修正Electron的IPC异步逻辑,确保文件内容能正确传递给Rekognition API。
内容的提问来源于stack exchange,提问作者quah joey
相关产品推荐
相关产品推荐

