前言
前段时间,我用electron-vue开发了一款跨平台(目前支持Mac和Windows)的免费开源的图床上传应用——PicGo,在开发过程中踩了不少的坑,不仅来自应用的业务逻辑本身,也来自electron本身。在开发这个应用过程中,我学了不少的东西。因为我也是从0开始学习electron,所以很多经历应该也能给初学、想学electron开发的同学们一些启发和指示。故而写一份Electron的开发实战经历,用最贴近实际工程项目开发的角度来阐述。希望能帮助到大家。
预计将会从几篇系列文章或方面来展开:
- electron-vue入门
- Main进程和Renderer进程的简单开发
- 引入基于Lodash的JSON database——lowdb
- 跨平台的一些兼容措施
- 通过CI发布以及更新的方式
- 开发插件系统——CLI部分
- 开发插件系统——GUI部分
- 想到再写…
说明
PicGo
是采用electron-vue
开发的,所以如果你会vue
,那么跟着一起来学习将会比较快。如果你的技术栈是其他的诸如react
、angular
,那么纯按照本教程虽然在render端(可以理解为页面)的构建可能学习到的东西不多,不过在main端(electron的主进程)应该还是能学习到相应的知识的。
如果之前的文章没阅读的朋友可以先从之前的文章跟着看。
LOGO的准备
经过前面几篇文章的实战,我相信大家已经对于构建一个基本的electron应用没有太多的问题了。本文主要阐述一下如何让我们的应用通过CI系统来自动帮我们构建应用,然后发布给用户使用。以及之后如果有更新,要如何通知用户更新。
当然,在此之前,我们还需要做一件事:给你应用加上好看的LOGO。LOGO的设计和制作不在本文的设计范围内。为了我们的应用能够跨平台地使用,不同平台上应用的LOGO尺寸和格式也不尽相同。三个平台所需的图片格式如下:
- Linux - png
- macOS - icns
- Windows - ico
准备一张1024*1024以下,256*256以上(长宽一致)的png图片,(推荐512 * 512)然后我们可以用一些工具来实现从png到其他两种格式。搜索png转ico或者png转icns的话有很多在线转换的网站,可以去上面在线转换。在mac上我推荐用的是image2icon这个工具。
然后我们将所得的三个图片文件,放到electron-vue项目根目录的build/icons/
目录下。
不同平台的构建配置
本文我们主要采用electron-vue已经配置好的基于electron-builder的构建脚本来进行我们的应用构建。构建脚本会读取package.json
里的build
字段里的配置来进行构建。electron-vue默认的配置如下:
1 | "build": { |
简单讲述一下build配置里的一些字段的含义。
首先productName
是你的应用的名字。appId
的作用是用于Windows平台区分应用的标识。(注意该配置必须配置,而且稍后会有使用该配置的地方。如果不配置不使用的话,构建出来的Windows平台的应用将无法发送eletron的桌面通知)dmg
这个配置里描述了macOS平台里,打开dmg
安装包后显示的界面里的信息。如下图:
表示了有两个标识,一个是应用文件,坐标是(130, 150)
, 一个是应用文件夹的快捷方式,坐标是(410, 150)
。
directories
的output
字段是你应用打包完生成的文件放置的目录。
files
指明了要打包的目录。
而mac
,win
,linux
是针对三个平台的不同的配置了。可以看出默认的配置里对它们的配置都是指向了不同的icon图标(也就是上一节所说的LOGO)。
PicGo在实际开发中,针对一些情况对默认的build
配置项做出了一些增改:
1 | "build": { |
由于PicGo在macOS上主要是一个顶部栏应用,所以在底部docker栏我并不想拥有一个占位的图标,所以在mac
字段里加入了:
1 | "extendInfo": { |
这个属性。参考相关issue。
在Windows平台上,默认打包出来的安装包并没有办法选择安装的路径,只会默认装到C盘的用户目录。这个并不是我们想要的。我们想要的是让用户自己选择安装的路径。
所以需要修改windows
的一些配置以及加上一个nsis
的配置来实现:
1 | "win": { |
由于目前我还没有打包过Linux平台的应用,所以Linux相关的配置暂时先不做修改。
Windows平台打包的一个小坑
还记得前面说到的一个配置:appId
么,这个配置需要我们在主进程index.js
里也要使用。否则打包后的应用将失去Windows平台的应用通知功能。这个appId
是可以任意取的,只要保证不和其他应用重复即可。对于PicGo而言,appId
是com.molunerfinn.picgo
。
打开你的main/index.js
,在Windows平台的时候加上这个appId
:
1 | // ... |
这样就解决了通知的那个问题。
通过CI系统自动构建与发布
版本相关
发布应用其实是一个比较繁琐的活,往往跟你的版本控制绑在一块,所以通常在项目开始的阶段就要有所布局。我说说我的做法吧,不一定很科学,不过简单易行。
- 仓库主要两个分支,一个dev一个master。平时在dev上开发,只有在发布新版的时候merge到master上。
- 书写简单的更新版本的脚本,一键打tag+push到GitHub。
- 结合CI系统,自动构建master分支的代码,并将应用推送到GitHub仓库去。
其中简单的更新版本的脚本我是在package.json
里写了简单的scripts
:
1 | "scripts": { |
里面用到了npm的一个命令,npm version [options]
,具体可以参考version的文档。简单来说,它能够自动帮你升级版本,修改package.json
里的version,并打上相应的git tag,很方便。
举个例子,一个符合语义的版本号通常由如下三个部分组成:major.minor.patch
,比如1.5.3
。如果我运行了npm run patch
,那么将会将小版本更新:1.5.4
,同时修改package.json
里的version
字段为1.5.4
并自动打上一个git tag 1.5.4
,并将这个修改和tag推送到远端。
不过需要注意的是,一开始我是通过electron-vue自带的npm run build
这个脚本让CI去执行构建,但是发现无法自动上传到GitHub的release里。所以通过查阅相关资料后,发现最简单的就是把对应的npm scripts命名为release
。于是我把原本的npm run build
的脚本复制了一遍,起了一个新名release
:
1 | "scripts": { |
CI相关
说到这里都还没说到CI系统。什么是CI?可以参考阮一峰老师给出的解释《持续集成是什么?》。我们如果每次发布应用都需要我们在本地构建,然后手动上传到GitHub(或者其他地方)去,然后让别人能下载的话,未免太累了。而且通常我们开发electron应用就是为了能够跨平台,但是要构建不同的平台的应用意味着我们要在不同的平台分别构建。这也是不能忍受的。
于是网上有一些第三方的CI系统,它们能够帮我们,在某些分支(比如master)发生了某些更新(比如更新了tag)的时候帮我们执行某些脚本(比如构建、测试)。这样就省却了我们在本地、多平台构建的烦心事,而且让一些都变得「自动化」了起来。
有了CI之后,我的electron应用的发布就变成这样的流程了:
这样,我们只需要Push代码足矣。
针对Linux或者macOS的构建,我们可以使用Travis-CI,针对Windows平台的构建,我们可以使用AppVeyor。一个好消息是,它们对于在GitHub上的开源项目都是可以免费构建的,并且和GitHub的仓库结合地特别好,配置也比较简单,可以说的非常良心了。
在使用它们之前,我们需要给予它们一定的权限让它们能够访问我们的GitHub仓库。所以需要:
- 用你的GitHub账号注册它们,才能获取你的仓库列表。
- 在GitHub上生成token,赋予CI系统读写你的仓库的权限。生成token的具体操作可以查看之前我写的一篇针对hexo持久化构建的文章。
- 针对不同的CI平台创建不同的配置文件,好让它们知道你要它们执行什么操作。不过electron-vue很友好地为我们准备了Travis-CI的配置文件模板
.travis.yml
和AppVeyor的配置文件模板appveyor.yml
。所以我们基本上只需要在它们的基础上小修改即可。
Travis-CI
注册并登录Travis-CI后,找到你要构建的仓库,然后打开,点击设置进入如下页面:
配置一下环境变量,名为GH_TOKEN
,token的值就是上一步我们在GitHub生成的token。等会会有用。
PicGo经过修改后的.travis.yml
如下:
1 | # Commented sections below can be used to run tests on the CI server |
抛去很多前置依赖(比如C++编译库之类的)和构建环境(是什么系统,是什么语言),那些都是electron-vue给我们预置好的。我们需要注意的仅仅是几个部分:
- script
- branches
- after_script
script
是当系统和环境和依赖都准备好之后,你要CI运行的命令。在这里我运行了两个命令,一个是npm run release
,这个就是打包构建应用啦,并且执行了这个命令之后,electron-builder
会自动将生成好的安装包推送到我们GitHub仓库的draft release里。另一个是构建PicGo主页的命令yarn run build:docs
。
branches
声明了你要在哪些分支在GitHub接收到了代码更新之后就构建,这里我们自然选择的是master。
after_script
是当你执行完script里的脚本之后要做的事。可以为空。对于我而言主要在这个部分将上一步构建好的PicGo主页推送到GitHub的gh-pages
分支。当然如果你的应用有使用说明、文档之类的网站,也可以在这里进行构建和推送。
注意到,在after_script
命令的最后一行,有个${GH_TOKEN}
,这个就是我们之前在Travis-CI配置里配置的环境变量GH_TOKEN
。用环境变量的好处是不会暴露你的TOKEN,只有构建系统知道。
AppVeyor
有了之前的经验,AppVeyor就更简单了。注册登录后,我们在主页添加一个PROJECT,选中你要构建的仓库。然后找到SETTING设置:
然后在左侧的Genral
一栏的内容区中,找到构建的分支为master,以及设置我们仅在tag
更新的时候构建:
当然这个都是根据项目实际来的配置,我只是说PicGo的项目是这样配置的。
然后在左侧的Environment
区,找到环境变量配置,我们依然写入GH_TOKEN
:
修改完配置都别忘了拉到底部去保存!
这样就算配置完了网页端的。而现在我们来看看appveyor.yml
这个配置文件:
1 | # Commented sections below can be used to run tests on the CI server |
依然是只需要关注我们所关心的配置即可。一个是branches
,一个是build_script
。有了Travis-CI
的.travis.yml
的经验,我相信你也能很快理解它。
经过上述配置之后,你已经实现了一个简单的前端工程的自动化构建推送流程了。而今你只需要关注代码提交,应用的构建都将会由CI系统自动帮你完成。当然CI系统也不仅仅是拿来构建electron应用的,正如你所见的,你能想到的其他项目的构建、测试其实它都能帮你通过预定义好的脚本完成。
发布Release
当CI构建玩应用,会将其推送到你的GitHub的release页面成为一个draf
(草稿),你可以编辑这个草稿,加上标题和更新说明,就可以点击publish
发布你的新版本的应用啦。
electron应用的更新
electron应用的自动更新其实社区有很好的解决方案electron-updater。而electron-vue也在主进程的main/index.js
里预先帮我们写好了一段注释的代码:
1 | // import { autoUpdater } from 'electron-updater' |
只要引入autoUpdater就能自动帮我们检查更新和自动下载安装更新。不过,凡事都有不过。这个方式虽然很简单,但是它需要的条件比较严格,需要你拥有证书用于应用签名。而macOS平台下的证书需要你申请开发者,一年99$的费用让我望而却步。
于是我只能退而求其次,能不能通过查询GitHub的release版本号,来比对当前版本,是否需要更新,并提醒用户呢?经过尝试,发现可行。我的实现方法如下:
我首先写了一个updateChecker
的助手:
1 | import { dialog, shell } from 'electron' |
然后在main/index.js
里,我在app准备启动的时候,调用这个更新助手:
1 | // ... |
这样就能在启动应用的时候弹出更新提示:
总结
本文简要地讲述了electron应用用上CI系统帮我们自动化构建和推送,以及在没有申请开发者,没有证书用于应用的代码签名的情况下如何告知用户进行应用更新。要做一个健壮的应用就应该考虑到应用的版本发布、版本更新和对用户的更新通知。
本文很多都是我在开发PicGo
的时候碰到的问题、踩的坑。也许文中简单的几句话背后就是我无数次的查阅和调试。希望这篇文章能够给你的electron-vue
开发带来一些启发。文中相关的代码,你都可以在PicGo的项目仓库里找到,欢迎star~如果本文能够给你带来帮助,那么将是我最开心的地方。如果喜欢,欢迎关注我的博客以及本系列文章的后续进展。
注:文中的图片除未特地说明之外均属于我个人作品,需要转载请私信