likes
comments
collection
share

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

作者站长头像
站长
· 阅读数 12

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

现状

本人最近接手了一个electron项目,项目里通过读取不同的config文件区分生产包和测试包,每次构建前都需要去手动修改导出config的文件,然后再构建。

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

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

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

存在的问题

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

解决方案

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

经过一番辛苦查阅各种资料、翻看文档以及实践之后,本人终于获得了解决方案。以下是具体实现步骤:

  1. 通过electron-builder的config参数,传入不同的构建命令,如:electron-builder --config ./build/uat.yml, 测试环境的配置文件如下:

    productName: 我的应用-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文件中的构建命令如下:

    "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"
    },
    
  2. 主渲染进程中判断环境的方法

    const { app } = require('electron')
    const getEnv = () => {
      if(!app.isPackaged) {
        // 未打包,本地开发环境
      } else {
        const productName = process.argv[0]
        if(productName.includes('我的应用-uat')) {
          // 根据不同环境的productName 来区分生产和测试
        } else {
          // 测试环境
        }
      }
    }
    
  3. beforePack.js 主要是在打包前清空dist目录

    module.exports = function afterPack () {
      const shell = require('shelljs')
      // 清空dist目录
      shell.rm('-rf', './dist')
    }
    

    这里用到的shell.js是一个在node环境下使用shell命令的库,在使用前需要在electron-app目录下执行:npm i shelljs --save-dev

  4. afterAllArtifactBuild.js主要是在构建完成后,将打包好的dist目录下的相关文件复制到存放静态资源的服务器目录下,具体代码如下:

      module.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 完成了,是不是非常方便! 也在你的项目里用起来吧,如果对你有帮助的话,记得点赞+关注~