海神


Electron的一些坑

2016-04-15

用Electron如果只是做一个网站的外壳还是挺简单的,start kit很容易就可以跑起来。可是后来大把的时间我都花在了打包上面,真的是坑的不轻。

打包

官方并没有给一个打包工具,所有的工具都是第三方的。有一个比较靠谱的是Electron-Builder。这个工具配置好之后会自动打包OS X dmg和windows的installer,linux的包应该也可以,不过我没有试验。

配置可以参数这个项目ea-todo。这个项目来源于这个网站:http://electron.rocks。这个网站的作者写了一系列Electron的文章,真的是帮了入门者的大忙。可以完全copy一份代码,然后在上面改,需要修改的东西不会很多。有几点需要注意的:

  1. 安装最新的node和npm,我开始用的是比较老的版本,npm报错,升级到最新的就没问题了
  2. 用npm,不要用cnpm和pnpm,pnpm和cnpm都很快,但是安装完package运行报错,npm就没问题,所以我就记得只用npm了。尤其是当配置了命令行代理之后,就更没有必要用别的工具了。参考我上一篇文章:Shadowsocks转http代理
  3. electron、electron-builder和electron-packager最近都更新的很频繁,记得安装最新的版本,小问题可能很快就改掉了。
  4. electron-builder有几个版本打包OS X app的时候没有icon,后来的版本修复掉了。
  5. 在OS X上面打包windows安装文件的时候,会使用electron-prebuilt来生成windows平台的native module,项目中有的package会导致打包的windows程序不能运行,如果出现这种情况就从这个package着手来查问题。
  6. 项目根目录下面的package.json里面的iconUrl是一个网络的url,而不是本地的地址,它的实际用处是windows安装卸载程序里面程序的图标。
  7. 在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!然后我发现作者居然是中国人,他的公司就在上海,哈!

其他

  1. 网页中报jQuery not found错误,在就BrowserWindow的初始化中加入一个参数:

     mainWindow = new BrowserWindow({
       name: "vipmro",
       width: 1280,
       height: 1000,
       toolbar: false,
       title: '工品汇',
       webPreferences: {
         nodeIntegration: false,
       }
     });
    
  2. 窗口标题,参考上面的title参数
  3. electron默认会用网页的title来做窗口的title,可以阻止这种行为:

     mainWindow.on('page-title-updated', function(event) {
       event.preventDefault();
     });
    
  4. 最大化窗口

     mainWindow.maximize(); 
    
  5. 防止新开窗口:

     mainWindow.webContents.on('new-window', function(event, url, frameName, disposition, options) {
       event.preventDefault();
       mainWindow.loadURL(url);
     });
    
  6. 我发现electron程序跟浏览器行为一样,会记住用户的登录,什么工作也不需要做。但是公司的网站不行,应该是本身网站的程序有问题。
  7. 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的能力。

参考


blog comments powered by Disqus