electron-updater实现热更新完整流程

11,887 阅读2分钟

最近项目做了一个electron项目,记录一下本次客户端热更新中对electron-updater的使用以及遇到的一些问题。

一、配置electron-builder

在electron-builder的配置文件"build"中增加

"publish": [
      {
        "provider": "generic",
        "url": "oss://xxx",
      }
    ]

url: 打包出来的文件存放的地址,配置之后会生成latest.yml文件。electron-updater会去比较这个文件,判断是否需要更新。

二、electron-updater的使用

官方文档: www.electron.build/auto-update…

主进程

import { autoUpdater } from "electron-updater";
const { ipcMain } = require("electron");

// 配置提供更新的程序,及build中配置的url
autoUpdater.setFeedURL("oss://xxx")
// 是否自动更新,如果为true,当可以更新时(update-available)自动执行更新下载。
autoUpdater.autoDownload = false

// 1. 在渲染进程里触发获取更新,开始进行更新流程。 (根据具体需求)
ipcMain.on("checkForUpdates", (e, arg) => {
  autoUpdater.checkForUpdates();
});

autoUpdater.on("error", function (error) {
  printUpdaterMessage('error');
  mainWindow.webContents.send("updateError", error);
});

// 2. 开始检查是否有更新
autoUpdater.on("checking-for-update", function () {
  printUpdaterMessage('checking');
});

// 3. 有更新时触发
autoUpdater.on("update-available", function (info) {
  printUpdaterMessage('updateAvailable');
  // 4. 告诉渲染进程有更新,info包含新版本信息
  mainWindow.webContents.send("updateAvailable", info);
});

// 7. 收到确认更新提示,执行下载
ipcMain.on('comfirmUpdate', () => {
  autoUpdater.downloadUpdate()
})

autoUpdater.on("update-not-available", function (info) {
  printUpdaterMessage('updateNotAvailable');
});

// 8. 下载进度,包含进度百分比、下载速度、已下载字节、总字节等
// ps: 调试时,想重复更新,会因为缓存导致该事件不执行,下载直接完成,可找到C:\Users\40551\AppData\Local\xxx-updater\pending下的缓存文件将其删除(这是我本地的路径)
autoUpdater.on("download-progress", function (progressObj) {
  printUpdaterMessage('downloadProgress');
  mainWindow.webContents.send("downloadProgress", progressObj);
});

// 10. 下载完成,告诉渲染进程,是否立即执行更新安装操作
autoUpdater.on("update-downloaded", function () {
    mainWindow.webContents.send("updateDownloaded");
    // 12. 立即更新安装
    ipcMain.on("updateNow", (e, arg) => {
      autoUpdater.quitAndInstall();
    });
  }
);

// 将日志在渲染进程里面打印出来
function printUpdaterMessage(arg) {
  let message = {
    error: "更新出错",
    checking: "正在检查更新",
    updateAvailable: "检测到新版本",
    downloadProgress: "下载中",
    updateNotAvailable: "无新版本",
  };
  mainWindow.webContents.send("printUpdaterMessage", message[arg]??arg);
}

渲染进程:

// 5. 收到主进程可更新的消息,做自己的业务逻辑
ipcRenderer.on('updateAvailable', (event, data) => {
  // do sth.
})

// 6. 点击确认更新
ipcRenderer.send('comfirmUpdate')

// 9. 收到进度信息,做进度条
ipcRenderer.on('downloadProgress', (event, data) => {
  // do sth.
})

// 11. 下载完成,反馈给用户是否立即更新
ipcRenderer.on('updateDownloaded', (event, data) => {
  // do sth.
})

// 12. 告诉主进程,立即更新
ipcRenderer.send("updateNow");

本地环境

如果想在本地环境调试更新,会报错找不到dev-app-update.yml文件 需要自己在根目录(或报错时显示的目录下)手动新建一个dev-app-update.yml里就可以了。文件,将打包生成好的latest.yml复制到dev-app-update.yml里就可以了。

完成截图

image.png

image.png