You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

无法运行打包后的Electron/React应用,寻求macOS跨平台打包Windows应用的解决方案

无法运行打包后的Electron/React应用,寻求macOS跨平台打包Windows应用的解决方案

我正在开发一个Windows应用,主力工作站是macOS。我在macOS上打包了exe文件,放到Windows上运行时出现错误;之后我在Windows机器上重新构建,还是遇到了同样的问题。

我的开发环境

  • 使用WebStorm作为IDE
  • 技术栈:Electron + React
  • 用Electron Builder进行应用分发

运行时错误截图

应用运行错误截图

我的package.json配置

{
  "name": "car_rental",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@electron/remote": "^2.1.2",
    "@testing-library/dom": "^10.4.0",
    "@testing-library/jest-dom": "^6.6.3",
    "@testing-library/react": "^16.2.0",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^1.8.2",
    "concurrently": "^9.1.2",
    "cross-env": "^7.0.3",
    "electron-is-dev": "^3.0.1",
    "motion": "^12.4.10",
    "react": "^19.0.0",
    "react-calendar": "^5.1.0",
    "react-dom": "^19.0.0",
    "react-router": "^7.3.0",
    "react-scripts": "5.0.1",
    "wait-on": "^8.0.2",
    "web-vitals": "^2.1.4"
  },
  "main": "public/electron.js",
  "homepage": "./",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "electron:serve": "concurrently -k \"cross-env BROWSER=none npm run start\" \"npm run electron:start\"",
    "electron:build": "npm run build && electron-builder -c.extraMetadata.main=build/electron.js",
    "electron:start": "wait-on tcp:3000 &&  electron ."
  },
  "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": {
    "electron": "^35.0.1",
    "electron-builder": "^25.1.8"
  },
  "build": {
    "appId": "your.id",
    "extends": null,
    "files": [
      "dist/**/*",
      "build/**/*",
      "node_modules/**/*",
      "package.json"
    ],
    "directories": {
      "buildResources": "assets"
    }
  }
}

我的electron.js主进程文件(位于public文件夹)

const {app, BrowserWindow, Menu} = require("electron");
const isDev = require("electron-is-dev");
const path = require("path");

require("@electron/remote/main").initialize();

function createWindow () {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            devTools: true,
            enableRemoteModule: true
        }, autoHideMenuBar: true,
    });
    Menu.setApplicationMenu(null);

    win.loadURL(isDev ? "http://localhost:3000" : `file://${path.join(__dirname, "../build/index.html")}`);

}

app.whenReady().then(()=>{
    createWindow();
    app.on("activate", () => {
        if (BrowserWindow.getAllWindows().length === 0) {
            createWindow();
        }
    })
});

app.on("window-all-closed", () => {
    if (process.platform !== "darwin") {
        app.quit();
    }
})

我更倾向于基于macOS的解决方案,这样就能直接在我的M1芯片macOS上打包Windows应用。


解决方案

一、先修复应用运行的核心问题

1. 解决主进程文件路径缺失问题

你的electron.js放在public文件夹,但React的build命令只会把public里的静态资源复制到build目录,不会自动移动主进程文件。而打包脚本里指定了build/electron.js作为入口,导致Windows运行时找不到主文件。

修改步骤:

  • 先把package.json里的main字段改成"build/electron.js"
  • 添加一个复制脚本,在build完成后把public/electron.js复制到build目录:
    scripts里新增:
    "copy-electron-main": "cp public/electron.js build/"
    
  • 然后更新electron:build脚本:
    "electron:build": "npm run build && npm run copy-electron-main && electron-builder -c.extraMetadata.main=build/electron.js"
    

2. 修复@electron/remote的初始化逻辑

Electron 14+版本已经废弃了enableRemoteModule字段,你当前的写法会导致运行时错误,需要调整electron.js

const {app, BrowserWindow, Menu} = require("electron");
const isDev = require("electron-is-dev");
const path = require("path");
const remoteMain = require("@electron/remote/main");

remoteMain.initialize();

function createWindow () {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            devTools: true,
            contextIsolation: false, // 暂时关闭上下文隔离(如果渲染进程需要用remote),后续建议用IPC替代
            nodeIntegration: true
        }, 
        autoHideMenuBar: true,
    });
    Menu.setApplicationMenu(null);

    // 必须启用当前窗口的remote权限
    remoteMain.enable(win.webContents);

    // 调整路径:现在electron.js在build目录,所以直接引用当前目录下的index.html
    win.loadURL(isDev ? "http://localhost:3000" : `file://${path.join(__dirname, "./index.html")}`);
}

app.whenReady().then(()=>{
    createWindow();
    app.on("activate", () => {
        if (BrowserWindow.getAllWindows().length === 0) {
            createWindow();
        }
    })
});

app.on("window-all-closed", () => {
    if (process.platform !== "darwin") {
        app.quit();
    }
})

二、配置M1 macOS跨平台打包Windows应用

要在M1芯片的Mac上打包Windows应用,需要先准备依赖环境,再调整打包配置:

1. 安装Wine环境

Electron Builder打包Windows应用需要Wine模拟Windows环境,用Homebrew安装:

brew install --cask wine-stable

安装完成后验证:

wine --version

2. 更新Electron Builder的Windows打包配置

package.jsonbuild字段里添加Windows相关配置:

"build": {
    "appId": "com.yourcompany.carrental", // 改成规范的反向域名格式
    "extends": null,
    "files": [
        "build/**/*",
        "node_modules/**/*",
        "package.json"
    ],
    "directories": {
        "buildResources": "assets"
    },
    "win": {
        "target": "nsis", // Windows安装包格式
        "icon": "assets/icon.ico" // 可选:准备ico格式图标放在assets目录
    },
    "nsis": {
        "oneClick": false, // 可选:允许用户自定义安装路径
        "allowToChangeInstallationDirectory": true
    }
}

3. 执行跨平台打包命令

在终端运行以下命令,指定打包Windows平台:

npm run electron:build -- --win

如果需要打包x64架构的Windows应用(适配大多数Windows设备),可以加上架构参数:

npm run electron:build -- --win --x64

三、验证结果

打包完成后,项目根目录的dist文件夹会生成Windows安装包(.exe文件),复制到Windows机器上运行测试即可。

备注:内容来源于stack exchange,提问作者Fever_Dream

火山引擎 最新活动