背景
咱们应用 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可供选择,用来查看是否须要更新,并解决具体的更新过程。
施行
在文档中看到macOS要实现自动更新的话,签名是必须的。
- macOS机器上打包:electron-builder会从零碎的钥匙串里找到配置里或者环境变量CSC_LINK(CSC_NAME)的对应的证书来进行签名
- Windows机器上打包:个别有两种类型的证书,咱们应用的是带USB加密器的EV Code Signing Certificate
签名之后也能让用户晓得利用开发者的身份,不至于是来历不明的软件。
筹备好签名证书之后,咱们将现有的降级逻辑进行优化,这里间接应用了官网的autoUpdater:
- 应用autoUpdater中的办法替换现有计划中的降级逻辑
- 思考主动降级失败的备用计划,在主动降级失败时,应用原有的降级逻辑中的计划,让用户重新安装残缺的安装包
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()})
为了配合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,或者微信扫码理解详情。