electron 应用根据构建命令打包不同环境的实现方案
现状
本人最近接手了一个electron项目,项目里通过读取不同的config文件区分生产包和测试包,每次构建前都需要去手动修改导出config的文件,然后再构建。
且生产包和测试包没有隔离,安装测试包就会把之前安装好的生产版本覆盖掉。为了解决这个问题,构建生产包时和构建测试包时,还需要修改package.json文件中的appid去区分应用版本。
且后期,桌面端应用增加了自动更新的功能,生产环境和测试自动更新的静态文件存放地址不同,后期发布新版本时还需要额外改对应的构建地址。
构建完成后,还需要将不同的包和版本信息文件放置不同的静态目录里。
存在的问题
每次构建时,需要手动修改三个文件来区分应用包版本,基础config配置、和更新文件地址,从而来区分不同的环境。由于是手动操作,很容易少改或者漏改,导致构建的版本环境不对,产生问题。
解决方案
主要的思路就是通过构建命令传入环境变量,然后通过环境变量区分不同环境、读取不同的配置、设置不同的appid。从而达到从手动到自动的进化。
经过一番辛苦查阅各种资料、翻看文档以及实践之后,本人终于获得了解决方案。以下是具体实现步骤:
-
通过electron-builder的config参数,传入不同的构建命令,如:
electron-builder --config ./build/uat.yml
, 测试环境的配置文件如下:yamlproductName: 我的应用-uat appId: uat.my.app win: target: [nsis] publish: [{ "provider": "generic", "url": "https://xxxx.cnn.com/app/uat" #测试环境的发布地址 }] nsis: oneClick: false allowToChangeInstallationDirectory: true beforePack: ./build/beforePack.js #开始打包前执行的钩子函数 afterAllArtifactBuild: ./build/afterAllArtifactBuild.js #所有build行为结束后执行的钩子函数
而此时,package.json文件中的构建命令如下:
json"scripts": { "start": "cross-env electron .", "pack:test": "electron-builder --config ./build/uat.yml", "pack:prod": "electron-builder --config ./build/prod.yml", "test": "echo \"Error: no test specified\" && exit 1" },
-
主渲染进程中判断环境的方法
javascriptconst { app } = require('electron') const getEnv = () => { if(!app.isPackaged) { // 未打包,本地开发环境 } else { const productName = process.argv[0] if(productName.includes('我的应用-uat')) { // 根据不同环境的productName 来区分生产和测试 } else { // 测试环境 } } }
-
beforePack.js 主要是在打包前清空dist目录
javascriptmodule.exports = function afterPack () { const shell = require('shelljs') // 清空dist目录 shell.rm('-rf', './dist') }
这里用到的shell.js是一个在node环境下使用shell命令的库,在使用前需要在electron-app目录下执行:
npm i shelljs --save-dev
-
afterAllArtifactBuild.js主要是在构建完成后,将打包好的dist目录下的相关文件复制到存放静态资源的服务器目录下,具体代码如下:
javascriptmodule.exports = function afterAllArtifactBuild (buildResult) { const copyPath = buildResult.configuration.productName === '我的应用-uat' ? '测试服务器路径' : '生产服务器路径' const shell = require('shelljs') shell.rm('-rf', copyPath) setTimeout(() => { // 这里使用定时器的主要原因是构建完成后还会根据electron-updater模块生成latest.yml文件,为了保证这个文件可以一起被复制到发布目录 shell.cp('-R', 'dist/', copyPath) shell.rm('-rf', copyPath + '/win-unpacked') shell.rm('-rf', copyPath + '/builder-*') }, 3000) }
最终成果
使用了以上方法,原本繁琐的构建步骤,全部都可以简单的通过 执行一条 npm run pack:test
完成了,是不是非常方便! 也在你的项目里用起来吧,如果对你有帮助的话,记得点赞+关注~