Electron 应用的迭代速度通常比传统桌面软件快得多,因此一套可靠的自动更新机制是项目走向成熟的必经之路。本节不会罗列所有可选方案,而是聚焦于一个经过大量项目验证的务实组合:electron-updater + 静态文件服务 + 灰度策略,并说明在出问题时如何安全回滚。
17.5.1 更新服务的核心原理
Electron 的自动更新并不是框架自带的黑盒功能,而是由专门模块负责:主进程检查远端服务器上的最新版本信息,对比本地版本后决定是否下载安装包,然后提示用户或静默更新。
整个流程可以抽象成:
- 构建:打包时生成安装包(
.exe/.dmg/.deb)和对应的latest.yml(或latest-mac.yml等)元信息文件。 - 发布:将安装包和元信息文件上传到可公开访问的静态服务器(或对象存储)。
- 检查:应用启动时(或定时),主进程请求元信息文件,对比版本号。
- 下载与安装:若远端版本更高,下载对应系统的安装包,校验签名后执行安装(Windows 下通常静默替换,macOS 下依赖
Squirrel.Mac,Linux 下由包管理器或 AppImage 处理)。
这里推荐使用 electron-updater(由 electron-builder 团队维护),它已经封装好了版本比对、下载、进度回调、签名验证和平台适配。你不需要关心不同操作系统的安装细节。
17.5.2 搭建最简更新服务
真实的项目中,更新服务不一定需要自己写一套后端接口。最实用的做法是利用对象存储(OSS)或静态站点托管,直接走 HTTP 文件下载。
步骤:
- 打包生成更新文件
在 electron-builder 的配置中开启 publish 或者直接在构建命令中指定:
// package.json 中的 build 配置
"build": {
"appId": "com.yourcompany.app",
"publish": [{
"provider": "generic",
"url": "https://update.yourdomain.com/download"
}]
}
运行 npm run build 后,会在输出目录生成 latest.yml、latest-mac.yml 和对应的安装包。
- 上传到服务器
将整个输出目录(或仅安装包和 .yml 文件)上传到服务器,确保目录结构与 .yml 中记录的路径一致。例如:https://update.yourdomain.com/download/your-app-1.0.0.exehttps://update.yourdomain.com/download/latest.yml
- 主进程初始化更新检查
在主进程中添加代码:
const { autoUpdater } = require('electron-updater');
autoUpdater.setFeedURL('https://update.yourdomain.com/download');
autoUpdater.checkForUpdatesAndNotify();
如果需要更精细的控制,可以监听 autoUpdater 的事件:
autoUpdater.on('checking-for-update', () => { /* 通知渲染进程 */ });
autoUpdater.on('update-available', (info) => {
// info.version 远端版本号,可询问用户是否立即更新
});
autoUpdater.on('update-downloaded', (info) => {
// 下载完成,提示用户重启安装
autoUpdater.quitAndInstall();
});
- 处理平台差异
- Windows:
electron-updater默认使用 NSIS 安装器,支持静默更新。你需要为安装包做好数字签名(使用sign配置),否则部分杀毒软件会拦截。 - macOS:要求应用签名且公证,否则更新后无法启动。发布前需用
electron-builder的mac.notarize配置完成公证。 - Linux:
.AppImage支持自动更新,.deb和.rpm需要依赖系统包管理器,此时electron-updater只能检测更新并引导用户去下载新包。
17.5.3 灰度发布:安全地推送新版本
直接全量推送新版本的风险很大——一旦新版包含严重 Bug,影响所有用户。灰度发布可以让一部分用户先更新,验证稳定性后再逐步扩大范围。
实用方案:控制更新元信息文件
electron-updater 检查更新时抓取的是 latest.yml,而这个文件里的版本号决定了谁可以更新。我们只需要在后端动态生成或切换 latest.yml 即可实现灰度。
具体实现方式之一:Nginx + 程序化规则
在更新服务器上,不直接提供静态的 latest.yml,而是由一个小型 Web 服务根据请求参数(如用户 ID、版本渠道等)返回不同的元信息文件。
例如,用户请求 https://update.yourdomain.com/download/latest.yml?userId=xxx,后端逻辑可以:
- 对于 稳定渠道 用户:返回当前全量稳定版本的元信息。
- 对于 灰度用户(例如 userId 哈希取模后属于 5% 分段):返回新版本的元信息。
- 请求头或其他标识可以用来区分。
electron-updater 本身支持自定义请求头,你可以在 setFeedURL 时附加动态参数:
autoUpdater.setFeedURL({
provider: 'generic',
url: 'https://update.yourdomain.com/download',
requestHeaders: { 'X-User-Id': userId }
});
然后后端根据 X-User-Id 决定返回哪个版本的 latest.yml。如果不方便改后端,也可以用更简单的方法:预先上传两个文件 latest-stable.yml 和 latest-canary.yml,灰度用户直接指定不同的 URL:
const feedUrl = isGrayUser
? 'https://update.yourdomain.com/download/canary'
: 'https://update.yourdomain.com/download/stable';
autoUpdater.setFeedURL(feedUrl);
灰度比例可以通过应用内置的远程配置中心(如 Firebase Remote Config 或自建配置接口)动态调整,无需发布新版本。
灰度验证指标
灰度期间需要重点监控:崩溃率(可使用 electron-crash-reporter 接入 Sentry)、关键业务流程报错、主进程异常。如果新版崩溃率明显升高,立即将灰度用户切回稳定元信息。
17.5.4 版本回滚:当新版本出现严重事故时
在 Electron 中,“回滚”并不是让已安装的新版本自动降级到旧版本(技术上不可靠且风险高),而是停止向更多用户推送问题版本,并引导已更新的用户退回稳定版。
策略一:立即下线问题版本元信息
如果更新服务通过动态 latest.yml 控制,直接把灰度或全量的元信息回退到上一个稳定版本的元信息文件。新打开应用的用户只会检测到与本地相同或更低的版本,不会触发更新;尚未下载的用户将下载到旧版本。此时就切断了问题版本的扩散。
策略二:强制降级提示(慎用)
如果问题非常严重(例如数据损坏),需要让已更新的用户主动降级。可以在应用启动时,主进程请求一个“强制降级”配置接口,若返回需要降级,则给出弹窗并引导用户去官网下载旧版安装包,或者在新版本中用内建逻辑下载指定的旧版安装包并执行替换安装(技术上等价于覆盖安装旧版本)。注意:这个操作需要非常谨慎,因为执行另一个安装程序可能被杀毒软件拦截,且用户体验不佳。
策略三:利用 Electron 的多版本共安装(罕见)
对于 Windows 和 macOS,通常一个应用只有一个安装位置。降级时安装旧版安装包会直接覆盖(Windows NSIS 安装器默认行为),或要求用户手动拖拽(macOS)。因此,更务实的做法是:发布一个紧急修复版(hotfix),版本号高于问题版本但修复了 Bug,利用自动更新推送给所有用户。这是一种“向前回滚”,比真正的降级更安全。
17.5.5 实战要点与避坑指南
- 更新 URL 必须 HTTPS
生产环境必须使用 HTTPS,否则安装包可能在传输过程中被篡改或替换,造成严重安全隐患。
- 签名与公证是绕不开的门槛
- Windows:使用正规代码签名证书(EV 证书更好),否则 Windows Defender 会报“未知发布者”,自动更新静默安装会被拦截。
- macOS:必须经过苹果公证(notarization),否则 macOS Gatekeeper 会阻止应用打开。
electron-builder提供了afterSign钩子配合@electron/notarize完成公证流程。
- 处理网络异常与更新失败
有部分用户网络环境特殊,可能无法下载更新文件。需要做好超时、错误重试逻辑,并在界面上给出明确提示,而不是静默失败。
- 更新提示的用户体验
强制更新会打断用户工作,更好的方式是提供“稍后提醒”和“下次自动安装”的选项。可以利用 autoUpdater 的事件结合渲染进程的弹窗组件实现友好交互。
- 大型应用的分包更新
如果应用超大(如几百 MB),可以使用 electron-updater 的 differentialUpdate(差量更新),或把部分静态资源放在线 CDN 动态加载,缩小安装包体积。
- 监控与报警
务必为自动更新流程添加监控:更新检查成功率、下载时间、安装成功率等。可以将这些指标上报到类似 Sentry 或自定义后端,一旦更新成功率骤降,就能立刻收到报警并介入。
- 灰度与回滚的自动化
初期可以手动修改灰度比例和回滚版本,但更成熟的做法是搭建一个更新管理后台,让产品和运维同事可以直接操作版本发布和灰度策略,减少开发介入。
自动更新是 Electron 应用生命线的一部分。它让你能够像 Web 一样频繁地修复 Bug 和发布特性,同时又不让用户感知到复杂的安装过程。只要提前把更新服务、灰度策略和应急回滚机制搭建好,你就能拥有快速迭代的底气,而不必担心上线后陷入“用户流失因为旧版本坏掉了却无法修复”的窘境。