Electron的一些坑
2016-04-15用Electron如果只是做一个网站的外壳还是挺简单的,start kit很容易就可以跑起来。可是后来大把的时间我都花在了打包上面,真的是坑的不轻。
打包
官方并没有给一个打包工具,所有的工具都是第三方的。有一个比较靠谱的是Electron-Builder。这个工具配置好之后会自动打包OS X dmg和windows的installer,linux的包应该也可以,不过我没有试验。
配置可以参数这个项目ea-todo。这个项目来源于这个网站:http://electron.rocks。这个网站的作者写了一系列Electron的文章,真的是帮了入门者的大忙。可以完全copy一份代码,然后在上面改,需要修改的东西不会很多。有几点需要注意的:
- 安装最新的node和npm,我开始用的是比较老的版本,npm报错,升级到最新的就没问题了
- 用npm,不要用cnpm和pnpm,pnpm和cnpm都很快,但是安装完package运行报错,npm就没问题,所以我就记得只用npm了。尤其是当配置了命令行代理之后,就更没有必要用别的工具了。参考我上一篇文章:Shadowsocks转http代理。
- electron、electron-builder和electron-packager最近都更新的很频繁,记得安装最新的版本,小问题可能很快就改掉了。
- electron-builder有几个版本打包OS X app的时候没有icon,后来的版本修复掉了。
- 在OS X上面打包windows安装文件的时候,会使用electron-prebuilt来生成windows平台的native module,项目中有的package会导致打包的windows程序不能运行,如果出现这种情况就从这个package着手来查问题。
- 项目根目录下面的package.json里面的
iconUrl
是一个网络的url,而不是本地的地址,它的实际用处是windows安装卸载程序
里面程序的图标。 - 在app/package.json里面可以加入一个
productName
属性,这样所有生成的可执行文件和安装包的名字都会从productName
取,而不是name
。这个名字中可以加空格,但是如果取中文,打包windows安装包的时候就会报错。这个错误的根源在wine,基本是无法解决的。但是我从electron-packager
着手进行了修复。可以参考我的修改版electron-packager。其实只改了一个文件:win32.js
,修复的原理很简单,就是先用name
来打包,然后把文件重命名为productName
。不过还有一个问题没法解决,就是OS X打包dmg的时候background.png
没有生效。
自动更新
在ea-todo的代码中已经有了自动更新的例子,完全可以照搬。electron-builder在打包的同时也会生成更新包。你还需要建立一个检测更新的服务端程序,ea-todo的作者同样给了demo:ea-todo-server。你可以部署到heroku上面。OS X和windows的更新机制不同。
- OS X使用
manifest.json
文件和dmg文件 - windows使用
RELEASES
文件和.nupkg文件
每次更新的工作就是把正确的4个文件放到正确的位置就好了,electron程序启动的时候会自动检测更新,下载更新包。下次启动就会启动新版本了。
另外OS X上需要建立一个证书做签名,具体参考这篇文章:http://electron.rocks/publishing-for-os-x/。
菜单
可以找electron官方的例子,注意OS X和windows的菜单会是不同的,快捷键也不同。
自动启动
有一个package叫auto-launch
。这个package很方便,只有3个方法,isEnable()、enable()和disable()。帮你包办了OS X和windows上面的自动启动。
不过有一个问题,isEnable方法如果写在菜单的点击方法里面,在OS X上面运行的时候会永远返回false,windows上面则没有问题。原因是它在OS X上面会用applescript
这个package来运行apple script来获取所有的启动项,这个package估计是在子进程运行有问题,获取的启动项为空。
我把auto-launch改了一下:https://github.com/phaibin/node-auto-launch,换了一个运行apple script的package,然后就没问题了。
保存数据
有一个很方便的package:electron-json-storage
,来保存一些设置。只需要用 set key, get key,这种形式来使用就好了。
安全
Electron是一项Web技术,要保护代码是不可能的,在Electron和Atom的社区都有讨论,他们也没有计划做任何安全性的工作。
不过我后来搜索到这么一篇文章:https://wiredcraft.com/blog/high-security-electron-js-application/。看到这篇文章有点大开眼界。这篇文章讲了他的公司为了给缅甸大选做投票系统,而做的选型考虑。是用C++/C#这样的原生代码,但是Electron这样的Web技术。最后他们的选择居然是Electron。不过他们为了安全性,把一部分数据保存的工作移到了Go开发的底层模块中,然后用js来调用Go的功能。里面讲到Go官方并不支持他们的数据库SQLCipher,于是他就自己写了一个Go的适配器!真NB!然后我发现作者居然是中国人,他的公司就在上海,哈!
其他
网页中报jQuery not found错误,在就BrowserWindow的初始化中加入一个参数:
mainWindow = new BrowserWindow({ name: "vipmro", width: 1280, height: 1000, toolbar: false, title: '工品汇', webPreferences: { nodeIntegration: false, } });
- 窗口标题,参考上面的title参数
electron默认会用网页的title来做窗口的title,可以阻止这种行为:
mainWindow.on('page-title-updated', function(event) { event.preventDefault(); });
最大化窗口
mainWindow.maximize();
防止新开窗口:
mainWindow.webContents.on('new-window', function(event, url, frameName, disposition, options) { event.preventDefault(); mainWindow.loadURL(url); });
- 我发现electron程序跟浏览器行为一样,会记住用户的登录,什么工作也不需要做。但是公司的网站不行,应该是本身网站的程序有问题。
- Electron的windows版本依赖.NetFramework,而且不同版本的Electron依赖的.NetFramework版本也不同,目前最新版本的Electron版本是v0.37.5,需要.NetFramework 4.5.1。很诡异的是VS Code使用的Electron版本是0.35.6,居然不需要装.NetFramework 4.0就可以运行。
6月16日更新:
我发现其实对.NetFramework的依赖来源于electron-builder生成的安装文件,如果直接把可执行文件复制到windows上面,是不需要.NetFramework就可以打开的。而对.NetFramework的依赖根源来源于electron-builder依赖的squirrel.windows。
最近Electron升级到1.0了,而electron-builder也更新了很多版本(依然非常活跃,经常更新版本)。在electron-builder的v5.4.0版本中,加入了对NSIS的支持,他们的commit中用feat(壮举)来形容。使用NSIS有很多优点,具体可以参考这个issue:https://github.com/electron-userland/electron-builder/issues/472。让用户先安装.NetFramework毕竟不是很友好,那转为用NSIS之后是不是就不需要了呢?我也是抱着很兴奋的心情试了一下,居然真的不需要了!使用NSIS的方法是,在package.json中修改:
"build": {
"win": {
"target": "nsis"
}
},
不过官方也说还远没有到ideal的程度。比如,这样就失去了Auto update的能力。
参考
- Electron中文文档
- ELECTRON ROCKS!,Electron爱好者建的小站,文章都很棒
- Electron SuperKit
- Awesome Electron,Electron的一些精彩应用
- Electron Fundamentals,Electron的一篇高级教程