背景
为什么要学习Electron
- 热爱编程:如开发小工具或者桌面端
 - 解决业务问题:B端(各式商家端、企业办公应用、开发者工具),快速上线桌面端
 - 技术广度:Web的超集,基于Javascript的环境能够让前端工程师快速上手,同时会接触到Node.js,甚至更底层的操作系统。能够让你将想象力从浏览器中释放出来,丰富自身的知识储备,提升技术视野
 流行的技术:Electron技术非常火,Github star超过7w
目标
正文
一、Electron介绍
Electron是什么
Electron是由Github开发的开源框架
- 
Electron组成
提供的能力
 Electron提供了统一的原生功能界面:窗口、托盘等
- 系统能力:系统通知等
 - 应用基础能力:软件更新、崩溃监控等
 

Node.js和基于不同平台的Native APIs加强的Chromium浏览器
【高效】Chromium : 为Electron提供了强大的UI能力,可以不考虑兼容性的情况下,利用强大的Web生态来开发界面
【能力】Node.js :让Electron有了底层的操作能力,比如文件的读写,甚至是集成C++等等操作,并可以使用大量开源的 npm 包来完成开发需求
【能力&体验】Native API :Native API让Electron有了跨平台和桌面端的原生能力,比如说它有统一的原生界面,窗口、托盘这些
Electron历史
Electron能力与Chromium和Node.js密不可分。
| 年份 | 事件 | 
|---|---|
| 1994 | 网景浏览器诞生,打破Mosaic的垄断地位,Mosaic + Godzilla + Killa = Mozilla(UA)浏览器野史 UserAgent列传 | 
| 1995 | 微软用IE+操作系统捆绑销售占据市场主导地位 | 
| 2002 | 网景浏览器以开源代码迎战,成立Mozilla非盈利组织,在网景2.0派生出火狐浏览器(安全、插件扩展、开发调试工具) | 
| 2008 | Chrome浏览器诞生,极致的简洁+10倍提速的V8引擎 | 
| 2009 | Node.js诞生。Ryan Dahl基于V8引擎将非阻塞IO和JS整合 | 
| 2011 | 英特尔工程师王文睿写了第一版node-webkit | 
| 2013 | Github的Atom项目组赵成开发了Atom-shell | 
| 2015 | Atom-shell更名为Electron | 
总结:网景公司在浏览器大战被IE击败后,开源代码成立了Mozilla派生了Firefox。Chrome基于Firefox开发并产生了V8引擎。Node基于V8引擎实现了非阻塞IO。NW基于Node和Chromium开发了桌面端。Atom在尝试NW失败后开始Atom-Shell开发,最后改名为Electron。
为什么开发桌面端
- 更快捷的入口
 - 离线可用
 - 调用系统能力(通知、硬件…)
 - 安全需求
 - 
什么时候使用Electron
1、快速试错
Electron的开发特别快
最小组成👇
2、特定领域
数据来源:https://www.electronjs.org/apps
3、同时开发web和桌面端(代码复用的挑战性)
谁在用 👇
如何判断应用是否使用Electron进行开发
应用程序>大象>Contents>Frameworks
二、Electron原理
Chromium架构
Electron:PC 端多端融合方案
Chromium本质上是一个桌面应用
Brower: 处理创建/管理tab页面,右键菜单,扩展程序等等
Renderer: 每个页面都是一个进程
进程间需要通过IPC通信,renderProcessHost和renderProcess都是用来处理IPC通信的模块
RenderView是基于Webkit排版渲染出来的
资源的请求需要通过ResourceDispatcher创建一个请求id,通过IPC通信,由Browser进程统一来处理请求资源
重点 Chromium是多进程架构(1 Browser + n Renderer)
- 进程间需要IPC通信
 - web关注到的只是很小的一部分(renderView)
 
Electron 架构
与Chromium相同点: 多进程
与Chromium差异:暴露了Native API模块、引入了Node.js
Node.js 和 Chromiums 整合
- 【难点】Node.js 事件循环基于 libuv,但 Chromium 基于 message bump
 - Chromium 集成到 Node.js: 用 libuv 实现 message bump (Node-Webkit 就是这么干的,缺点挺多。1、平台GUI差异,MacOS:NSRunLoop Linux: glib 2、边界处理不全 3、一小段定时器轮询 GUI 事件,CPU占用高)
 - Node.js 集成到 Chromium(Electron就是这么做的)
 
后来随着 libuv 引入 backend_fd 的概念,相当于是 libuv 轮询事件的文件描述符。通过轮训 backend_fd 可以知道 libuv 的新事件。所以 Electron 采取的做法就是将 Node.js 集成到 Chromium 中。
- Electron 新起一个安全线程去轮询 backend_fd
 - 当检测到一个新的 backend_fd,也就是一个新的 Node.js 事件之后,通过 PostTask 转发到 Chromium 的事件循环中
 
延伸资料
https://electronjs.org/blog/electron-internals-node-integration
https://www.youtube.com/watch?v=OPhb5GoV8Xk
https://github.com/electron/electron/blob/main/shell/common/node_bindings.cc
三、桌面端技术选型
Native(C++/C#/Objective-C)
- 高性能
 - 原生体验
 - 包体积小
 - 门槛高
 - 迭代速度慢
 
QT
- 基于C++
 - 跨平台(Mac、Windows、iOS、Android、Linux、嵌入式)
 - 高性能
 - 媲美原生的体验
 - 门槛高
 

Flutter
- 跨端(iOS、Android、Mac、Windows、Linux、Web)
 - PC 端在发展中(Mac > Linux、Windows)
 - 基建少
 
NW.js
- 跨平台(Mac、Windows、Linux),v0.14.7 支持 XP(XP 市场份额约为15%)
 - 迭代快,Web 技术构建
 - 源码加密、支持 Chrome 扩展
 - 不错的社区
 - 包体积大
 - 性能一般
 

Electron
- 跨平台(Mac、Windows、Linux、不支持 XP)
 - Web 技术构建
 - 活跃的社区
 - 大型应用案例
 - 包体积大
 - 性能一般
 

对比
| Electron | Native | QT | NW | |
|---|---|---|---|---|
| 性能 | ✓ | ✓✓✓ | ✓✓ | ✓ | 
| 安装包⼤大⼩小 | ✓ | ✓✓✓ | ✓ | ✓ | 
| 原⽣生体验 | ✓ | ✓✓✓ | ✓✓ | ✓ | 
| 跨平台 | ✓✓✓ | × | ✓✓✓ | ✓✓✓ | 
| 开发效率 | ✓✓✓ | ✓ | ✓✓ | ✓✓✓ | 
| ⼈人才储备 | ✓✓✓ | ✓✓ | ✓✓ | ✓✓✓ | 
| 社区 | ✓✓✓ | ✓✓ | ✓ | ✓✓ | 
| 适⽤用场景 | • 跨平台应⽤ • quick delivery 快速交付 • 前端技术栈  | 
• 专业应⽤ • best performance  | 
• 跨平台应⽤ • better performance  | 
• 跨平台(包括 XP)• quick delivery • 前端技术栈  | 
四、第一个 Electron 应用:简单的番茄钟
是什么
流程梳理


Electron 渲染进程讲解
引入模块,各进程直接在electron模块引入即可。例子:
const { app, BrowserWindow } = require(‘electron’) // 主进程引入app, BrowserWindow模块const { ipcRenderer } = require(‘electron’) // 渲染进程引入ipcRendereripcRenderer.invoke(channel, ...args).then(result => { handleResult }) // 渲染进程跟主进程发送请求
Electron 主进程模块讲解
// app,用于控制应用生命周期。本次只会用到 app.on(‘ready’,callback),用于在应用就绪后开始业务app.on(‘ready’,callback)// BrowserWindow,用于创建和控制窗口。let win = new BrowserWindow({width, height, ...}) // 创建窗口,并设置宽高win.loadURL(url)win.loadFile(path) // 加载⻚面// 页⾯Notification,创建 Notification。let notification = new Notification({title, body, actions:[{text, type}]})notification.show() // 展示通知ipcMain.handle(channel, handler) // 处理理渲染进程的 channel 请求,在 handler 中 return 返回结果
五、与Web开发不同
1、主进程与渲染进程
Electron 架构
主进程
- Electron 运行 package.json 的 main 脚本的进程被称为主进程
 - 每个应用只有一个主进程
 - 管理原生 GUI,典型的窗口(BrowserWindow、Tray、Dock、Menu)
 - 创建渲染进程
 - 控制应用生命周期(app)
 
渲染进程
- 展示 Web 页面的进程称为渲染进程
 - 通过 Node.js、Electron 提供的 API 可以跟系统底层打交道
 - 一个 Electron 应用可以有多个渲染进程
 
native模块
常用的是深色的,先学习常用的
官网
2、进程间通信
Electron 进程间通信的目的
- 通知事件
 - 数据传输
 - 共享数据
 
IPC 模块通信
Electron 提供了 IPC 通信模块,主进程的 ipcMain 和 渲染进程的 ipcRenderer
ipcMain、ipcRenderer 都是 EventEmitter 对象
三类通信:主进程往渲染进程、渲染进程往主进程、页面间(渲染进程之间)
3、原生能力

使用 Electron API 创建原生 GUI
- BrowserWindow
 - Tray
 - appMenu
 - dialogTouchBar
 - …
 
使用 Electron API 获得底层能力
- clipboard
 - screen
 - globalShortcut
 - desktopCapture
 - shell
 - powerMonitor
 - …
 
使用 Node.js 获得底层能力
- Electron 同时在主进程和渲染进程中对 Node.js 暴露了所有的接口fs 进行文件读写crypto 进行加解密
 - 通过 npm 安装即可引入社区上所有的 Node.js 库
 
使用 Node.js 调用原生模块
- node.js add-on
 - node-ffi
 
调用 OS 能力
- WinRT
 - Applescript
 - 
学习资料
官网:
https://www.electronjs.org/docs
Vue 开发模式:
https://github.com/SimulatedGREG/electron-vue
React 开发模式:
https://github.com/electron-react-boilerplate/electron-react-boilerplate
一些很棒的electron:
https://github.com/sindresorhus/awesome-electron
quick-start
https://electronjs.org/docs/tutorial/first-app
基本架构
https://electronjs.org/docs/tutorial/application-architecture#main-and-renderer-processes
写得很好的基础介绍
http://jlord.us/essential-electron/
掌握Electron模块。重点包括:app、BrowserWindow、ipcMain、Menu、Tray、ipcRenderer、Notification、clipboard 通过api-demos可以快速看到效果 https://github.com/electron/electron-api-demos
- 查看文档 https://electronjs.org/docs
 
