Electron 45 上 Chromium 156、Node 24.22、V8 15.6:破坏性变更都在沙箱边界上

v45.0.0 的破坏性变更集中在三处:沙箱预加载脚本不再有 events/timers/url 与 Buffer 等全局、iframe 里创建的 Worker 不再自动拿到 Node、扩展页面不再无条件注入预加载脚本。

Electron 45.0.0 在 10 月 21 日发布,栈升级到 Chromium 156.0.8078.48 / Node 24.22.0 / V8 15.6。这种大版本升级本身没什么可讲的,但它的破坏性变更清单很集中:全部落在沙箱与注入边界上。

一、沙箱预加载脚本少了六个东西

改动来自 #54048,标题是「减少不使用 Buffer 的沙箱预加载脚本的启动开销」。具体做法:

  • 从沙箱预加载脚本里移除 events、timers、url 三个模块;
  • 同时移除 Buffer、setImmediate、clearImmediate 三个全局;
  • 沙箱渲染器(没有预加载脚本时)启动更快;
  • 沙箱预加载脚本启动更快 —— 除非开启 webviewTag,Electron 不再在沙箱渲染器里求值自己那份 JS 包。

逻辑很清楚:沙箱预加载脚本过去会预置一小套 Node 兼容层,为的是让老代码能跑。这份兼容层本身就是启动成本。现在默认不给了,需要的人自己 polyfill。

// 过去在沙箱预加载脚本里可以直接用
const { EventEmitter } = require('events');
const buf = Buffer.from('hello');

// 45 之后:自己补
// preload.js 顶部引入 polyfill,或用 contextBridge 从主进程传能力

Electron v45.0.0 的发布页

这条对老项目是实打实的破坏:升级后某些 preload 会直接抛 Cannot find module 'events'。而 preload 出错的表现通常是「页面看起来正常,但所有 IPC 都不工作」—— 比白屏更难查。

二、Worker 的 Node 集成不再「跟着进程走」

第二个变更更有意思:

开启 nodeIntegrationInWorker: true 时,从 <iframe> 里创建的 Worker 过去会拿到 Node 集成,即使那个 iframe 自己没有。

也就是说,判断依据从「进程里有没有开」变成了「创建它的 frame 有没有开」。现在的规则是:只有主 frame,或者开启了 nodeIntegrationInSubFrames 时的任意 frame,创建的 Worker 才有 Node。

这是一次权限收窄,方向正确:iframe 是隔离边界,凭「同一个进程」就继承能力,等于让边界失效。

三、扩展页面不再无条件注入预加载脚本

第三条也是收窄:

chrome-extension:// 文档过去在任何位置嵌入都会收到窗口的预加载脚本(以及会话预加载脚本)。现在只有作为顶层 frame,或托管在 DevTools 前端(devtools_page 或面板)里时才收到;嵌入普通页面的扩展 frame 按普通子 frame 处理,遵循 nodeIntegrationInSubFrames。

对一个装了第三方扩展的应用,这条很重要 —— 扩展页面过去是个「意外获得主世界权限」的入口。

Electron 的沙箱文档:预加载脚本能拿到什么

还有两条小变更

  • chromeMediaSource: 'desktop' 只接受 desktopCapturer.getSources 给出的屏幕 / 窗口 id。传 WebContents 的 id 会直接报 Invalid state。要抓某个 WebContents,得用 chromeMediaSource: 'tab' 配 webContents.getMediaSourceId(),或者走 setDisplayMediaRequestHandler。
  • 实验性的 contentTracing.enableHeapProfiling() 被移除。用它的项目基本只有做性能分析的工具,影响面小,但会直接编译失败。

升级建议

我的判断:45 是个「值得升但要排期」的版本。理由:

  1. Chromium 156 带来的安全修复是刚需,尤其是把 Electron 当浏览器用的产品(内嵌网页、第三方内容);
  2. 但三条破坏性变更都需要改代码 —— 沙箱 preload 的 polyfill、Worker 的权限判断、扩展页面的注入假设;
  3. 而 preload 的失败模式是静默的(页面正常、IPC 不通),必须有回归测试覆盖到「打开应用、点一个需要 IPC 的按钮」。

顺序上我会这么做:先在一个分支上升级,跑一遍所有 preload 的加载路径,再检查有没有 webviewTag 与 nodeIntegrationInSubFrames 的组合用法。这类版本的风险不在新特性,在老代码里那些「刚好能用」的假设。

Electron 的破坏性变更文档

顺带说一句版本节奏:45 是 stable,46 已经出了 alpha.1(10 月 23 日)。Electron 现在维持「每 8 周一个大版本」,跟着升级需要固定的时间预算 —— 不跟的话,半年后会同时面对三个大版本的变更。

← 返回文章列表

评论

…