桌面应用和 Web 应用最大的不同之一,就是版本更新不再只是刷新浏览器那么简单。用户本地安装的软件需要替换二进制文件、处理配置文件兼容性、在操作系统层面做版本标记——每一步出问题都可能让用户打开应用时报错甚至无法启动。因此,理解 Electron 应用自动更新的原理,是构建生产级桌面应用时必须掌握的一课。
目前主流的 Electron 自动更新方案(如 electron-updater、electron-builder 内置的 auto-update 机制)都围绕两种更新策略展开:全量更新和增量更新。它们各有优劣,也适用于不同的分发渠道和用户体验预期。
17.1.1 全量更新:简单可靠的主力方案
全量更新是最基础也最稳妥的更新方式。原理非常简单:当有新版本发布时,客户端下载一个完整的安装包(.exe、.dmg 或 .zip),然后替换旧的应用程序目录。用户下一次启动应用时,就会运行新版本。
具体流程(以 Windows 为例)
- 检测更新:应用启动后,主进程向后端 API 或静态文件服务器发送请求,检查是否有新版本。通常会携带当前版本号、平台信息,后端返回最新版本号、下载地址和更新日志。
- 下载安装包:如果存在新版本,应用通过 HTTP 请求下载完整的
.exe安装包或便携版压缩包。文件大小通常在 100MB 到 200MB 之间(因为包含了完整的 Chromium 和 Node.js),下载过程会在后台运行,并可以向渲染进程报告进度。 - 应用更新:下载完成后,Electron 不会直接修改自己正在运行的文件(操作系统会锁住可执行文件),而是采用“两阶段替换”策略:
- 将下载的文件解压到临时目录。
- 调用操作系统的安装程序或脚本,在应用退出后完成替换,然后重新启动。
- 用户无感重启:常用的方式是通过
autoUpdater.quitAndInstall()在用户关闭窗口时自动执行替换;也可以弹出提示“更新已下载,是否立即重启?”让用户主动触发。Windows 上通常借助 NSIS 或 Squirrel 安装器,macOS 则依赖.dmg内部的.app替换。
优点
- 实现简单:服务器端只需要保存每个版本的完整安装包,无需额外计算差分包。
- 可靠性高:每个更新包自包含完整的应用,不会因为本地文件状态不一致导致崩溃。
- 普适性强:适合任何分发场景(官网下载、GitHub Releases 托管、企业私有云等)。
缺点
- 带宽与时间成本高:每次更新都要下载上百兆,对于网络条件差的用户不友好,也增加了服务器的流量费用。
- 磁盘占用大:下载过程中需要在临时目录存放完整包,部分磁盘空间紧张的老设备可能失败。
在实际项目中,绝大多数 Electron 应用都采用全量更新——不是因为它是完美的,而是因为它足够简单,出错概率最低。像 Postman、Slack、Figma 等知名应用,也都是后台静默下载完整安装包,下次启动时自动替换。
17.1.2 增量更新:按需下载差异内容
增量更新的理念是只下载新旧版本之间的文件差异,而不是整个安装包。它借鉴了现代软件(尤其是 Chrome、VS Code)的补丁机制,能将更新包体积从几百兆缩减到几兆甚至几百 KB。
实现原理
通常使用 electron-updater 结合 nsis-web 或 AppImage 等支持增量更新的打包格式。其核心依赖于一种叫 BSDiff(Binary Diff) 或 Courgette(Chromium 使用的差分算法) 的二进制差分技术。具体步骤:
- 服务端在每次发布新版本时,预先计算上一个版本(或多个历史版本)与新版本之间的
.patch补丁文件。 - 客户端检测到更新后,不再直接下载完整安装包,而是下载这个体积小得多的补丁文件。
- 客户端在本地使用补丁文件与旧的安装目录内容进行合成,生成新版本的完整文件。
- 后续的替换和重启流程与全量更新一致。
以 VS Code 为例,它的 Windows 安装器使用了 Inno Setup 搭配自定义差分系统,每次更新通常只有几 MB,用户体验接近原生。其背后是微软维护的一套成熟增量更新管道,能保证差分生成高度可靠。
优点
- 更新极快:补丁体积经常只有全量包的 5% 甚至更小,几秒钟即可完成下载。
- 节省流量:显著降低服务器带宽成本和用户流量消耗,尤其适合移动热点或按流量计费的网络环境。
缺点
- 引入复杂度:需要服务端支持差分生成逻辑,客户端必须具备可靠的补丁应用能力和回滚机制。
- 容错性要求高:如果本地文件被手动修改、杀毒软件误删或磁盘损坏,差分合成可能失败,此时必须回退到全量更新作为兜底。
- 跨大版本升级困难:若用户跳过了多个版本,可能需要链式应用多个补丁,累积错误风险增加。
真实项目中的取舍
大部分中小团队或独立开发者会优先选择全量更新,把时间花在打磨业务功能上。只有当你的应用体量很大、用户分布在网络欠佳的地区,或者每日发版频繁时,增量更新才值得投资。即便采用增量,通常也会保留一个“完整包下载”的兜底链接,当补丁应用失败时自动切换,保证用户至少能更新成功。
17.1.3 安全与签名
无论采用哪种更新策略,都不能忽视代码签名和完整性校验。操作系统在安装或启动应用时会验证开发者签名,防止恶意篡改。
- Windows:需要 Authenticode 代码签名证书打签
.exe和安装包,否则 SmartScreen 会拦截下载,甚至直接阻止运行。 - macOS:必须使用 Apple 签发的 Developer ID 证书对
.app进行签名和公证,否则会被 Gatekeeper 阻止。 - Linux:虽然签名不是强制的,但使用 GPG 签名
.deb或.rpm仓库仍然是推荐的安全实践。
自动更新过程中,下载的文件也必须经过哈希校验(SHA256 或 MD5),确保文件未被中间人篡改。electron-updater 默认会校验通过 HTTPS 拉取的安装包与发布服务器提供的哈希值是否匹配。
17.1.4 更新策略的工程化选择
最后,从工程落地的角度,你可以遵循几个简单原则来设计自动更新的架构:
- 先上全量,后看需求:初期版本直接使用
electron-updater的全量更新,稳定可靠。只有当用户反馈“更新包太大,流量受不了”时,考虑引入增量。 - 后端尽量用云存储:将安装包托管到 GitHub Releases、腾讯云 COS、阿里云 OSS 等对象存储服务,借助 CDN 加速,能极大降低服务器维护成本并提升下载速度。
- 提供手动更新入口:即使用户关闭了自动更新,也应该在菜单中保留“检查更新”按钮,避免因网络问题或用户主动拦截导致长期停留在旧版。
- 测试回滚场景:确保当更新失败或用户数据不兼容时,应用不会崩溃或数据丢失。日志记录和备份迁移脚本是必要的保障。
自动更新不是一个“炫技”功能,而是桌面软件的基本职业素养。它能让你在发现一个安全漏洞或严重 Bug 后,几小时内就将修复推送到所有用户设备上。理解全量和增量的原理,能帮你做出适合自己项目规模和用户场景的合理选择,让更新真正成为产品体验的隐形加速器,而不是令用户头疼的弹窗。