Electron-builder打包和自动更新

前言

文本主要讲述如何为 electron 打包出来软件配置安装引导和结合 github 的 release 配置自动更新。

electron-builder 是将 Electron 工程打包成相应平台的软件的工具,我的工程是使用 electron-vite 构建的,其默认集成了 electron-builder ,下文也是基于 electron-vite 生成的工程进行讲解。

下文是基于 Window 平台讲解,所以安装包我也会说成 exe 文件

配置

electron-builder 有两种配置方式

  • 在 package.json 配置
  • 使用 electron-builder.yml 配置

如果打包命令带上 ---config,就是使用 electron-builder.yml 的方式,例如

bash 复制代码
electron-builder --win --config

以下介绍都基于 electron-builder.yml 的方式,如需使用 package.json,请自行翻阅文档转换

详见:CLI

NSIS安装引导

electron-builder 生成的安装包默认是一键安装,也就是无法选择安装路径等。这时候就需要用到 NSIS 了(注意:NSIS 只适用于 Window 平台)

只需要修改 electron-builder.yml 即可,我常用的配置如下:

yaml 复制代码
nsis:
  oneClick: false # 创建一键安装程序还是辅助安装程序(默认是一键安装)
  allowElevation: true # 是否允许请求提升,如果为false,则用户必须使用提升的权限重新启动安装程序 (仅作用于辅助安装程序)
  allowToChangeInstallationDirectory: true # 是否允许修改安装目录 (仅作用于辅助安装程序)
  createStartMenuShortcut: true # 是否创建开始菜单快捷方式
  artifactName: ${productName}-${version}-${platform}-${arch}.${ext}
  shortcutName: ${productName}
  uninstallDisplayName: ${productName}
  createDesktopShortcut: always

详见:NsisOptions

自动更新

结合 github 的 release 配置自动更新

代码修改

  1. 修改 electron-builder.yml

    以 dubbo 仓库举例子:https://github.com/apache/dubbo

    yaml 复制代码
    # 仓库配置
    publish:
      provider: github # 选择github平台
      owner: apache # github用户名
      repo: dubbo # github仓库名
    # 更新日志
    releaseInfo:
      releaseNotes: |
       这是更新日志
       测试测试
  2. 工程代码修改

    我是基于 TypeScript 的写法,如果需要 JavaScript 的写法,请参考文档:Auto-Update官方案例

    • 安装 electron-updater

      bash 复制代码
      npm install electron-updater
    • 主线程添加自动更新代码

      jsx 复制代码
      import { autoUpdater, UpdateInfo } from 'electron-updater';
      
      // dev-start, 这里是为了在本地做应用升级测试使用,正式环境请务必删除
      if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
        autoUpdater.updateConfigPath = path.join(__dirname, '../../dev-app-update.yml');
      }
      Object.defineProperty(app, 'isPackaged', {
        get() {
          return true;
        }
      });
      // dev-end
      
      // 触发检查更新(此方法用于被渲染线程调用,例如页面点击检查更新按钮来调用此方法)
      ipcMain.on('check-for-update', () => {
        logger.info('触发检查更新');
        autoUpdater.checkForUpdates();
      });
      
      // 设置自动下载为false(默认为true,检测到有更新就自动下载)
      autoUpdater.autoDownload = false;
      // 检测下载错误
      autoUpdater.on('error', (error) => {
        logger.error('更新异常', error);
      });
      
      // 检测是否需要更新
      autoUpdater.on('checking-for-update', () => {
        logger.info('正在检查更新......');
      });
      // 检测到可以更新时
      autoUpdater.on('update-available', (releaseInfo: UpdateInfo) => {
        logger.info('检测到新版本,确认是否下载');
        const releaseNotes = releaseInfo.releaseNotes;
        let releaseContent = '';
        if (releaseNotes) {
          if (typeof releaseNotes === 'string') {
            releaseContent = <string>releaseNotes;
          } else if (releaseNotes instanceof Array) {
            releaseNotes.forEach((releaseNote) => {
              releaseContent += `${releaseNote}\n`;
            });
          }
        } else {
          releaseContent = '暂无更新说明';
        }
        // 弹框确认是否下载更新(releaseContent是更新日志)
        dialog
          .showMessageBox({
            type: 'info',
            title: '应用有新的更新',
            detail: releaseContent,
            message: '发现新版本,是否现在更新?',
            buttons: ['否', '是']
          })
          .then(({ response }) => {
            if (response === 1) {
              // 下载更新
              autoUpdater.downloadUpdate();
            }
          });
      });
      // 检测到不需要更新时
      autoUpdater.on('update-not-available', () => {
        logger.info('现在使用的就是最新版本,不用更新');
      });
      // 更新下载进度
      autoUpdater.on('download-progress', (progress) => {
        logger.info('下载进度', progress);
      });
      // 当需要更新的内容下载完成后
      autoUpdater.on('update-downloaded', () => {
        logger.info('下载完成,准备更新');
        dialog
          .showMessageBox({
            title: '安装更新',
            message: '更新下载完毕,应用将重启并进行安装'
          })
          .then(() => {
            // 退出并安装应用
            setImmediate(() => autoUpdater.quitAndInstall());
          });
      });

      上面的代码只是主线程的,还需要渲染线程和页面配置

发布 release

  1. 创建 token

    登录 github → 点击个人头像 → Settings → 选择Developer Settings → 创建token

    配置选择

    复制创建好的 token

  2. 给仓库设置 token

    回到 electron 工程项目 → Settings → Secrets and variables → Actions

    secret 的名字使用 GH_TOKEN,值就是刚才复制的 token

  3. 添加 github action 需要的文件

    在 .github/workflows 文件夹下创建 build.yml 文件,内容如下(请自行把注释删掉)

    我们这里就用到了上一步配置的 GH_TOKEN

    yaml 复制代码
    name: build
    
    # 当提交tag时触发
    on:
      push:
        tags:
          - "*"
    
    jobs:
      build:
    
        runs-on: windows-latest
    
        steps:
        # 步骤1,检出仓库代码
        - name: Check out Git repository
          uses: actions/checkout@v3
        # 步骤2,使用node环境
        - name: Use Node.js
          uses: actions/setup-node@v3
          with:
            node-version: 18.x
            cache: 'npm'
        # 步骤3,执行npm install命令,安装依赖
        - name: Install dependencies
          run: npm install
        # 步骤4,执行打包命令(请自行修改成自己的打包命令)
        - name: build win
          run: npm run build:win
          env:
            GH_TOKEN: ${{ secrets.GH_TOKEN }}
        # 步骤5,发布release,需要注意包含的3个文件
        - name: release
          uses: softprops/action-gh-release@v1
          with:
            files: |
             dist/*.exe
             dist/*.exe.blockmap
             dist/latest.yml
            draft: false
          env:
            GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}

    看清楚注释,作业别闭眼抄哈

  4. 发布

    提交代码,推送tag,等待几分钟,release 就构建好了

总结

没啥好总结的


参考资料

electron-builder

GitHub Actions

相关推荐
转角羊儿9 分钟前
uni-app文章列表制作⑧
前端·javascript·uni-app
大G哥16 分钟前
python 数据类型----可变数据类型
linux·服务器·开发语言·前端·python
hong_zc40 分钟前
初始 html
前端·html
小小吱1 小时前
HTML动画
前端·html
Bio Coder1 小时前
学习用 Javascript、HTML、CSS 以及 Node.js 开发一个 uTools 插件,学习计划及其周期
javascript·学习·html·开发·utools
糊涂涂是个小盆友1 小时前
前端 - 使用uniapp+vue搭建前端项目(app端)
前端·vue.js·uni-app
浮华似水1 小时前
Javascirpt时区——脱坑指南
前端
王二端茶倒水2 小时前
大龄程序员兼职跑外卖第五周之亲身感悟
前端·后端·程序员
_oP_i2 小时前
Web 与 Unity 之间的交互
前端·unity·交互
钢铁小狗侠2 小时前
前端(1)——快速入门HTML
前端·html