背景

为什么要学习Electron

  • 热爱编程:如开发小工具或者桌面端
  • 解决业务问题:B端(各式商家端、企业办公应用、开发者工具),快速上线桌面端
  • 技术广度:Web的超集,基于Javascript的环境能够让前端工程师快速上手,同时会接触到Node.js,甚至更底层的操作系统。能够让你将想象力从浏览器中释放出来,丰富自身的知识储备,提升技术视野
  • 流行的技术:Electron技术非常火,Github star超过7w

    目标

    初步认识Electron基础知识、快速上手入门

    正文

    一、Electron介绍

    Electron是什么

  • Electron是由Github开发的开源框架

  • 它允许开发者使用Web技术构建跨平台桌面应用

    Electron组成

    提供的能力

  • Electron提供了统一的原生功能界面:窗口、托盘等

  • 系统能力:系统通知等
  • 应用基础能力:软件更新、崩溃监控等

image.png
Node.js和基于不同平台的Native APIs加强的Chromium浏览器
【高效】Chromium : 为Electron提供了强大的UI能力,可以不考虑兼容性的情况下,利用强大的Web生态来开发界面
【能力】Node.js :让Electron有了底层的操作能力,比如文件的读写,甚至是集成C++等等操作,并可以使用大量开源的 npm 包来完成开发需求
【能力&体验】Native API :Native API让Electron有了跨平台和桌面端的原生能力,比如说它有统一的原生界面,窗口、托盘这些

Electron历史

Electron能力与Chromium和Node.js密不可分。
image.png

年份 事件
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的开发特别快
    最小组成👇
    image.png
    2、特定领域
    image.png
    数据来源:https://www.electronjs.org/apps
    3、同时开发web和桌面端(代码复用的挑战性)
    image.png
    谁在用 👇
    image.png
    如何判断应用是否使用Electron进行开发
    应用程序>大象>Contents>Frameworks
    image.png

    二、Electron原理

    Chromium架构
    Electron:PC 端多端融合方案
    Chromium本质上是一个桌面应用
    Brower: 处理创建/管理tab页面,右键菜单,扩展程序等等
    Renderer: 每个页面都是一个进程
    进程间需要通过IPC通信,renderProcessHost和renderProcess都是用来处理IPC通信的模块
    RenderView是基于Webkit排版渲染出来的
    资源的请求需要通过ResourceDispatcher创建一个请求id,通过IPC通信,由Browser进程统一来处理请求资源
    image.png
    重点

  • Chromium是多进程架构(1 Browser + n Renderer)

  • 进程间需要IPC通信
  • web关注到的只是很小的一部分(renderView)

Electron 架构
image.png
与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 中。
image.png

  • 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、嵌入式)
  • 高性能
  • 媲美原生的体验
  • 门槛高

image.png

Flutter

  • 跨端(iOS、Android、Mac、Windows、Linux、Web)
  • PC 端在发展中(Mac > Linux、Windows)
  • 基建少

NW.js

  • 跨平台(Mac、Windows、Linux),v0.14.7 支持 XP(XP 市场份额约为15%)
  • 迭代快,Web 技术构建
  • 源码加密、支持 Chrome 扩展
  • 不错的社区
  • 包体积大
  • 性能一般

image.png
Electron

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

image.png
对比

Electron Native QT NW
性能 ✓✓✓ ✓✓
安装包⼤大⼩小 ✓✓✓
原⽣生体验 ✓✓✓ ✓✓
跨平台 ✓✓✓ × ✓✓✓ ✓✓✓
开发效率 ✓✓✓ ✓✓ ✓✓✓
⼈人才储备 ✓✓✓ ✓✓ ✓✓ ✓✓✓
社区 ✓✓✓ ✓✓ ✓✓
适⽤用场景 • 跨平台应⽤
• quick delivery
快速交付
• 前端技术栈
• 专业应⽤
• best performance
• 跨平台应⽤
• better performance
• 跨平台(包括 XP)• quick delivery
• 前端技术栈

四、第一个 Electron 应用:简单的番茄钟

是什么
image.png
流程梳理
image.png
image.png
image.png
Electron 渲染进程讲解
引入模块,各进程直接在electron模块引入即可。例子:

  1. const { app, BrowserWindow } = require(‘electron’) // 主进程引入app, BrowserWindow模块
  2. const { ipcRenderer } = require(‘electron’) // 渲染进程引入ipcRenderer
  3. ipcRenderer.invoke(channel, ...args).then(result => { handleResult }) // 渲染进程跟主进程发送请求


Electron 主进程模块讲解

  1. // app,用于控制应用生命周期。本次只会用到 app.on(‘ready’,callback),用于在应用就绪后开始业务
  2. app.on(‘ready’,callback)
  3. // BrowserWindow,用于创建和控制窗口。
  4. let win = new BrowserWindow({width, height, ...}) // 创建窗口,并设置宽高
  5. win.loadURL(url)
  6. win.loadFile(path) // 加载⻚面
  7. // 页⾯Notification,创建 Notification。
  8. let notification = new Notification({title, body, actions:[{text, type}]})
  9. notification.show() // 展示通知
  10. ipcMain.handle(channel, handler) // 处理理渲染进程的 channel 请求,在 handler 中 return 返回结果

五、与Web开发不同

1、主进程与渲染进程

Electron 架构
image.png
主进程

  • Electron 运行 package.json 的 main 脚本的进程被称为主进程
  • 每个应用只有一个主进程
  • 管理原生 GUI,典型的窗口(BrowserWindow、Tray、Dock、Menu)
  • 创建渲染进程
  • 控制应用生命周期(app)

渲染进程

  • 展示 Web 页面的进程称为渲染进程
  • 通过 Node.js、Electron 提供的 API 可以跟系统底层打交道
  • 一个 Electron 应用可以有多个渲染进程

native模块
常用的是深色的,先学习常用的
官网
image.png

2、进程间通信

Electron 进程间通信的目的

  • 通知事件
  • 数据传输
  • 共享数据

IPC 模块通信
Electron 提供了 IPC 通信模块,主进程的 ipcMain 和 渲染进程的 ipcRenderer
ipcMain、ipcRenderer 都是 EventEmitter 对象
三类通信:主进程往渲染进程、渲染进程往主进程、页面间(渲染进程之间)

3、原生能力

image.png
使用 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 能力