技术博客

Electron 从入门到部署


一、Electron 是什么?

基于chrome 内核 + nodeJS 服务 + Html5 展现来开发的桌面软件,可以轻易的跨平台。例如Visual Studio Code、Slack 、Atom 等等桌面端软件都是使用Electron 开发的。

二、技术选型

1.框架 Electron VS NW.js

Electron 前身是atomshell,NW.js 前身是Node-Webkit。区别:

1) 程序入口
NW.js 以网页为入口,Electron 以js 为入口,Electron 更加灵活。例如可以开发纯菜单应用。

2) 编译系统
Electron 使用 libchromiumcontent,比NW.js 编译应用的时候,省去编译整个 Chromium (编译Chromium 非常费时)。

3) Node 集成
NW.js 的 Node 集成需要给 Chromium 打补丁才能工作。Electron 通过集成 libuv loop 和 平台的 message loop 避免给 Chromium 打补丁。

4) Multi-context
NW.js 创造了 Node context 和 web context 的概念,而 Electron 没有引入新的 context,而是直接使用 Node 的 Multi-context 特性(这一特性是 Atom 开发者赞助 Node 添加的)。

5) Electron 不支持XP

官方英文传送门

2.模块选型 electron-packager OR electron-builder

builder 是在 packager 基础上的整合版,提供开发到部署一整套,生产各个平台可以执行文件、安装程序、软件签名、自动更新。

packager 想要打包成 windows 端安装版,需要安装模块electron-installer-windows 来进行打包,没有builder 在package.json 中配置参数更简单方便。

三、APP架构

1.创建浏览器窗口

package.json 中配置"main"参数APP启动 js,这里为 main.js。

main.js (Main Process)创建主窗口,用来操作窗口菜单、大小、隐藏显示等等。

new BrowserWindow({     icon           : __dirname + "/resources/icon_256.png",     title          : "主窗口",     fullscreenable : true,     webPreferences : {         nodeIntegration               : false,         plugins                       : true,         preload                       : __dirname + '/preload.js',         allowDisplayingInsecureContent: true,         scrollBounce                  : false     } });

renderer.js (Renderer Process)会注入到页面dom 中,可以与Main Process 交互,操作页面的显示。

2.数据通讯

2.1 事件型
2.1.1 同窗口
renderer.js 中可以主动调用 ipcRenderer 发送消息给 main.js,main.js 的 ipcMain 会送消息给 renderer.js。

//发送消息 ipcRenderer.send('events-hello', 'Hi Steve Jobs') //接收消息 ipcMain.on('events-hello', function (event, data) {   //回送消息   console.log(data);   event.sender.send('events-reply', 'Hello Man') }) //接收回送消息 ipcRenderer.on('events-reply', function (event, data) {   console.log(data); })

2.1.2 跨窗口
需要先找到对应窗口对象,例如发送消息到下载窗口,下载窗口对象为downloadWindow

//发送消息 downloadWindow.webContents.send('download-file-update', file); //接收消息 ipcRenderer.on('download-file-update', function (event, data) {   console.log(data); })

也可以发送自己当前窗口的 Renderer Process

2.2 非事件型
main.js 中会默认声明一个变量 global,调用 remote.getGlobal 就可以获取

//main.js global.name = 'worktile' //renderer.js remote.getGlobal('name')

3 存储

简易用户的一些 String Number JSON 数据,可使用 electron-json-storage、electron-config。(重新安装APP这里的数据不会丢失)
大量数据,可使用 nedb (JavaScript Database)。
这些都是官方推荐的。

四、打包

1.文件过滤
File Patterns

"build": {   "files": []  //election有默认配置,注意看文档 }

2.打包
Terminal 执行命令 build:mac

"scripts": {   "start": "electron ./",  //启动测试   "build:mac": "build --mac",  //打包Mac 端app   "build:win": "build --win --ia32"  //打包Windows 端exe }

3.桌面快捷方式
let handleSquirrelEvent = function () {     if (process.platform != 'win32') {         return false;     }    function executeSquirrelCommand(args, done) {         let updateDotExe = path.resolve(path.dirname(process.execPath), '..', 'update.exe');         let child = cp.spawn(updateDotExe, args, {detached: true});         child.on('close', function (code) {             done();         });     }    function install(done) {         let target = path.basename(process.execPath);         executeSquirrelCommand(["--createShortcut", target], done);     }    function uninstall(done) {         let target = path.basename(process.execPath);         executeSquirrelCommand(["--removeShortcut", target], done);     }    let squirrelEvent = process.argv[1];     switch (squirrelEvent) {         case '--squirrel-install':             install(app.quit);             return true;         case '--squirrel-updated':             install(app.quit);             return true;         case '--squirrel-obsolete':             app.quit();             return true;         case '--squirrel-uninstall':             uninstall(app.quit);             return true;     }     return false; }; if (handleSquirrelEvent()) {     return; }

4.签名

(1) 安装开发者证书
(2) 安装企业证书
(3) package.json添加build.appId为App的唯一标示

"build": {    "appId": "your.id",  //App的唯一标示    "mac": {             "category": "your.app.category.type"   //App分类    } }

执行build --mac 打包会自动通过appId调用证书打包,就有打包出的app 就有签名了。

Thx!

最后,这里讲一个八卦,Electron 与NW.js 两个框架都是由 zcbenz 起步,地地道道的中国人,他在 Intel 做的 NW.js,火了以后,跳槽去了 GitHub 做了 Electron。传送门,可以看看他的自述。