现状
本人最近在做一个electron项目,使用的是electron-egg这个基础项目,项目里在请求后台接口时需要区分生产环境和测试环境,每次构建前都需要去手动修改导出config的文件,然后再构建。
且生产包和测试包没有隔离,安装测试包就会把之前安装好的生产版本覆盖掉。为了解决这个问题,构建生产包时和构建测试包时,还需要修改package.json文件中的appid去区分应用版本。
且后期,桌面端应用增加了自动更新的功能,生产环境和测试自动更新的静态文件存放地址不同,后期发布新版本时还需要额外改对应的构建地址。
构建完成后,还需要将不同的包和版本信息文件放置不同的静态目录里。
存在的问题
每次构建时,需要手动修改三个文件来区分应用包版本,基础config配置、和更新文件地址,从而来区分不同的环境。由于是手动操作,很容易少改或者漏改,导致构建的版本环境不对,产生问题。
解决方案
主要的思路就是通过构建命令传入环境变量,然后通过环境变量区分不同环境、读取不同的配置、设置不同的appid。从而达到从手动到自动的进化。
第一种方案:动态地向Electron应用的package.json文件中添加额外的元数据。
- 借鉴官网中的一段配置说明,动态往package.json中添加额外的配置参数。
参考文章electron-builder打包详解.md
electron-builder -c.extraMetadata.foo=bar 这条命令的作用是在构建过程中向extraMetadata对象中添加一个名为foo的属性,其值为bar。这样可以动态地向Electron应用的package.json文件中添加额外的元数据,以便在运行时进行不同的处理。
在Electron的主进程中,你可以通过读取package.json文件来获取extraMetadata中添加的额外属性。以下是一个示例,展示如何在主进程中获取并使用foo属性。
- 实际实现步骤:
- 读取
package.json文件: 在主进程中,你可以使用Node.js的fs模块来读取package.json文件,并解析其中的内容。 - 获取
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 应用根据构建命令打包不同环境的实现方案