跳转到主内容

关于 "runAsNode" CVEs 的声明

· 阅读时间:约 6 分钟

今天早些时候,Electron 团队被告知,最近有几个公开的 CVEs 针对几个著名的 Electron 应用程序进行了提交。 这些 CVE 与 Electron 的两个 fuses(保险丝) - runAsNodeenableNodeCliInspectArguments - 相关,并错误地声称,如果这些组件没有被积极禁用,远程攻击者能够通过这些组件执行任意代码。

我们认为这些 CVE 并非出于善意提交。 首先,这个声明是不正确的 - 配置并不允许远程代码执行。 其次,尽管拥有漏洞赏金计划,但在这些 CVE 中被点名的公司并没有收到通知。 最后,虽然我们确实相信禁用相关组件可以增强应用程序的安全性,但我们认为这些 CVE 的提交并没有准确反映其严重性。 “Critical”级别是为最高危险的问题保留的,显然这里的情况并非如此。

任何人都可以申请 CVE。 虽然这对软件行业的整体健康有益,但“挖掘 CVEs”来增强单个安全研究员的声誉并没有帮助。

话虽如此,我们理解仅仅是一个带有可怕的 critical 严重性的 CVE 的存在可能会导致用户感到困惑,因此作为一个项目,我们希望提供指导和协助来处理这个问题。

这会给我带来什么影响?

在审查了 CVEs 之后,Electron 团队认为这些 CVEs 并不是 critical 的。

攻击者需要已经能够在机器上执行任意命令,无论是通过对硬件的物理访问还是通过实现完全的远程代码执行。 这值得重申:所描述的漏洞_要求攻击者已经能够访问被攻击的系统_。

例如,Chrome 在其威胁模型中不考虑本地物理攻击

我们认为这些攻击超出了 Chrome 的威胁模型范围,因为对于已经能够以你的身份登录你的设备或者能够以你的操作系统用户账户的权限运行软件的恶意用户,Chrome(或任何应用程序)无法进行防御。 这样的攻击者可以修改可执行文件和DLL文件,更改像 PATH 这样的环境变量,更改配置文件,读取你的用户账户所拥有的任何数据,将其通过电子邮件发送给自己等等。 这样的攻击者对你的设备拥有完全的控制权,Chrome 所能做的任何事情都无法提供严格的防御保证。 这个问题不仅仅存在于Chrome - 所有应用程序都必须信任本地物理用户。

利用 CVE 中描述的漏洞,攻击者可以将受影响的应用程序用作具有继承 TCC 权限的通用 Node.js 进程。 因此,如果应用程序例如已被授权访问地址簿,攻击者可以将应用程序作为 Node.js 运行,并执行将继承该地址簿访问权限的任意代码。 这通常被称为“寄生式攻击”。 攻击者通常使用 PowerShell、Bash 或类似工具来运行任意代码。

我是否受到了影响?

默认情况下,所有发布版本的 Electron 都启用了 runAsNode enableNodeCliInspectArguments 功能。 如果您没有按照 Electron Fuses 文档中描述的方法关闭它们,那么您的应用程序同样容易受到“寄生式攻击”的影响。 再次强调,攻击者需要已经能够在受害者的机器上执行代码和程序。

缓解措施

减轻这个问题的最简单方法是在您的 Electron 应用程序中禁用 runAsNode fuse。 runAsNode fuse 用于切换是否考虑 ELECTRON_RUN_AS_NODE ` 环境变量。 请参阅 Electron Fuses 文档以获取有关如何切换这些 fuses 的信息。

请注意,如果禁用了这个 fuse,那么主进程中的 process.fork 将无法按预期运行,因为它依赖于这个环境变量来运行。 相反,我们建议您使用实用进程,它适用于许多需要独立的 Node.js 进程的用例(例如 Sqlite 服务器进程或类似情况)。

您可以在我们的安全清单中找到更多关于我们推荐的 Electron 应用程序的安全最佳实践的信息。

Electron 28.0.0

· 阅读时间:约 5 分钟

Electron 28.0.0 已发布! 它包括升级 Chromium 120.0.6099.56 和 V8 12.0 以及 Node.js 18.18.2


Electron 团队很高兴发布了 Electron 28.0.0 ! 你可以通过 npm install electron@latest 或者从我们的发布网站下载它。 继续阅读此版本的详细信息。

如果您有任何反馈,请在 TwitterMastodon 上与我们分享,或加入我们的 Discord 社区! Bug 和功能请求可以在 Electron 的问题跟踪器中报告。

重要变化

重点内容

  • 实现了对 ECMAScript 模块或 ESM 的支持(什么是 ECMAScript 模块?) 在这里了解更多信息. 这包括在 Electron 本身中支持 ESM,以及诸如 UtilityProcess API 入口点等方面。 详情见我们的 ESM 文档 以获取更多详细信息。
  • 除了在 Electron 本身中启用 ESM 支持外,Electron Forge 还支持使用 ESM 来打包、构建和开发 Electron 应用程序。 您可以在 Forge v7.0.0 或更高版本中找到这种支持。

架构(Stack)更新

新特性

  • 启用 ESM 支持。 #37535
  • UtilityProcess API 添加了 ESM 入口点。 #40047
  • 添加了几个属性到 display 对象中,包括 detectedmaximumCursorSizenativeOrigin#40554
  • 新增对 Linux 上 ELECTRON_OZONE_PLATFORM_HINT 环境变量的支持。 #39792

重大更改

行为改变:在宿主 BrowserWindow 中将 WebContents.backgroundThrottling 设置为 false 将影响所有的 WebContents

WebContents.backgroundThrottling 设置为 false 将禁用由 BrowserWindow 显示的所有 WebContents 的帧节流。

移除: BrowserWindow.setTrafficLightPosition(position)

已经移除了 BrowserWindow.setTrafficLightPosition(position) 方法,应该改用 BrowserWindow.setWindowButtonPosition(position)方法。新的方法接受 null 作为替换 { x: 0, y: 0 } 的参数,以将位置重置为系统默认值。

// 在 Electron 28 移除
win.setTrafficLightPosition({ x: 10, y: 10 });
win.setTrafficLightPosition({ x: 0, y: 0 });

// 代替为
win.setWindowButtonPosition({ x: 10, y: 10 });
win.setWindowButtonPosition(null);

移除: BrowserWindow.getTrafficLightPosition()

已经删除了 BrowserWindow.getTrafficLightPosition(),应该使用 BrowserWindow.getWindowButtonPosition() API 代替,当没有自定义位置时,它返回 null 而不是 { x: 0, y: 0 }

// 在 Electron 28 移除
const pos = win.getTrafficLightPosition();
if (pos.x === 0 && pos.y === 0) {
// 没有自定义位置
}

// 代替为
const ret = win.getWindowButtonPosition();
if (ret === null) {
// 没有自定义位置
}

移除: ipcRenderer.sendTo()

ipcRenderer.sendTo() API 已经被删除。 应该用渲染进程之间的 MessageChannel 来替代它

IpcRendererEventsenderIdsenderIsMainFrame 属性也已经被移除。

移除: app.runningUnderRosettaTranslation

app.runningUnderRosettaTranslation 属性已经被移除。 使用 app.runningUnderARM64Translation 代替.

// 移除
console.log(app.runningUnderRosettaTranslation);
// 代替为
console.log(app.runningUnderARM64Translation);

终止对 25.x.y 的支持

根据项目的支持政策,Electron 25.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。

E28(23 年 12 月)E29(24 年 2 月)E30(24 年 4 月)
28.x.y29.x.y30.x.y
27.x.y28.x.y29.x.y
26.x.y27.x.y28.x.y

接下来

在短期内,您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发,包括 Chromium、Node 和 V8。

您可以在此处找到 Electron 的公开时间表

有关这些和未来变化的更多信息可在计划的突破性变化页面找到。

回顾 2023 年生态系统

· 阅读时间:约 8 分钟

回顾 2023 年 Electron 开发者生态系统的改进和变化。


过去几个月里,我们在整个 Electron 生态系统中进行一些优化,以提升 Electron 应用程序的开发者体验! 这是 Electron HQ 最新增加的项目的快速概述。

Electron Forge 7 及其以后

Electron Forge 7 — 用于打包和分发 Electron 应用程序的一体化工具的最新主要版本 — 现已发布。

虽然 Forge 6 与 v5 是完全重写的,但 v7 的范围较小,但仍包含一些重大变更。 未来,我们将继续发布 Forge 的主要版本,以便进行必要的重大变更。

欲了解更多详情,请参阅 GitHub 上的完整描述 Forge v7.0.0 更新日志

重大变更

  • 切换 macOS notarization 工具到 notarytool 截至2023-11-01。 苹果废弃了 macOS notarization 的传统工具 altool,此次发布将其从 Electron Forge 中完全删除。
  • 最小 Node.js 支持增加到 v16.4.0: 在这个版本中,我们已将所需版本的 Node.js 设置为 16.4.0。
  • 废弃了对 electron-prebuildelectron-prebuild-compile 的支持: electron-prebuild 是 electron npm 模块的原始名称的支持,但在 v1.3.1 中 被 electron 代替了。 electron-prebuild-compile 是一个带有增强开发体验功能的二进制文件的替代方案,但最终作为一个项目被放弃了。

重点内容

  • Google Cloud Storage 发布器: 作为我们推动更好地支持静态自动更新的一部分,Electron Forge 现在支持直接发布到 Google Cloud Storage!
  • ESM forge.config.js 支持: Electron Forge 现在支持 ESM forge.config.js 文件。 (附言: 期待在 Electron 28 中支持 ESM entrypoint。)
  • Makers 现在可以并行运行 在 Electron Forge 6 中 Makers 由于 ✨ 遗产 ✨ 原因而顺序运行。 从那时起,我们已经测试了使用并行 Make 步骤的效果,并且没有出现任何负面影响。 当在同一平台上构建多个目标时,你应该会看到加速效果!
非常感谢!

🙇 对于 mahnunchik 为 GCS Publisher 和 Forge 配置中支持 ESM 的贡献,表示衷心感谢!

静态存储自动更新的改进

Squirel.Windows 和 Squirrel.Mac 是支持 Electron 的内置 autoUpdater 模块的特定平台更新技术。 两个项目都支持通过两种方法自动更新:

  • 一个与 Squirrel 兼容的更新服务器
  • 在静态存储提供商上托管的清单 URL (例如 AWS、谷歌云平台、微软 Azure 等)

传统上,更新服务器方法一直被认为是 Electron 应用的推荐方法(并提供了额外的更新逻辑自定义),但它也有一个主要的缺点 — 如果应用是闭源的,它需要维护自己的服务器实例。

另一方面,虽然静态存储方法一直是可行的,但在 Electron 内部没有文档记录,并且在 Electron 工具包中支持不足。

通过 @MarshallOfSound 的杰出工作,无服务器自动应用程序更新已经得到了显著简化:

  • Electron Forge 的 Zip 和 Squirrel.Windows 制作工具现在可以配置为输出与 autoUpdater 兼容的更新清单。
  • 现在,update-electron-app 的一个新的主要版本(v2.0.0)可以读取这些生成的清单,作为 update.electronjs.org 服务器的替代方案。

一旦你的 Makers 和 Publishers 配置好了并上传更新清单到云文件存储,你只需要几行配置代码就可以启用自动更新。

const { updateElectronApp, UpdateSourceType } = require('update-electron-app');

updateElectronApp({
updateSource: {
type: UpdateSourceType.StaticStorage,
baseUrl: `https://my-manifest.url/${process.platform}/${process.arch}`,
},
});
延伸阅读

📦 想要了解更多? 详细指南见 Forge 的自动更新文档

@electron/ 扩展宇宙

Electron 刚开始时,社区发布了许多软件包,以增强开发、包装和分发 Electron 应用的体验。 随着时间的推移,其中许多软件包都被纳入 Electron 的 GitHub 组织,核心团队承担了维护负担。

在2022年,我们开始将所有这些 first-party 工具整合到 npm 的 @electron/ 命名空间下。 此变更意味着以前被称为 electron-foo 的软件包现在在 npm上被称为 @electron/foo,而以前命名为 electron/electron-foo 的仓库现在在 GitHub 上被称为 electron/foo。 这些变化有助于明确划分 first-party 项目和 userland 项目。 这包括许多常用的软件包,例如:

  • @electron/asar
  • @electron/fuses
  • @electron/get
  • @electron/notarize
  • @electron/osx-sign
  • @electron/packager
  • @electron/rebuild
  • @electron/remote
  • @electron/symbolicate-mac
  • @electron/universal

从现在开始,我们发布的所有 first-party 软件包都将在 @electron/ 命名空间中。 这条规则有两个例外情况:

  • Electron 核心将继续在 electron 软件包下发布。
  • Electron Forge 将继续在 @electron-forge/ namespace 下发布其所有的 monorepo 软件包。
寻找 Star

⭐ 在这个过程中,我们意外地将 electron/packager 仓库设为私有,这不幸地导致我们的 GitHub 星星计数被删除(擦除之前超过9000颗)。 如果你是 Packager 的活跃用户,我们将非常感谢你的 ⭐ Star ⭐ !

介绍 @electron/windows-sign

从 2023 年 6 月 1日开始,行业标准要求 Windows 代码签名证书的密钥必须存储在符合 FIPS 标准的硬件上。

在实践中,这意味着对于在 CI 环境中构建和签名的应用来说,代码签名变得更加困难,因为许多 Electron 工具使用证书文件和密码作为配置参数,并尝试使用硬编码逻辑从中进行签名。

这种情况对于 Electron 开发人员来说是一个常见的痛点,这就是为什么我们一直在努力寻找一个更好的解决方案,将 Windows 代码签名独立到一个单独的步骤中,类似于 @electron/osx-sign 在 macOS 上的做法。

在未来,我们计划将此软件包完全整合到 Electron Forge 工具链中,但目前它独立存在。 该软件包目前可通过 npm install --save-dev @electron/windows-sign 进行安装,并可通过编程或命令行界面(CLI)进行使用。

请尝试在项目的 issue 跟踪器中给我们反馈!

下一步

我们将在下个月进入我们每年 12 月安静的时期。 在这样做的同时,我们将考虑如何在 2024 年使 Electron 开发体验更好。

你是否希望看到我们接下来的工作? 请告诉我们!

12月安静期(2023年12月)

· 阅读时间:约 2 分钟

The Electron project will pause for the month of December 2023, then return to full speed in January 2024.

via GIPHY


12月保持不变的内容

  1. 必要时将发布零日和其他与安全相关的主版本。 Security incidents should be reported via SECURITY.md.
  2. Code of Conduct reports and moderation will continue.

12月变动的内容

  1. Electron 28.0.0 will be released on December 5th. After Electron 28, there will be no new Stable releases in December.
  2. 12 月的最后两周没有 Nightly 和 Alpha 版本。
  3. 除了少数例外,不会合并请求的审核或合并。
  4. 任何仓库上都不会有问题跟进更新。
  5. 维护人员不会提供 Discord 调试帮助。
  6. 社交媒体暂停更新内容。

Going forward

This is our third year running our quiet period experiment, and we've had a lot of success so far in balancing a month of rest with maintaining our normal release cadence afterwards. Therefore, we've decided to make this a regular part of our release calendar going forward. We'll still be putting a reminder into the last stable release of every calendar year.

See you all in 2024!

Electron 27.0.0

· 阅读时间:约 5 分钟

Electron 27.0.0 已发布! 此次升级中包含 Chromium 118.0.5993.32,V8 11.8,和 Node.js 18.17.1


Electron 团队很高兴发布了 Electron 27.0.0! 您可以通过 npm install electron@latest 进行安装,或者从我们的 发布网站 下载它。 继续阅读此版本的详细信息。

如果您有任何反馈,请在 TwitterMastodon 上与我们分享,或加入我们的 Discord 社区! Bug 和功能请求可以在 Electron 的 问题跟踪器 中报告。

重要变化

架构(Stack)更新

重大更改

已移除:macOS 10.13 / 10.14 / 支援

macOS 10.13 (High Serria) 和 macOS 10.14 (Mojave) 不再支援Chromium.

旧版本的 Electron 将继续在这些操作系统上运行,但需要 macOS 10.15 (Catalina) 或更高版本才能运行 Electron v27.0.0 及更高版本。

弃用:ipcRenderer.sendTo()

ipcRenderer.sendTo() 已被弃用。 可以通过在渲染器之间设置一个 MessageChannel 来替换它。

IpcRendererEventsenderIdsenderIsMainFrame 属性也已被弃用。

已删除: systemPreferences 中的 color scheme 相关事件

以下 systemPreferences 事件已被删除:

  • inverted-color-scheme-changed
  • high-contrast-color-scheme-changed

请改用 nativeTheme 模块上的新 updated 事件。

// 已删除
systemPreferences.on('inverted-color-scheme-changed', () => {
/* ... */
});
systemPreferences.on('high-contrast-color-scheme-changed', () => {
/* ... */
});

// 替换为
nativeTheme.on('updated', () => {
/* ... */
});

已删除: webContents.getPrinters

webContents.getPrinters 方法已被删除。 使用webContents.getPrintersAsync代替。

const w = new BrowserWindow({ show: false });

// 已删除
console.log(w.webContents.getPrinters());
// 替换为
w.webContents.getPrintersAsync().then((printers) => {
console.log(printers);
});

已删除:systemPreferences.{get,set}AppLevelAppearancesystemPreferences.appLevelAppearance

方法 systemPreferences.getAppLevelAppearancesystemPreferences.setAppLevelAppearance 已被删除,也包括属性 systemPreferences.appLevelAppearance。 请改用模块 nativeTheme

// 已删除
systemPreferences.getAppLevelAppearance();
// 替换为
nativeTheme.shouldUseDarkColors;

// 已删除
systemPreferences.appLevelAppearance;
// 替换为
nativeTheme.shouldUseDarkColors;

// 已删除
systemPreferences.setAppLevelAppearance('dark');
// 替换为
nativeTheme.themeSource = 'dark';

已删除:systemPreferences.getColoralternate-selected-control-text

systemPreferences.getColoralternate-selected-control-text 值已被删除。 替换为 selected-content-background

// 已删除
systemPreferences.getColor('alternate-selected-control-text');
// 替换为
systemPreferences.getColor('selected-content-background');

新特性

  • 添加了应用可访问性透明度设置 API #39631
  • 添加了对 chrome.scripting 扩展 API 的支持 #39675
  • 默认启用 WaylandWindowDecorations #39644

终止对 24.x.y 的支持

根据项目的支持政策,Electron 24.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。

E27(23 年 10 月)E22 (23 年 12 月)E29(24 年 2 月)
27.x.y28.x.y29.x.y
26.x.y27.x.y28.x.y
25.x.y26.x.y27.x.y

终止对 22.x.y 的支持

今年早些时候,Electron 团队将 Electron 22 的计划生命终止日期从 2023 年 5 月 30 日延长至 2023 年 10 月 10 日,以配合 Chrome 对 Windows 7/8/8.1 的扩展支持(详情请查看 Farewell, Windows 7/8/8.1)。

根据项目的支持政策和此支持扩展,Electron 22.x.y 已经达到了支持的终点。 这将恢复到支持最新的三个稳定的主要版本,并将结束对 Windows 7/8.1 的官方支持。

接下来

在短期内,您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发,包括 Chromium、Node 和 V8。

您可以在此处找到 Electron的公开时间表

有关这些和未来变化的更多信息可在 计划的突破性变化 页面找到。

Breach to Barrier: Strengthening Apps with the Sandbox

· 阅读时间:约 7 分钟

距离 CVE-2023-4863: 在WebP图片中的堆栈溢出 被公开已经过去了一个星期多。这导致众多渲染 webp 图片的软件都得到了更新:macOS, iOS, Chrome, Firefox 和众多 Linux 发行版都发布了更新。 这是在Citizen Lab进行调查之后进行的。他们发现 “设在华盛顿特区的民间组织” 使用的iPhone通过零点击漏洞在iMessage中被攻击。

Electron也在同一天发布新版本:如果您的应用会显示任何用户提供的内容 您应该更新您的 Electron 版本 - v27 0.0-beta.2, v26.2.1, v25.8.1, v24.8.3, v22.3.24 均包括已经过修复的 libwebp,一个负责渲染 webp 图像的库。

既然我们大家都新近意识到, 像“渲染一幅图片” 这样看似无害的交互是一种潜在的危险活动, 我们要借此机会提醒大家,Electron包括的进程沙盒将限制下一次大型攻击的猛烈程度,无论它将会是什么。

沙盒从 Electron v1 开始可用,并在 v20 默认情况下启用。 但我们知道许多应用 (尤其是那些已经存在有一段时间的应用) 可能会在其代码中的某个地方有一个 sandbox: falsenodeIntegration: true,这则配置在当没有明确的 sandbox 设置时同样禁用沙盒。 这是可以理解的:如果你已经使用Electron很长时间,你可能已经感受到了 require("child_process")require("fs") 直接扔进运行你的 HTML/CSS 的代码带来的力量。

在我们讨论你能够_如何_迁移到沙盒内之前,我们不如首先讨论你_为什么_会想要迁移。

沙盒围绕所有渲染进程设置了一个保护机制。这确保不论内部发生什么,代码都在受限制的环境中执行。 作为一个概念,它比Chromium老得多,并且所有主流的操作系统都提供了这个功能。 Electron和Chromium的沙盒搭建在这些系统功能之上。 即使您从未显示用户生成的内容,你应该考虑到你的渲染器可能受到损害的可能性:场景像供应链攻击一样复杂,并且很简单,因为小的bug可能会导致你的渲染器做意想不到的事。

沙盒使情景变得更安全:一个在沙盒内的进程可以免费使用 CPU 资源和内存 — 就没别的了。 进程不能写入磁盘或显示自己的窗口。 就我们的 libwep bug而言,沙盒确保攻击者无法安装或运行恶意程序。 事实上,在最初 Pegasus 袭击雇员 iPhone 的案件中,袭击具体针对的是一个非沙盒图像进程以获得对手机的访问权限,打破了正常情况下 iMessage 沙盒的界限。 当一个CVE像这个示例中的那样被宣布时,您仍然须将您的 Electron 应用程序升级到安全版本 — 不过与此同时,攻击者能够造成的损害受到极大的限制。

将原版Electron应用程序从 sandbox: false 迁移到 sandbox: true 是一项较大的任务。 我理解,因为即使我亲自撰写了 Electron 安全准则,我还没有设法迁移我自己的一个应用来使用该项准则。 在这个周末,我把它改掉了,我建议你也这么做。

别被修改行数的体量吓到,这些大多都在 package-lock.json 里。

你需要处理两件事:

  1. 如果您在 preload 脚本或实际的 WebContents 中使用Node.js 代码,您需要将所有以上这些与 Node.js 的交互迁移到主进程 (或者,如果你愿意的话,一个多用途进程) 。 考虑到最近渲染器正在变得越来越强大,很有可能你的代码很大一部分其实并不需要重构。

    查阅我们对于 进程间通信 的文档。 就我而言,我移动了许多代码,并用 ipcRenderer.invoke()ipcMain.handle()包装了它,但是这个过程是直截了当的,而且很快就完成了。 请稍微注意你的 API - 如果你构建一个名为 executeCodeAsRoot(code)的API,沙盒将不会过多地保护你的用户。

  2. 因为启用沙盒会在您的预加载脚本中禁用对 Node.js 的集成,你不再能使用require("../my-script")。 换言之,您的预加载脚本需要是一个单一的文件。

    这样做有多种方式:Webpack、esbuild、parcel 和 rollup 都能办到。 我使用 Electron Forge的出色Webpack插件,而同样受欢迎的 electron-builder 用户可以使用 electron-webpack

总的来讲,整个过程花了我四天时间 — 而这包括很多,由于我决定利用这次机会通过其他方式去重构我的代码而产生的,对于如何最大化 Webpack 众多效用的思考。

Electron 26.0.0

· 阅读时间:约 3 分钟

Electron 26.0.0 已发布! 此次升级中包含 Chromium 116.0.5845.62,V8 11.2,和 Node.js 18.16.1 。 请阅读下文了解更多详情!


Electron 团队很高兴发布了 Electron 26.0.0 ! 您可以通过 npm install electron@latest 进行安装,或者从我们的 发布网站 下载它。 继续阅读此版本的详细信息。

如果您有任何反馈,请在Twitter上与我们分享,或加入我们的社区 Discord! Bug 和功能请求可以在 Electron 的 问题跟踪器 中报告。

重要变化

架构(Stack)更新

重大更改

弃用:webContents.getPrinters

webContents.getPrinters 方法已经被废除。 使用webContents.getPrintersAsync代替。

const w = new BrowserWindow({ show: false });

// 被弃用
console.log(w.webContents.getPrinters());
// 使用它来代替
w.webContents.getPrintersAsync().then((printers) => {
console.log(printers);
});

弃用:systemPreferences.{get,set}AppLevelAppearancesystemPreferences.appLevelAppearance

方法systemPreferences.getAppLevelAppearancesystemPreferences.setAppLevelAppearance 已被弃用,也包括属性 systemPreferences.appLevelAppearance。 请改用模块 nativeTheme

// 被弃用
systemPreferences.getAppLevelAppearance();
// 替换为
nativeTheme.shouldUseDarkColors;

// 被弃用
systemPreferences.appLevelAppearance;
// 替换为
nativeTheme.shouldUseDarkColors;

// 被弃用
systemPreferences.setAppLevelAppearance('dark');
// 替换为
nativeTheme.themeSource = 'dark';

弃用:systemPreferences.getColoralternate-selected-control-text

systemPreferences.getColoralternate-selected-control-text 值已被弃用。 替换为 selected-content-background

// 被弃用
systemPreferences.getColor('alternate-selected-control-text');
// 替换为
systemPreferences.getColor('selected-content-background');

新特性

  • 添加了 safeStorage.setUsePlainTextEncryptionsafeStorage.getSelectedStorageBackend api。 #39107
  • 添加了 safeStorage.setUsePlainTextEncryptionsafeStorage.getSelectedStorageBackend api。 #39155
  • senderIsMainFrame添加到通过ipcRenderer.sendTo()发送的消息中。 #39206
  • 添加了由键盘初始化菜单弹出的支持。 #38954

终止对 23.x.y 的支持

根据项目的支持政策,Electron 23.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。

E26(23 年 8月)E27(23 年 10 月)E28(24 年 1 月)
26.x.y27.x.y28.x.y
25.x.y26.x.y27.x.y
24.x.y25.x.y26.x.y
22.x.y

接下来

在短期内,您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发,包括 Chromium、Node 和 V8。

您可以在此处找到 Electron的公开时间表

有关这些和未来变化的更多信息可在 计划的突破性变化 页面找到。

Electron 25.0.0

· 阅读时间:约 6 分钟

Electron 25.0.0 已发布! 此次升级中包含 Chromium 114,V8 11.4,和 Node.js 18.15.0 。 请阅读下文了解更多详情!


Electron 团队很高兴发布了 Electron 25.0.0 ! 您可以通过 npm install electron@latest 进行安装,或者从我们的 发布网站 下载它。 继续阅读此版本的详细信息。

如果您有任何反馈,请在Twitter上与我们分享,或加入我们的社区 Discord! Bug 和功能请求可以在 Electron 的 问题跟踪器 中报告。

重要变化

重点内容

  • 使用 Chromium 的网络栈在 Electron 的 net 模块中实现了 net.fetch。 和 Node 的 fetch() 不同的是后者使用了 Node.js 的 HTTP 栈。 请参阅 #36733#36606
  • 添加了 protocol.handle,它取代并弃用了 protocol.{register,intercept}{String,Buffer,Stream,Http,File}Protocol#36674
  • 增加了对 Electron 22 的支持,以配合 Chromium 和 Microsoft 的 Windows 7/8/8.1 弃用计划。 请参阅本博文末尾的更多详细信息。

架构(Stack)更新

重大更改

弃用:protocol.{register,intercept}{Buffer,String,Stream,File,Http}Protocol

protocol.register***Protocolprotocol.intercept***Protocol 方法 已替换为 protocol.handle

新方法可以注册新协议或拦截现有协议 协议和响应可以是任何类型。

// 在 Electron 25 中弃用
protocol.registerBufferProtocol('some-protocol', () => {
callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') });
});

// 用以代替
protocol.handle('some-protocol', () => {
return new Response(
Buffer.from('<h5>Response</h5>'), // 也可以是 string 或 ReadableStream.
{ headers: { 'content-type': 'text/html' } }
);
});
// 在 Electron 25 中弃用
protocol.registerHttpProtocol('some-protocol', () => {
callback({ url: 'https://electronjs.org' });
});

// 用以代替
protocol.handle('some-protocol', () => {
return net.fetch('https://electronjs.org');
});
// 在 Electron 25 中弃用
protocol.registerFileProtocol('some-protocol', () => {
callback({ filePath: '/path/to/my/file' });
});

// 用以代替
protocol.handle('some-protocol', () => {
return net.fetch('file:///path/to/my/file');
});

弃用:BrowserWindow.setTrafficLightPosition(position)

BrowserWindow.setTrafficLightPosition(position) 已弃用,应使用 BrowserWindow.setWindowButtonPosition(position) API,它接受 null 而不是 { x: 0, y: 0 } 将位置重置为系统默认值。

// 在 Electron 25 中弃用
win.setTrafficLightPosition({ x: 10, y: 10 });
win.setTrafficLightPosition({ x: 0, y: 0 });

// 用以代替
win.setWindowButtonPosition({ x: 10, y: 10 });
win.setWindowButtonPosition(null);

弃用:BrowserWindow.getTrafficLightPosition()

BrowserWindow.getTrafficLightPosition() 已弃用,应使用 BrowserWindow.getWindowButtonPosition() API,当没有自定义位置时,它返回 null 而不是 { x: 0, y: 0 }

// Deprecated in Electron 25
const pos = win.getTrafficLightPosition();
if (pos.x === 0 && pos.y === 0) {
// No custom position.
}

// Replace with
const ret = win.getWindowButtonPosition();
if (ret === null) {
// No custom position.
}

新特性

  • 已添加 net.fetch()#36733
    • net.fetch 支持对 file: URL 和使用 protocol.register*Protocol 注册的自定义协议的请求。 #36606
  • 添加了 BrowserWindow.set/getWindowButtonPosition API。 #37094
  • 添加了protocol.handle,替换并弃用了protocol.{register,intercept}{String,Buffer,Stream,Http,File}Protocol#36674
  • webContents<webview> 标签添加了一个 will-frame-navigate 事件,每当 frame 层中的任何一个 frame 调用 navigate 时,都会触发该函数。 #34418
  • 向 navigator 事件添加了启动信息。 这个信息允许区分来自父框架 window.open 引起的 navigation 事件,而不是来自子框架发起的 navigation 事件。 #37085
  • 增加了 net.resolveHost,它使用 defaultSession 对象来解析 hosts。 #38152
  • app 添加了新的 'did-resign-active' 事件。 #38018
  • webContents.print() 添加了几个标准页面大小选项。 #37159
  • 向会话处理程序 ses.setDisplayMediaRequestHandler() 的回调中添加了 enableLocalEcho 标志,以允许当 audioWebFrameMain 时在本地输出流中回显远程音频输入。 #37315
  • powerMonitor 添加了 thermal 信息管理。 #38028
  • 允许将绝对路径传递给 session.fromPath() API。 #37604
  • webContents 上公开 audio-state-changed 事件。 #37366

22.x.y 持续支持

正如再见 Windows 7/8/8.1 所述,Electron 22(Chromium 108)的计划寿命终止日期将从 2023 年 5 月 30 日延长至 2023 年 10 月 10 日。 Electron 团队将会继续向 Electron 22 提供本计划中的任何安全修复,直到 2023 年 10 月 10 日。 十月 支持日期遵循 Chromium 和 Microsoft 的延长支持日期。 10 月 11 日,Electron 团队将支持回退到最新的三个稳定主要版本,将不再支持 Windows 7/8/8.1。

E25(23 年 5 月)E26(23 年 8月)E27(23 年 10 月)
25.x.y26.x.y27.x.y
24.x.y25.x.y26.x.y
23.x.y24.x.y25.x.y
22.x.y22.x.y--

接下来

在短期内,您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发,包括 Chromium、Node 和 V8。

您可以在此处找到 Electron的公开时间表

有关这些和未来变化的更多信息可在 计划的突破性变化 页面找到。

Electron 24.0.0

· 阅读时间:约 5 分钟

Electron 24.0.0 已发布! 此次升级中包含 Chromium 112.0.5615.49,V8 11.2,和 Node.js 18.14.0 。 请阅读下文了解更多详情!


Electron 团队很高兴发布了 Electron 24.0.0 ! 您可以通过 npm install electron@latest 进行安装,或者从我们的 发布网站 下载它。 继续阅读此版本的详细信息。

如果您有任何反馈,请在Twitter上与我们分享,或加入我们的社区 Discord! Bug 和功能请求可以在 Electron 的 问题跟踪器 中报告。

重要变化

架构(Stack)更新

重大更改

API Changed: nativeImage.createThumbnailFromPath(path, size)

maxSize 参数已更改为 size 以反映传入的大小将是创建的缩略图的大小。 以前,如果图像小于 maxSize,Windows 不会放大图像,而 macOS 总会将大小设置为 maxSize。 现在跨平台的行为是相同的。

// 一张 128x128 的图片。
const imagePath = path.join('path', 'to', 'capybara.png');

// 放大较小的图像。
const upSize = { width: 256, height: 256 };
nativeImage.createThumbnailFromPath(imagePath, upSize).then((result) => {
console.log(result.getSize()); // { width: 256, height: 256 }
});

// 缩小更大的图像。
const downSize = { width: 64, height: 64 };
nativeImage.createThumbnailFromPath(imagePath, downSize).then((result) => {
console.log(result.getSize()); // { width: 64, height: 64 }
});

新特性

  • 添加了使用 cookies.get() 过滤 cookie 中 HttpOnly 的功能。 #37365
  • logUsage 添加到 shell.openExternal() 参数中,以允许将 SEE_MASK_FLAG_LOG_USAGE 标志传递给 Windows 上的 ShellExecuteExSEE_MASK_FLAG_LOG_USAGE 标志表示用户发起启动,可以跟踪常用程序和其他行为。 #37291
  • webRequest 过滤器添加了 types,添加了过滤监听请求的能力。#37427
  • webContents 添加了一个新的 devtools-open-url 事件,以允许开发人员使用它们打开新窗口。 #36774
  • webContents.print() 添加了几个标准页面大小选项。 #37265
  • 向会话处理程序 ses.setDisplayMediaRequestHandler() 的回调中添加了 enableLocalEcho 标志,以允许当 audioWebFrameMain 时在本地输出流中回显远程音频输入。 #37528
  • 允许向 inAppPurchase.purchaseProduct() 传递一个特定于应用程序的用户名。 #35902
  • 公开了window.invalidateShadow(),以清除macOS上残留的视觉伪影。 #32452
  • 整个程序优化现在在 Electron headers 配置文件中默认启用,允许编译器利用程序中所有模块的信息进行优化,而不是以每个模块 (compiland) 为基础。 #36937
  • SystemPreferences::CanPromptTouchID (macOS) 现在支持Apple Watch。 #36935

终止对 21.x.y 的支持

根据项目的支持政策,Electron 21.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。

As noted in Farewell, Windows 7/8/8.1, Electron 22's (Chromium 108) planned end of life date will be extended from May 30, 2023 to October 10, 2023. The Electron team will continue to backport any security fixes that are part of this program to Electron 22 until October 10, 2023.

E24(23 年 4 月)E25(23 年 5 月)E26(23 年 8月)
24.x.y25.x.y26.x.y
23.x.y24.x.y25.x.y
22.x.y23.x.y24.x.y
--22.x.y22.x.y

接下来

在短期内,您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发,包括 Chromium、Node 和 V8。

您可以在此处找到 Electron的公开时间表

有关这些和未来变化的更多信息可在 计划的突破性变化 页面找到。

Electron 10 周年🎉

· 阅读时间:约 16 分钟

2013年3月13日1 首次被提交到 electron/electron 仓库。

由 @aroben 进行的 electron/electron 的初始提交。

经过10年和来自 1192 位贡献者的 27147 次提交之后,Electron 已成为如今构建桌面应用程序最受欢迎的框架之一。 这个里程碑是一个完美的机会,可以庆祝和回顾我们迄今为止的旅程,并分享我们沿途所学到的东西。

如果没有每个人都献出时间和努力为该项目做出贡献,我们今天就不会在这里了。 尽管源代码提交总是最显著的贡献,但我们还必须承认那些报告错误、维护用户空间模块、提供文档和翻译,并参与网络空间中的 Electron 社区的人所做出的努力。 对于我们作为维护者来说,每一份贡献都是无价之宝。

在我们继续博客文章的其余部分之前:谢谢你们。 ❤️

我们怎么发展到现在的?

Atom Shell 是为 GitHub Atom 编辑器 打造的基础框架,该编辑器于 2014 年 4 月公开发布 beta 版。 它是基于当时一些以网页为基础的桌面端框架 (node-webkit and Chromium Embedded Framework) 从头开始构建的替代方案。 它有一个杀手级功能:嵌入 Node.js 和 Chromium,为网页 技术提供一个强大的桌面运行时间。

一年之内,Atom Shell 的功能和知名度开始大幅增长。 大型公司、初创公司和个人开发者都已开始使用它构建应用程序。(一些早期采用者包括 Slack, GitKrakenWebTorrent), 该项目被恰当地重命名为 Electron

从那时起,Electron 便一发不可收拾,从未停止过。 这里是每周下载量随时间变化的趋势,由 npmtrends.com 提供:

Electron 每周下载量随时间变化的图表

Electron v1 于 2016 年发布,承诺增加 API 稳定性和更好的文档和工具。 Electron v2 于 2018 年发布,并引入了语义版本,使 Electron 开发者更容易跟踪发布周期。

到 Electron v6 时,我们转变为常规的 12 周主要发布节奏,以与 Chromium 相匹配。 这个决定是该项目心态的改变,将“拥有最新的 Chromium 版本”从一种附加功能变成了一项优先考虑的任务。 这降低了版本升级之间的技术债务量,使我们更容易地保持 Electron 的更新和安全。

从那时起,我们就像一台润滑良好的机器一样运转,每次 Chromium 稳定版发布时都会同时发布一个新的 Electron 版本。 到 2021 年,Chromium 加快了发布速度,每 4 周发布一次,而我们也能够轻松地调整发布频率为每 8 周。

现在我们已经更新到了 Electron v23 (并且还在继续更新),仍致力于构建最佳的跨平台桌面应用程序运行时。 尽管近年来 JavaScript 开发工具繁荣发展,但 Electron 仍然是桌面应用程序框架领域中一个稳定、经受过实战考验的重要支柱。 如今,Electron 应用程序已经无处不在:您可以使用 Visual Studio Code 进行编程,使用 Figma 进行设计,使用 Slack 进行通信,并使用 Notion 进行笔记记录 (还有许多其他用例)。 我们对这一成就感到非常自豪,并感谢使之成为可能的每一个人。

在这个过程中,我们学到了什么?

这十年的历程曲折而漫长。 以下是一些关键因素,帮助我们运营一个可持续的大型开源项目。

通过治理模型扩展分布式决策制定。

我们不得不克服的一个挑战是,在 Electron 初次爆发出人气后,如何处理项目的长期发展方向。 我们如何处理一个由几十名工程师组成、分布在不同公司、不同国家和不同时区的团队?

在早期,Electron 的维护者团队依靠非正式的协调方式,这对于较小的项目来说是快速和轻量级的,但不适用于更广泛的协作。 在2019年,我们转向了一种治理模型,不同的工作组拥有正式的责任领域。 这对于简化流程和将项目所有权的部分分配给特定的维护者非常重要。 现在每个工作组 (WG) 负责什么?

  • 将 Electron 发布上线 (Releases WG)
  • 升级 Chromium 和 Node.js (Upgrades WG)
  • 监督公共 API 设计 (API WG)
  • 保持 Electron 的安全性 (Security WG)
  • 运营网站、文档和工具 (Ecosystem WG)
  • 社区与企业外联 (Outreach WG)
  • 社区管理 (Community & Safety WG)
  • 维护我们的构建基础设施,维护者工具和云服务 (Infrastructure WG)

在我们转向治理模式的同时,我们还将 Electron 的所有权从 GitHub 转移到了 OpenJS Foundation 尽管原来的核心团队今天仍然在 Microsoft 工作,他们也仅仅是 Electron 治理团队这个庞大组织的一部分。2

虽然这种模式并不完美,但它在全球流行病和持续的宏观经济逆风中为我们提供了良好的支持。 今后,我们计划修订治理章程,以指导我们走向 Electron 的第二个十年。

info

如果您想了解更多,请查看 electron/governance 代码仓库!

社区

开源社区的组织是很困难的,特别是当你的外联团队是一群穿着“社区经理”外套的十几个工程师时。 话虽如此,成为一个大型的开源项目意味着我们拥有大量的用户,利用他们的能量来为 Electron 建立用户生态系统是维持项目健康的关键部分。

我们为发展社区做了哪些工作?

建立社区

  • 2020 年,我们推出了我们在 Discord server 的社区。 我们之前在 Atom 的论坛上有一个版块,但决定有一个更非正式的消息传递平台,让维护者和 Electron 开发人员之间有一个讨论的空间,并获得一般的调试帮助。
  • 2021 年,我们在 @BlackHole1 的帮助下建立了 Electron China 用户群。 这个群体在中国蓬勃发展的科技界中对 Electron 用户的增长起了重要作用,为他们在我们的英语语言的范畴之外提供了一个创意合作、讨论 Electron 的空间。 我们还要感谢 cnpm 为支持 Electron 在他们的中文镜像中为 npm 所做的工作。

参与高知名度的开源项目​

  • 自 2019 年以来,我们每年都会庆祝 Hacktoberest 。 Hacktoberfest 是由 DigitalOcean 组织的每年一度的开源庆典,每年我们都会有数十名热情的贡献者加入其中,希望在开源软件上留下自己的印记。
  • 在 2020 年,我们参加了首次举行的 Google Season of Docs 活动,与 @bandantonio 合作重新设计了 Electron 的新用户教程流程。
  • 2022年,我们第一次指导 Google Summer of Code 的学生。 @aryanshridhar did some awesome work to refactor Electron Fiddle's core version loading logic and migrate its bundler to webpack.

将所有东西自动化!

今天,Electron 的维护有大约 30 名积极的维护者。 我们中只有不到一半的人是全职贡献者,这意味着还有很多工作需要做。 我们怎么才能让一切顺利进行呢? 我们的座右铭是计算机便宜,人的时间是昂贵的。 按照典型的工程师风格,我们开发了一套自动化支持工具来使我们的生活更轻松。

Not Goma​

Electron 的核心代码库是一个庞大的 C++ 代码库,而编译时间一直是限制我们能够快速发布错误修复和新功能的因素之一。 在2020年,我们部署了Not Goma,这是一个专门为 Electron 定制的后端,用于 Google 的 Goma 分布式编译器服务。 Not Goma 处理来自授权用户机器的编译请求,并在后端的数百个核心上进行分布式编译。 它还会缓存编译结果,这样编译相同文件的其他人只需下载预编译的结果即可。

自从启用 Not Goma 以来,维护者的编译时间已经从几个小时缩短到几分钟的级别。 拥有稳定的互联网连接成为贡献者编译 Electron 的最低要求!

info

如果你是一个开源贡献者,你也可以尝试 Not Goma 的只读缓存,它默认在 Electron Build Tools 中提供。

Continuous Factor Authentication

Continuous Factor Authentication (CFA) 是 npm 双因素认证(2FA)系统的自动化层,我们将其与语义化版本控制工具(semantic-release)结合使用来管理我们各种 @electron/ npm 包的安全和自动化发布。

虽然语义化版本控制工具(semantic-release)已经自动化了 npm 包的发布过程,但它需要关闭两步验证或传递绕过此限制的秘密令牌。

我们构建了CFA 来为 npm 2FA 提供基于时间的一次性密码(TOTP),以供任意 CI 任务使用,从而让我们利用语义化版本控制工具(semantic-release)的自动化功能,同时保持双重身份验证的额外安全性。

我们使用 CFA 与 Slack 集成前端,允许维护人员在任何拥有 Slack 的设备上验证软件包发布,只要他们手头有 TOTP 生成器即可。

info

如果您想在自己的项目中尝试 CFA,请查看 GitHub存储库文档 ! 如果您使用 CircleCI 作为 CI 提供程序,我们还有 一个方便的 orb,可以快速搭建一个带有 CFA 的项目。

Sheriff

Sheriff 是我们编写的一个开源工具,用于自动化管理 GitHub、Slack 和 Google Workspace 等平台上的权限。

Sheriff 的主要价值主张是权限管理应该是一个透明的进程。 它使用一个单独的 YAML 配置文件,指定了所有上述服务的权限。 使用 Sheriff,获得对仓库的协作者身份或创建新的邮件列表就像获得 PR 批准并合并一样容易。

Sheriff 还具有审计日志,会发布到 Slack,当 Electron 组织中的任何地方发生可疑活动时,会向管理员发出警告。

…和我们所有的 GitHub 机器人

GitHub 是一个具有丰富 API 可扩展性的平台,并且拥有一个称为 Probot 的官方机器人应用程序框架。 为了帮助我们专注于工作中更有创意的部分,我们开发了一套更小型的机器人,以帮助我们完成一些繁琐的工作。 以下是一些例子:

  • Sudowoodo 可以自动化 Electron 的发布流程,从启动构建到上传发布资产至 GitHub 和 npm,全部自动化完成。
  • Trop 可以根据 GitHub PR 标签,在先前的发行分支上尝试挑选补丁,从而自动化 Electron 的回溯过程。
  • Roller 可以自动化 Electron 的 Chromium 和 Node.js 依赖项的滚动升级过程。
  • Cation 是我们针对 electron/electron PR 的状态检查机器人。

总的来说,我们的这些小机器人为我们的开发者生产力带来了巨大的提升!

下一步是什么?

在我们进入项目的第二个十年时,您可能会问:Electron 接下来会发生什么?

我们将继续保持同步 Chromium 的发布节奏,每 8 周发布 Electron 新的主要版本,以保持该框架更新到 Web 平台和 Node.js 的最新技术,同时维护企业级程序的稳定性和安全性

通常,我们会在计划即将实现时公布相关消息。 如果你想跟进未来的新版本、功能和项目更新的最新动态,你可以阅读我们的博客,并关注我们的社交媒体账户(TwitterMastodon)!

Footnotes

  1. 这实际上是来自 electron-archive/brightray 项目的第一次提交,该项目在 2017 年被整合到了 Electron 中,并合并了其 Git 历史记录。 但谁在乎呢? 今天是我们的生日,所以我们可以制定规则!

  2. 与普遍的看法相反的是,Electron 不再属于 Github 或者 Microsoft 所有,在现在是OpenJS Foundation 的一部分.