Electron React项目构建打包后出现空白页问题求助
TriviApp生产环境打包后空白页问题排查
我开发这款TriviApp应用已有数周,如今尝试打包分发,但开发环境运行正常,生产环境启动后仅显示空白页。已查阅诸多相关帖子仍未解决问题,现将相关配置代码附上,恳请帮忙排查原因:

package.json
{ "name": "triviapp", "author": "trivify", "version": "1.0.0", "private": true, "main": "public/electron.js", "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.2.0", "@fortawesome/free-solid-svg-icons": "^6.2.0", "@fortawesome/react-fontawesome": "^0.2.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "docxtemplater": "^3.31.6", "electron-is-dev": "^2.0.0", "jimp": "^0.16.2", "lodash": "^4.17.21", "mongoose": "^6.7.0", "nodejs-pptx": "^1.0.1", "pizzip": "^3.1.3", "ppt-template": "^1.0.9", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.4.2", "react-scripts": "5.0.1", "translate": "^1.4.1", "web-vitals": "^2.1.4", "xlsx-template": "^1.3.2" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "electron-dev": "concurrently \"set BROWSER=none&& npm start\" \"wait-on http://localhost:3000 && electron .\"", "hotel-dev": "concurrently \"set BROWSER=none&& npm start\" \" electron .\"", "dist": "electron-builder" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "devDependencies": { "babel-polyfill": "^6.26.0", "concurrently": "^7.5.0", "electron": "^21.2.0", "electron-builder": "^23.6.0", "wait-on": "^6.0.1" }, "build": { "appId": "com.trivify.triviapp", "productName": "TriviApp", "target": "NSIS", "extends": null, "nsis": { "allowToChangeInstallationDirectory": true, "oneClick": false }, "directories": { "buildResources": "resources", "output": "release" } } }
electron.js
const electron = require('electron'); const app = electron.app; const { BrowserWindow, ipcMain } = electron; const path = require('path'); const isDev = require('electron-is-dev'); const { generateTrivia, createFolderWithImgs } = require('../src/logic/func'); const { createDoc } = require('../src/logic/createDoc'); const { createPPT } = require('../src/logic/createPPT'); const { getPreguntas, getRascas, addQuestionToBD, getBaresIsla, newIslandInDB, getIslaCodes } = require('../src/logic/dbfuncs'); const { connectDB } = require('../src/db'); const {createRascas} = require('../src/logic/createRascas'); const { createTicketIsla } = require('../src/logic/createTicketsIsla'); const url = require('url'); connectDB(); let mainWindow; function createWindow() { mainWindow = new BrowserWindow({ width: 1300, height: 900, center: true, useContentSize: true, minHeight: 600, minWidth: 1000, webPreferences: { nodeIntegration: true, contextIsolation: false, enableRemoteModule: true, webSecurity: false } }); mainWindow.loadURL(isDev ? 'http://localhost:3000' : url.format({ pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true })); if (isDev) { // Open the DevTools. //BrowserWindow.addDevToolsExtension('<location to your react chrome extension>'); // mainWindow.webContents.openDevTools(); } mainWindow.on('closed', () => mainWindow = null); } app.on('ready', createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { if (mainWindow === null) { createWindow(); } });
index.js
import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import { HashRouter } from "react-router-dom" const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <HashRouter > <App /> </HashRouter> </React.StrictMode> );
App.js
import './stylesheets/App.css'; import { Route, Routes } from "react-router-dom"; import Home from './views/Home'; import Trivial from './views/Trivial'; import DataBases from './views/Databases'; import Rascas from './views/Rascas'; import IslaMisterio from './views/IslaMisterio'; import Facturas from './views/Facturas'; function App() { return ( <div className='App'> <Routes> <Route path='/' element={<Home />} /> <Route path='/trivial' element={<Trivial />} /> <Route path='/pasapalabra' element={<Home />} /> <Route path='/isla' element={<IslaMisterio />} /> <Route path='/rasca' element={<Rascas />} /> <Route path='/facturas' element={<Facturas />} /> <Route path='/databases' element={<DataBases />} /> </Routes> </div> ); } export default App;
问题排查与修复建议
1. 核心路径错误(最可能原因)
你的electron.js放在public目录下,打包后尝试加载public/index.html,但React执行npm run build后,产物是在build目录下。加载路径完全错误,导致空白页。
修改electron.js中的加载代码:
// 替换原来的loadURL部分 const buildIndexPath = path.join(__dirname, '../build/index.html'); mainWindow.loadURL(isDev ? 'http://localhost:3000' : url.format({ pathname: buildIndexPath, protocol: 'file:', slashes: true }));
2. React资源路径配置
React打包后静态资源默认是绝对路径,在本地file协议下会加载失败,需要设置相对路径。
在package.json顶层添加字段:
"homepage": "./",
3. 确保打包顺序正确
必须先构建React产物,再打包Electron:
npm run build && npm run dist
4. 查看生产环境控制台错误
临时打开生产环境的开发者工具,定位具体报错:
在electron.js的createWindow函数中,去掉注释:
// 不管开发还是生产都打开devtools,排查完再注释 mainWindow.webContents.openDevTools();
打包运行后,查看控制台的错误信息(比如模块加载失败、资源404、数据库连接错误等),针对性解决。
5. 检查Electron打包资源包含
确保electron-builder将build目录包含到打包产物中,在package.json的build字段里添加files配置:
"build": { // ... 原有配置 "files": [ "build/**/*", "public/electron.js" ] }
内容的提问来源于stack exchange,提问作者dandomin
相关产品推荐
相关产品推荐

