乐趣区

关于electron:如何为Electron应用实现自动更新

背景

咱们应用 Electron 开发了一个桌面端开发工具 Ada 工作台,提速增效前端开发,在更新比拟频繁的状况下,为了使整个更新体验更为顺畅、晋升工作台的降级比率,须要优化以后的更新机制,尽量做到 VSCode 的无感知更新。

Electron 是一个应用 JavaScript, HTML 和 CSS 等 Web 技术创立原生利用的框架,应用 Electron 这个框架创立的桌面应用程序就是 Electron 利用。

Electron 现有的相干类库:

打包工具:

  • Electron Forge 除了打包还提供了我的项目脚手架、我的项目模版等性能
  • electron-builder 打包、签名,残缺的打包工具

更新服务器:

  • Hazel 依赖 Github Release
  • Nuts 依赖 Github Release
  • electron-release-server 不须要依赖 Github Release,独自部署
  • Nucleus 不须要依赖 Github Release,独自部署

现状

介绍了一些通用的背景常识之后,来看看咱们现有的版本升级计划:

  • 打包工具:通过 electron-builder 进行利用的打包和签名
  • 散发服务器:打包后的安装程序上传到一个自建的服务器 electron-release-server
  • 降级逻辑:利用内自行编写更新逻辑,通过定时器查问是否有新的版本可供下载,如果有,将一个残缺的安装程序下载到本地,下载实现后提醒用户,用户确认后能够启动新的安装程序装置笼罩原有的版本

目前版本升级时的成果:

  • Windows: 利用敞开,并呈现一个小小的装置进度条用于期待利用装置结束,装置结束后主动启动新的利用
  • macOS: 利用敞开,并呈现装置界面,须要手动拖拽到利用文件夹,而后手动从利用文件夹内关上利用

看起来不错,曾经实现了根本的更新逻辑,然而成果上让人不称心,与同样是 Electron 利用的 VSCode 的降级成果相差甚远,心愿实现的成果是:让用户不必再期待一个新的装置过程,咱们替用户去装置。每当有新版本公布时,用户只须要重新启动应用程序就能体验到最新的版本。

那么怎么能力实现这个成果呢?

调研

现有的打包工具和更新服务器曾经在稳固运行,咱们先看看它们能不能实现咱们要的成果,如果不能,咱们再去尝试别的类库。

咱们应用的 electron-builder 和 electron-release-server 的文档中都有对 auto update 的形容。从这里能够看到服务器对更新文件是有类型要求的,比方 OS X 零碎上,安装文件只反对 dmg,更新文件只反对 zip,Windows 零碎上,安装文件只能是 exe,更新文件只能是残缺的 nupkg。而咱们的打包工具是反对生成这些文件的(打包工具要求 macOS 利用要应用自动更新的话必须签名)。在利用代码中,则有 electron-updater 和官网的 autoUpdater 可供选择,用来查看是否须要更新,并解决具体的更新过程。

施行

  1. 在文档中看到 macOS 要实现自动更新的话,签名是必须的。

    • macOS 机器上打包:electron-builder 会从零碎的钥匙串里找到配置里或者环境变量 CSC_LINK(CSC_NAME)的对应的证书来进行签名
    • Windows 机器上打包:个别有两种类型的证书,咱们应用的是带 USB 加密器的 EV Code Signing Certificate

签名之后也能让用户晓得利用开发者的身份,不至于是来历不明的软件。

  1. 筹备好签名证书之后,咱们将现有的降级逻辑进行优化,这里间接应用了官网的 autoUpdater:

    1. 应用 autoUpdater 中的办法替换现有计划中的降级逻辑
    2. 思考主动降级失败的备用计划,在主动降级失败时,应用原有的降级逻辑中的计划,让用户重新安装残缺的安装包
    autoUpdater.on('checking-for-update', () => {
      // 开始查看是否有新版本
      // 能够在这里揭示用户正在查找新版本
    })
    
    autoUpdater.on('update-available', (info) => {
      // 查看到有新版本
      // 揭示用户曾经找到了新版本
    })
    
    autoUpdater.on('update-not-available', (info) => {
      // 查看到无新版本
      // 揭示用户以后版本曾经是最新版,无需更新
    })
    
    autoUpdater.on('error', (err) => {
      // 主动降级遇到谬误
      // 执行原有降级逻辑
    })
    
    autoUpdater.on('update-downloaded', (ev, releaseNotes, releaseName) => {
      // 主动降级下载实现
      // 能够询问用户是否重启利用更新,用户如果批准就能够执行 autoUpdater.quitAndInstall()})
  2. 为了配合 electron-release-server 对更新文件的要求,咱们须要批改打包配置。

    打包工具现有的打包配置 mac 关键词的 target 是 default,也就是打包 mac 利用时默认会生成 dmg 和 zip 文件,而 win 关键词的 target 是默认的 nsis,打包后只生成了 exe 文件,并没有 nupkg 文件。于是尝试将 target 改为 squirrel,会依照 server 的要求生成 nupkg 文件用于更新,autoUpdater.quitAndInstall 之后具体的成果是:

    • Windows: 利用敞开,并呈现一个可自定义的 gif 图片用于期待利用装置结束,装置结束后主动启动新的利用
    • macOS: 利用敞开,大概一秒就启动了新的利用

比照咱们现有的成果,在 Windows 上差异不大,但进度条绝对于 gif 来说更好一点。在 macOS 上显著是新计划占优。于是我将 Windows 和 macOS 别离做了降级的逻辑,在 Windows 上仍旧走旧的降级逻辑,在 macOS 上通过 autoUpdater 来降级,并用旧逻辑作为备用计划。到此为止,咱们的更新计划就实现啦,最终的成果:

  • Windows: 利用敞开,并呈现一个小小的装置进度条用于期待利用装置结束,装置结束后主动启动新的利用
  • macOS: 利用敞开,大概一秒就启动了新的利用

踩坑

大部分状况下咱们不会是第一个遇到问题的人,有数前辈在互联网上留下了他们解决问题的计划,等着咱们从搜索引擎中将他们找到,然而”定义问题“自身就不是一件容易的事。留下一些开发过程中遇到的问题的解决方案,当作后来者的宝藏。

  • autoUpdater.setFeedURL 出错。

    autoUpdater.on('error', (err) => {console.log(err) //"Error: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection."
    })

    第一个遇到的问题呈现得猝不及防,谬误的形容其实曾经很清晰,App Transport Security 要求资源通过平安的连贯来加载,也就是通过 HTTPS 协定。autoUpdater.setFeedURL 的 url 地址一看是 https 的,而后就略过了这里,殊不知起初发现这个接口中咱们又对 electron-release-server 的接口进行了封装,而 electron-release-server 的接口并不是 https 的。而后将 appUrl 改成 https 即可,btw,这个文档的地位可真难找。

  • electron-release-server 更新接口的查看更新逻辑问题。

    ${ADA_AUTOUPDATE_FEED_API}${platform}/${version}/${channel}

    channel 为 beta 时,预期是不论任何时候,只有 version 不是最新的 beta 版本,接口应该返回最新的 beta 版本。然而理论发现这个接口的实现跟上传工夫无关,比方 version 为 2.18.0-beta.202008051710 时,接口返回 2.18.0-beta.202008142217。这是失常的。然而 version 为 2.18.0-beta.202008051438 时,接口返回 2.18.0,返回的是 stable 的版本,并且没有按预期找到最新的 beta 版本。这是因为在接口内获取最新版本时,会依据版本创立工夫去进行一次筛选,并且对 channel 采取了优先级的过滤,比方咱们这里是 beta 版本,在获取新版本时会把优先级更高的 rc,以及 stable 版本都蕴含进来。

    没有思考提交 MR 是因为看得出来作者在这里是有本人的思考的,只是预期后果与咱们心愿的不一样而已,所以这里的解决方案是自行提供一个合乎咱们预期的接口。

  • Windows 上通过命令行打包乱码问题。

    因为证书中有中文,所以须要批改命令行编码模式为 utf-8,通过命令:chcp 65001,而后再次尝试即可。

总结

整体而言,Electron 的开发体验还是很不错的,不论是官网文档还是第三方类库都比较完善,还有 VSCode、Twitch、Facebook Messenger 为它背书。桌面跨平台软件在可见的将来仍旧是有不小的市场需求的,大家学起来吧!

招聘

咱们是智联大前端,作为智联招聘的前端架构团队,咱们在过来的几年中创始了细粒度的前端研发和公布模式,对立了挪动端和桌面端的技术栈,搭建了灵便牢靠的 Serverless 运行环境,率先落地了微前端计划,并且还在向 FaaS 和轻研发等方向一直迈进。

诚招前后端架构师和高级工程师,如果您也和咱们一样酷爱技术、酷爱学习、酷爱摸索,就请退出咱们吧!请将简历请发送至邮箱 zpfe@group.zhaopin.com.cn,或者微信扫码理解详情。

退出移动版