一、基础篇
1.1 介绍Electron
Electron是什么?
- Electron 是由 Github 开发的开源框架。
- 它允许开发者使用 Web 技术构建跨平台桌面应用。
Electron的核心组成
Node.js让Electron有了底层的操作能力,如文件的读写、集成C++等,还可以使用大量的NPM包,完成项目需求。
内置的Native API解决了跨平台的问题。
首先,提供了统一的原生界面。比如像窗口、托盘;
其次,是系统能力,如:Notification;
最后,应用的基础能力,如:软件更新、崩溃监控等。
Electron历史
什么时候用
Electron谁在用?
判断应用是否为Electron创建
学习Electron好处
1、造工具-提高效率
简单反向代理工具,将项目域名代理打包给其他人使用
2、提升技术广度
从web端延伸到桌面端,成为符合型人才
Electron最小组成
index.html 页面
package.json 包体描述,里面有应用名版本号
main.js 管理整个应用的脚本
一个最小的Electron组成
package.json
index.js
启动一个1000*680的窗口
index.html
加载页面,展示hello
启动后
1.2 Electron的架构和原理
Electron多进程架构
Chromiun架构
Chromium本质是Chrome的开源版,也是一个浏览器。
浏览器也是一个桌面应用,需要
- 创建窗口
- 右键菜单
- 管理浏览器Tab页面
- 扩展程序
处理以上事项的进程:主进程——Browser
IPC跨进程通信
Chromium架构
Electron中分为主进程和渲染进程
Electron跟 Chromium不一样的2个点:
- 在各个进程中暴露了一些Native API
- 引入了Node.js
所以我们可以在Electron中使用Chromuim和Node。
如:
- 通过Node管理窗口,在页面中使用Node库
这是很不容易的:因为在主线程中在同一时间下只能运行一个事件循环。
但是Node.js的事件循环是基于libuv。
Chromium是基于messagebump,这就是Electron原理的重点:如何整合事件循环。
Node.js和Chromium整合
难点:Node.js 事件循环基于 libuv,但 Chromium 基于 message pump
- Chromium 集成到 Node.js:用 libuv 实现 message pump(nw)
- Node.js 集成到 Chromium
-
Electron具体整合事件循环的2个思路:
将Chromium的messagebump用libuv实现一次,如NW就是这么做的。Electron也试过,在渲染进程里面实现比较简单,但是在主进程里面,因为各个系统的GUI实现都不一样,如:Mac是NSRunLoop,Linux是glib,工程量很浩大,但是最为致命的是很多边界情况都处理的不好。
-
后来作者又尝试了一种方法,就是用一个小间隔定时器去轮询GUI事件。
但是会发现GUI响应的特别慢CPU也很高,后来随着libuv引入了backend fd的概念,相当于libuv轮询事件的文件描述符,可以通过轮询backend fd,可以知道ibuv的一个新事件,所以Electron的做法:将Node集成到Chromium。
Electron贡献者之一Shelly在JSheroes上的PPT
本质的原理
Electron起了一个新的安全线程去轮询backend_fd,当我们的Node.js有了一个新的事件之后通过PostTask转发到我们的Chromium的事件循环当中,这样就完成了Electron的事件融合。
延伸资料
- https://electronjs.org/blog/electron-internals-node-integration
- https://www.youtube.com/watch?v=OPhb5GoV8Xk
- https://github.com/electron/electron/blob/master/shell/common/node_bindings.cc
Chromium和Node.js是怎么一起工作的?
https://github.com/electron/electron/blob/master/shell/common/node_bindings.cc
首先,在 PrepareEmbedThread 里面启动一个独立的线程。
然后使用 EmbedThreadRunner 轮训具体的事件,当有了一个新的事件之后,唤起主线程
主线程会通过PostTask转发到Chromium的事件循环
这样,Chromium和Node.js两者就可以有机地结合到一起。
桌面端技术选型:如何选择合适的桌面端技术?
为什么我们要开发桌面端?
- 更快捷的入口:让自己的产品占据用户的桌面
- 离线可用:office在飞机上可用
- 调用系统能力(通知、硬件):通知用户、结合打印机完成自己的业务等
- 安全需求:金融或企业级应用领域,更偏向做客户端
- ...其他的原因根据业务具体分析
开发桌面应用有哪些技术?
1、Native(C++/C#/Objective-C)
- 高性能
- 原生体验
- 包体积小
- 门槛高(缺陷)
- 迭代速度慢(缺陷)
2、QT 基于C++的跨平台开发框架
- 基于C++
- 跨平台(Mac、Windows、i0s、Android、Linux、嵌入式
- 高性能
- 媲美原生的体验
- 门槛高(缺陷)
- 迭代速度一般(缺陷)
用QT写的应用
- DropBox
- WPS
QT有自己的QML,类似CSS,有不错的社区和生态,所以迭代速度会比Native快一些,但整体门槛还是比较高,而且人才在市场上比较稀缺。
3、Flutter——移动端非常火
- 跨端(i0s、Android、Mac、Windows、Linux、Web)
- PC端在发展中(Mac>Linux、Windows)(缺陷)
- 基建少(缺陷)
Flutter整体目标:跨平台
缺点:太新了,在Linux和Windows上是基本不可用的状态,基建也特别少,目前来说不适合做业务。
推荐:保持关注。
4、NW.js——Web技术的代表
- 跨平台(Mac、Windows、Linux),v0.14.7支持XP(XP 市场份额约为15%
- 迭代快,Web 技术构建
- 源码加密、支持 Chrome 扩展
- 不错的社区
- 包体积大(缺陷)
- 性能一般(缺陷)
代表作:微信开发工具(用NW.js的原因是起步比较早,还没有用Electron)
5、Electron
- 跨平台(Mac、Windows、Linux、不支持 XP)
- Web 技术构建
- 活跃的社区:github 2024年2月10日 110.6k star
- 大型应用案例:Atom、slack、VS Code、WhatsApp、WordPress、大象
- 包体积大(缺陷)——Electron将整个Chromium都打包进去了,包体积会达到50M。
- 性能一般(缺陷)——性能相比Native和QT都会差一些
代表作:
6、更多
- Google Carlo——复用装好的Chrome浏览器运行,目前还不够成熟。
- WPF——如果是.NET高手,而且只做Windows平台,是一个非常不错的选择
- Chromium Embedded Framework (CEF)——可以让你的桌面应用去做集成,让你部分的UI用Web来实现
- PWA——本质上不是用来做PC的,但是可以帮助很多人不做PC,如替代那些只想拥有桌面入口、通知能力、离线可用桌面应用
各个框架的对比
Electron开发准备:环境搭建及前期准备
1. 选择一个合适的编辑器
- Vs Code (推荐)
- WebStorm
- Atom
- VIM
- ...
2. NVM安装
- Mac/Linux
curl -0- https://raw.githubusercontent.com/nym-sh/nvm/v0.35.2install.sh l bash
- Windows
https://github.com/coreybutler/nvm-windows/releases
3. Node.js / NPM安装
- 安装 Node.js
nvm install 12.14.0
- 切换 Node.js 版本
nvm use 12.14.0
- 验证
npm -v
- 验证
node -v
验证安装效果
Electron安装
- npm install electron --save-dev
- npm install --arch=ia32 --platform=win32 electron
在Windows上打包都应该基于32位打包,这样32位和64位的都可以用,只需要维护一套即可。 - 验证安装成功:
- npx electron -v
- ./node_modules/.bin/electron -v
验证 Electron 是否安装成功
如果npm是大于5.2的话,可以直接使用npx命令
npx是为了让项目内部安装的模块调用更方便,而产生的一个新命令。
如果npm低于5.2的话,只能通过 ./node_modules/.bin/electron -v 来做验证。
操作截图
启动后
./node_modules/.bin/electron
加速技巧——设置Electron的镜像源
ELECTRON MIRROR=https://cdn.npm.taobao.org/dist/electron/ npm install electron --save-dev
第一个Electron应用:开发一个简单版的番茄钟(上)
- 番茄工作法是一种时间管理法;
- 使用定时器分割出一个一般为25分钟工作时间和5分钟休息时间;
目标效果
简单版番茄钟-流程梳理
分析主进程和渲染进程都做什么、用什么模块
Electron 渲染进程讲解
-
引入模块,各进程直接在 electron 模块引入即可。例子:
-
const {app, BrowserWindow } = require('electron') //主进程引入app,BrowserWindow模块
-
const {ipcRender} = require('electron') //渲染进程引入ipcRenderer
-
ipcRenderer.invoke(channel, ...args).then(result => {handleResult}) // 渲染进程跟主进程发送请求
Electron 主进程模块讲解
- app,用于控制应用生命周期。本次只会用到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 返回效果。
第一个Electron应用:开发一个简单版的番茄钟(下)
准备好开发环境:
index.html
node_modules
package-lock.json
package.json
为了整个交互的流畅度,引入timer.js
https://github.com/husa/timer.js
npm install timer.js
renderer.js添加
var myTimer = new Timer(options);
关键点
ontick 秒钟跳动的时候去渲染界面
onend 时钟结束之后弹一个通知
与Web开发对比
针对不同之处做Electron开发,扎实了解并做一个番茄钟应用
二、项目实战篇
从0实现一个桌面控制软件(结合Electron、Node.js、WebRTC技术)
三、工程篇
完善实战篇桌面控制项目
讲述真实项目中做Electron应用的流程、工程化建设的关键点和坑