使用Electron打包React应用遇运行错误,求助如何使用构建文件
Electron + React 打包后运行报错的解决方案
问题场景
首次使用Electron开发项目,开发阶段启动React应用后执行npm run electron一切正常,但执行npm run package-win打包完成后,运行生成的exe文件出现错误。推测原因是未运行React应用,想了解是否可直接使用React构建文件解决该问题。
相关代码文件
main.js
const path = require("path"); const electron = require("electron"); const isDev = require("electron-is-dev"); // Module to control application life. const app = electron.app; // Module to create native browser window. const BrowserWindow = electron.BrowserWindow; const url = require("url"); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let mainWindow; function createWindow() { // Create the browser window. mainWindow = new BrowserWindow({ show: false }); // cm: open app in fullscreen mode mainWindow.maximize(); mainWindow.show(); // cm: remove default menu bar mainWindow.setMenuBarVisibility(false); if (isDev) { mainWindow.loadURL( "http://localhost:3000" ); } else { mainWindow.loadFile("./dist/index.js"); } // Open the DevTools. mainWindow.webContents.openDevTools(); // Emitted when the window is closed. mainWindow.on("closed", function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. mainWindow = null; }); } // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.on("ready", createWindow); // Quit when all windows are closed. app.on("window-all-closed", function () { // On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== "darwin") { app.quit(); } }); app.on("activate", function () { // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (mainWindow === null) { createWindow(); } }); // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and require them here.
package.json 脚本部分
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "electron": "electron .", "package-win": "electron-packager . IranFMCG --overwrite --platform=win32 --arch=ia32 --icon=assets/icons/win/icon.ico --prune=true --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName=\"IranFMCG\"" }
问题根源
- 加载路径错误:生产环境下你尝试加载
./dist/index.js,但React执行build命令后生成的静态资源目录是build,而非dist,且Electron的loadFile方法需要加载HTML文件而非JS文件。 - 打包未包含React构建产物:原打包脚本中的
--prune=true会清理非必要文件,可能导致React的build目录未被打包进Electron应用中。
修复步骤
1. 生成React生产构建文件
先执行React的构建命令,生成静态资源:
npm run build
执行完成后,项目根目录会出现build文件夹,包含React应用的完整静态资源。
2. 修改main.js的加载逻辑
将生产环境的文件路径改为build目录下的index.html,并使用绝对路径避免打包后的路径问题:
// 替换原else分支的代码 if (isDev) { mainWindow.loadURL("http://localhost:3000"); } else { // 使用path.join生成绝对路径,确保打包后能找到文件 mainWindow.loadFile(path.join(__dirname, "build", "index.html")); }
3. 调整打包脚本
移除package-win中的--prune=true参数,避免React的build目录被误删:
"package-win": "electron-packager . IranFMCG --overwrite --platform=win32 --arch=ia32 --icon=assets/icons/win/icon.ico --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName=\"IranFMCG\""
4. 重新打包并测试
按顺序执行以下命令:
npm run build npm run package-win
打包完成后,前往release-builds目录运行生成的exe文件即可。
内容的提问来源于stack exchange,提问作者Vala Khosravi
相关产品推荐
相关产品推荐

