2

第一次开发Electron应用

背景

由于工作内容大多是一些日常活动,虽然活动都以已经做好模板为主,实际并不需要什么开发量,一般都是调一下按钮的位置、颜色、字体大小什么的就可以立即发布,但是运营觉得活动什么都要经过开发才能发布,影响他们的运营效率(╮(╯▽╰)╭ ),开始下达开发指令:希望能够模块化,通过拖拉就可以生成一个活动(°(°ˊДˋ°) ° 大致可以理解为类型MAKA这样生成H5的工具),好吧,么有交互,么有设计,给你这么大的空间,好好发挥,搞好加鸡腿。╮(╯▽╰)╭一脸懵逼, 表示么有做过,得回去好好思考一下。。。

Electron大法好

经过一段时间深入思考(挣扎纠结良久,快吐血了),(╯▔^▔)╯觉得使用Electron搞能够最大程度降低难度(本来也想做成后台应用的,但是我的直觉告诉我,怎么简单怎么来),能用web技术开发(效率扛扛),能利用巨多的nodejs模块(支持大大的好),能够摆脱兼容性问题(只需兼容一个浏览器,是一个啊,听着都幸福)。以上就是选择Electron开发的原因。

如何更新

既然要做成客户端,更新是个大问题,如果整个应用更新,基本开发完之后打包压缩72M(没有做任何优化,依赖的包比较多,node_modules压缩后也有20M),应该算是很大的了。如果第一次分发倒是没啥问题,但是每次都这样整个应用让运营手动更新,运营肯定不爽,必须得搞个自动更新方案出来。
在Github看了一遍文档,是有专门一节介绍自动更新的 传送门,Electron团队也很贴心,给了一系列的解决方案,只是感觉自己用不上那么高大上的技术(我只需要更简单一点就可以了),好(╯▔^▔)╯,决定自己撸一套出来。
首先利用electron-packager,打包出来的Electron应用(因为公司都是windows,只针对windows打包即可,但是打包过程也是相当耗时,时间大多耗在复制node_modules文件夹),很容易就发现electron-packager生成其实就是一个模板,每次内容改变就只是resources文件夹下面的内容改变而已,如果我们不需要复制node_modules的文件夹的内容,打包速度会提高很多(其实一般来说node_modules也不会经常改变),开始设想把node_modules 和 src(代码)分开打包,这样以后更新的话,只更新src目录也相当快。

ASAR文件

在看Electron文档时,看到了Electron内部是支持一种叫asar格式的文件,那asar到底是一种什么样的格式呢,Github的官方介绍是这样的:

Asar is a simple extensive archive format, it works like tar that concatenates all files together without compression, while having random access support.

可见这种文件格式只是简单把文件整理到一起,并没有压缩,可以当做它是一个文件夹来访问里面的文件,还有很重要的一点,你只能读取不能写入。
有了这种文件格式就提供了一个思路,把node_modules 和 src 分别打包成node_modules.asar 和 src.asar,当应用启动的时候直接require对应src.asar文件,在src.asar里面的代码再执行创建窗口和加载页面。
然后应用更新也只更新node_modules.asar 和 src.asar这两个文件,这样的话,整体的更新粒度是缩小了,当然你如果有更高的要求要做到那种更小粒度(针对代码某个文件级别的更新)可能得再思考一下了,但是在我当前的场景下是足够用了。

一点小问题

还有一点小问题,src.asar里面的代码怎么寻找到node_modules.asar里面的模块尼,换句话说就是怎么把node_modules.asar放到模块的查找路径上,这里贴一下我所使用的方法:

require('module').globalPaths.unshift(require('path').join(process.cwd(), 'resources/node_modules.asar'));

只要加到globalPaths上,且放到第一个(查找更快点)。

根据这样的更新方案,项目的目录结构也得做一点改变,在我的项目下主要三个文件夹:app,node_modules,src。node_modules 和 src就不用多说,那现在的app目录下的代码到底要干些啥尼

1. 先检查有没有文件需要更新,如果有弹出更新窗口(代码先请求一个manifest.json文件,里面有文件的MD5,用现有的文件做对比)
跳到2,没有就跳到3
2. 依次下载对应的文件,例如:src.asar.update, node_modules.asar.update,下载完成后,直接替换旧的文件
3. 最后require('src.asar').createApp()创建主界面,现在就能保证应用启动时都是最新的代码(只要下载没出问题)

结束

就这样一个简单的方案,运营也没在抱怨更新麻烦,皆大欢喜。当然面对真实用户场景,应该还有很多欠缺的地方,以后慢慢再学习改进(╯▔^▔)╯。


tain335
576 声望196 粉丝

Keep it simple.