显著变化

1. Electron版本发布周期变化

从 Electron 15 开始,新的 major 版本发布周期会从 12 周改为 8 周。
New Electron Release Cadence
此外,到 2022 年 5 月前,Electron 会由原来支持最新 3 个版本改为支持最新 4 个版本。
Electron Versioning

2. 技术栈变化

Electron 16 使用以下版本:

  • Chromium 96
  • Node.js 16.9.1
  • V8 9.6

V8 9.5-9.6 新特性

亮点特性

1. 支持 WebHID API

WebHID API 是浏览器提供的支持人机界面设备的 API,通过这个 API 你就能连接如 Switch 的 Joy-Con 控制器之类的硬件设备。
PR 链接

2. app.requestSingleInstanceLock 支持传参以在两个实例间共享数据

回顾一下,app.requestSingleInstanceLock() 方法的返回值表示你的应用程序实例是否成功取得了锁。如果它取得锁失败并退出,你可以假设另一个应用实例已经存在且取得了锁并仍旧在运行。一般用于确保当前应用只有一个实例。
但有些场景启动应用想带上参数,而原来的 app.requestSingleInstanceLock() 不支持传参,当第二个实例启动后因为锁的存在而被退出,但命令带的参数并没有被传给第一个实例去执行。
这次 Electron 16 支持了可以往 app.requestSingleInstanceLock() 传一个 JSON 对象作为参数,当第二个实例启动后,第二个实例的参数会被传给第一个实例,在第一个实例中可以通过监听 ‘second-instance’ 事件 来获取传来的参数:

  1. const { app } = require('electron')
  2. let myWindow = null
  3. const additionalData = { myKey: 'myValue' }
  4. const gotTheLock = app.requestSingleInstanceLock(additionalData)
  5. if (!gotTheLock) {
  6. app.quit()
  7. } else {
  8. app.on('second-instance', (event, commandLine, workingDirectory, additionalData) => {
  9. // commandLine 是第二个实例的命令行参数的数组, workingDirectory 是这个实例当前工作目录,additionalData 是第二个实例的参数
  10. console.log(additionalData);
  11. // 当运行第二个实例时,将会聚焦到myWindow这个窗口
  12. if (myWindow) {
  13. if (myWindow.isMinimized()) myWindow.restore()
  14. myWindow.focus()
  15. }
  16. })
  17. // 创建 myWindow, 加载应用的其余部分, etc...
  18. app.whenReady().then(() => {
  19. myWindow = createWindow()
  20. })
  21. }

PR 链接
此外,我看已经有 PR 在讨论加一个事件提供给第二个实例,用以第一个实例传参给第二个实例。

3. setPermissionRequestHandler() 支持传 securityOrigin 给 media请求

ses.setPermissionRequestHandler(handler) 是主进程的 session 模块下处理权限请求的方法。之前遇到 media 类型的权限请求,如摄像头、麦克风、扬声器设备的权限请求时,handler 并没有传请求的 security_origin
但在配套的API ses.setPermissionCheckHandler(handler)handler 里,参数 details 又提供了 securityOrigin,所以为了保持一致减少歧义,Electron 16 也给 ses.setPermissionRequestHandler(handler) 加上了 securityOrigin

  1. const { session } = require('electron')
  2. session.fromPartition('some-partition').setPermissionRequestHandler((webContents, permission, callback, details) => {
  3. if (webContents.getURL() === 'some-host' && permission === 'notifications' && details.securityOrigin === undefined) {
  4. return callback(false) // 拒绝请求
  5. }
  6. callback(true)
  7. })

至于这俩 API 的不同,参考这个 issue

  • setPermissionRequestHandler:处理可以被异步响应的权限请求。
  • setPermissionCheckHandler:处理必须被同步响应的权限检查。

PR 链接

4. 新增 API - commandLine.removeSwitch

喜大普奔!Electron 官方终于支持关闭 Chromium 命令行开关了!相信很多应用都想关闭线上包的命令行开关,来防止用户执行一些开发者不想让用户执行的命令。现在可以通过设置这一属性,来关闭 Chromium 命令行开关了:

  1. app.commandLine.appendSwitch('foobar3', 'test');
  2. console.log(app.commandLine.hasSwitch('foobar3')); // true
  3. app.commandLine.removeSwitch('foobar3');
  4. console.log(app.commandLine.hasSwitch('foobar3')); // false

PR 链接

更多特性,可看 Electron 16 发布版本通知

突破性变化

1. config.gypi 不再继承运行时 process.config

config.gypi 文件将继承自 $nodedir/include/node/config.gypi,不再从运行时的 process.config 对象继承,具体原因参考 issue
对于使用 node-gyp 的应用,需要考虑使用 --force-process-config ,可以强制切回到原来的表现,即强制使用运行时 process.config 对象生成 config.gypi 文件。
具体有三种使用 node-gyp 构建的情况(更多细节请看 PR):

  1. 为官方 Node.js 二进制文件构建带有官方头文件的模块
    1. 使用 $nodedir/include/node/config.gypi 或者 process.config 都可以
  2. 为第三方 Node.js 二进制文件构建带有官方头文件的模块
    1. 使用 $nodedir/include/node/config.gypi 可能会有问题,因为一些第三方 Node.js 库使用了与官方头文件不同的构建配置。
  3. 为自定义 Node.js 二进制文件或 Node.js 嵌入式应用程序构建带有自定义头文件的模块
    1. 必须使用 $nodedir/include/node/config.gypi 而非 process.config ,因为只有前者包含构建目标的正确构建配置。

PR 链接

2. Linux 上 crashReporter 的实现转移到了 Crashpad

Linux 上 crashReporter API 的基础实现已经从 Breakpad 转移到了 Crashpad,与 Windows 和 Mac 保持一致。现在子进程会被自动监视,所以也不再需要在 Node 子进程调用 process.crashReporter.start (也不建议,因为这将启动 Crashpad 记录器的第二个实例)。

更多未来的突破性变化,可看 Planned Breaking Changes

版本支持

结束支持 Electron 12.x.y。接下来的版本支持时间表:

E15 (21年9月) E16 (21年11月) E17 (22年2月) E18 (22年3月) E19 (22年5月)
15.x.y 16.x.y 17.x.y 18.x.y 19.x.y
14.x.y 15.x.y 16.x.y 17.x.y 18.x.y
13.x.y 14.x.y 15.x.y 16.x.y 17.x.y
12.x.y 13.x.y 14.x.y 15.x.y

原文链接

Electron 16.0.0