electron 应用根据构建命令打包不同环境的实现方案(一)

1,560 阅读3分钟

现状

本人最近在做一个electron项目,使用的是electron-egg这个基础项目,项目里在请求后台接口时需要区分生产环境和测试环境,每次构建前都需要去手动修改导出config的文件,然后再构建。

且生产包和测试包没有隔离,安装测试包就会把之前安装好的生产版本覆盖掉。为了解决这个问题,构建生产包时和构建测试包时,还需要修改package.json文件中的appid去区分应用版本。

且后期,桌面端应用增加了自动更新的功能,生产环境和测试自动更新的静态文件存放地址不同,后期发布新版本时还需要额外改对应的构建地址。

构建完成后,还需要将不同的包和版本信息文件放置不同的静态目录里。

存在的问题

每次构建时,需要手动修改三个文件来区分应用包版本,基础config配置、和更新文件地址,从而来区分不同的环境。由于是手动操作,很容易少改或者漏改,导致构建的版本环境不对,产生问题。

解决方案

主要的思路就是通过构建命令传入环境变量,然后通过环境变量区分不同环境、读取不同的配置、设置不同的appid。从而达到从手动到自动的进化。

第一种方案:动态地向Electron应用的package.json文件中添加额外的元数据。

electron-builder -c.extraMetadata.foo=bar 这条命令的作用是在构建过程中向extraMetadata对象中添加一个名为foo的属性,其值为bar。这样可以动态地向Electron应用的package.json文件中添加额外的元数据,以便在运行时进行不同的处理。

在Electron的主进程中,你可以通过读取package.json文件来获取extraMetadata中添加的额外属性。以下是一个示例,展示如何在主进程中获取并使用foo属性。

  • 实际实现步骤:
  1. 读取package.json文件: 在主进程中,你可以使用Node.js的fs模块来读取package.json文件,并解析其中的内容。
  2. 获取extraMetadata中的属性: 解析package.json文件后,你可以访问extraMetadata对象,并获取其中的foo属性。
  • 关键代码及配置
第一步,配置打包参数,在package.json中配置打包命令,使用配置文件方式加载配置builder.test.json。
打包命令

"build-m-arm64-test": "electron-builder --config=./electron/config/builder.test.json -m --arm64"

第二步,修改配置文件builder.test.json

"mac": {

"icon": "build/icons/icon.icns",

"artifactName": "${productName}-${os}-${version}-${arch}.${ext}",

"darkModeSupport": true,

"hardenedRuntime": false

},

"extraMetadata": {

"mode": "test"

}
第三步 ,在main.js或者其他主进程js文件中读取mode参数


// main.js 或主进程入口文件
const { app } = require('electron');
const fs = require('fs');
const path = require('path');

let fooValue;

// 读取package.json文件
const packagePath = path.join(app.getAppPath(), 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));

// 获取extraMetadata中的foo属性
if (packageJson.extraMetadata && packageJson.extraMetadata.foo) {
  fooValue = packageJson.extraMetadata.foo;
} else {
  fooValue = 'default'; // 如果没有找到foo属性,可以使用默认值
}

console.log(`foo value: ${fooValue}`);


/**

* 以下是mac系统重打印的日志

* 2024-07-30 11:20:52,878 INFO 49927 [addon:autoUpdater] mode = undefined

2024-07-30 11:20:52,878 INFO 49927 [addon:autoUpdater] productName = /Applications/ywxd-test.app/Contents/MacOS/ywxd-test

2024-07-30 11:20:52,878 INFO 49927 [addon:autoUpdater] process = /Applications/ywxd-test.app/Contents/MacOS/ywxd-test

2024-07-30 11:20:52,878 INFO 49927 [addon:autoUpdater] test? = true

*/

Log.info(`[addon:autoUpdater] mode = ${process.env.MODE}`);

const productName = process.argv[0];

Log.info(`[addon:autoUpdater] productName = ${productName}`);

Log.info(`[addon:autoUpdater] process = ${process.argv}`);

if (!productName.includes("test")) {

// 根据不同环境的productName 来区分生产和测试

Log.info(`[addon:autoUpdater] test? = false`);

} else {

// 测试环境

Log.info(`[addon:autoUpdater] test? = true`);

}

我自己是在自动更新模块中增加的这段测试代码,以后是相关的日志啊

2024-07-30 14:25:00,369 INFO 81057 [addon:autoUpdater] load

2024-07-30 14:25:00,370 INFO 81057 [addon:autoUpdater] packagePath: /Applications/ee.app/Contents/Resources/app.asar/package.json

2024-07-30 14:25:00,370 INFO 81057 [addon:autoUpdater] packageJson: {"name":"ee","version":"1.0.1","description":"","main":"main.js","repository":"https://github.com/dromara/electron-egg.git","author":"哆啦好梦, Inc <530353222@qq.com>","license":"Apache","dependencies":{"@microsoft/fetch-event-source":"^2.0.1","auto-launch":"^5.0.6","axios":"^1.6.7"...},"iohook":{"targets":["node-93","electron-109"],"platforms":["win32","darwin","linux"],"arches":["x64","ia32","arm64"]},"mode":"test"}

2024-07-30 14:25:00,370 INFO 81057 [addon:autoUpdater] modeValue: test

第二种方案,不同打包命令,使用不同配置文件,打包成不同产品名称

参考# electron 应用根据构建命令打包不同环境的实现方案

关键代码

第一步,配置打包参数,在package.json中配置打包命令,使用配置文件方式加载配置builder.test.json。
打包命令

"build-m-arm64-test": "electron-builder --config=./electron/config/builder.test.json -m --arm64"
第二步,修改配置文件builder.test.json
"productName": "ee-test"
第三步 ,修改js文件
const productName = process.argv[0];

Log.info(`[addon:autoUpdater] productName = ${productName}`);

Log.info(`[addon:autoUpdater] process = ${process.argv}`);

if (!productName.includes("test")) {

// 根据不同环境的productName 来区分生产和测试

Log.info(`[addon:autoUpdater] test? = false`);

} else {

// 测试环境

Log.info(`[addon:autoUpdater] test? = true`);

}

以下是相关的日志


2024-07-30 14:25:00,370 INFO 81057 [addon:autoUpdater] productName = /Applications/ee-test.app/Contents/MacOS/ee-test

2024-07-30 14:25:00,370 INFO 81057 [addon:autoUpdater] process = /Applications/ee-test.app/Contents/MacOS/ee-test

2024-07-30 14:25:00,370 INFO 81057 [addon:autoUpdater] test? = true

本人最后采用第一个方案。

参考资料

与下面这个博文中遇到的问题一样,但是解决方案稍微不同。 # electron 应用根据构建命令打包不同环境的实现方案