显著变化

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