Electron 重大更改

2023-02-16 17:17 更新

这里将记录重大更改,并在可能的情况下向JS代码添加弃用警告,在这更改之前至少会有一个重要版本.

重大更改的类型

本文档使用以下约定对重大更改进行分类:

  • API 更改:已更改的 API 会以某种方式使未更新的代码必定抛出异常。
  • 行为改变:Electron 的行为已经改变,但并不一定抛出相应的异常。
  • 默认值更改:依赖于默认值的代码的行为可能被破坏,但不保证会抛出相应的异常。 您可以通过显式指定该值的方式恢复旧的默认行为。
  • 已废弃:该 API 已标记为废弃。 该 API 依旧可正常运作,但会抛出已废弃警告,并在将来会移除。
  • 已移除:该 API 或功能已移除,Electron团队不再对此提供支持。

计划重写的 API (23.0)

已删除:BrowserWindow scroll-touch-* 事件

在 BrowserWindow 上已弃用的 scroll-touch-beginscroll-touch-end 和 scroll-touch-edge 事件已被删除。相反,使用 WebContents 上新提供的输入事件事件。

// Removed in Electron 23.0
win.on('scroll-touch-begin', scrollTouchBegin)
win.on('scroll-touch-edge', scrollTouchEdge)
win.on('scroll-touch-end', scrollTouchEnd)

// Replace with
win.webContents.on('input-event', (_, event) => {
  if (event.type === 'gestureScrollBegin') {
    scrollTouchBegin()
  } else if (event.type === 'gestureScrollUpdate') {
    scrollTouchEdge()
  } else if (event.type === 'gestureScrollEnd') {
    scrollTouchEnd()
  }
})

计划重写的 API (22.0)

已废弃: WebContents new-window 事件

WebContents 中的 new-window 事件已经被废弃。 已弃用:webContents.setWindowOpenHandler()

// Removed in Electron 21
webContents.on('new-window', (event) => {
  event.preventDefault()
})

// Replace with
webContents.setWindowOpenHandler((details) => {
  return { action: 'deny' }
})

已废弃:Browserwindow scroll-touch-* 事件

在 BrowserWindow 上已弃用的 scroll-touch-beginscroll-touch-end 和 scroll-touch-edge 事件已被删除。 相反,使用新的 input-event WebContents 上的事件。

// Deprecated
win.on('scroll-touch-begin', scrollTouchBegin)
win.on('scroll-touch-edge', scrollTouchEdge)
win.on('scroll-touch-end', scrollTouchEnd)

// Replace with
win.webContents.on('input-event', (_, event) => {
  if (event.type === 'gestureScrollBegin') {
    scrollTouchBegin()
  } else if (event.type === 'gestureScrollUpdate') {
    scrollTouchEdge()
  } else if (event.type === 'gestureScrollEnd') {
    scrollTouchEnd()
  }
})

计划重写的 API (21.0)

Behavior Changed: V8 Memory Cage enabled

V8 内存笼已启用,这对使用 ArrayBuffer 或 Buffer 包装非 V8 内存的本机模块有影响。

API Changed: webContents.printToPDF()

webContents.printToPDF() 已修改为符合 Chrome DevTools 协议中的 Page.printToPDF。这是为了解决上游的变化而进行的更改,这些更改使我们以前的实施变得站不住脚并且充满了错误。

参数更改

  • pageRanges

参数移除

  • printSelectionOnly
  • marginsType
  • headerFooter
  • scaleFactor

参数添加

  • headerTemplate
  • footerTemplate
  • displayHeaderFooter
  • margins
  • scale
  • preferCSSPageSize
// Main process
const { webContents } = require('electron')

webContents.printToPDF({
  landscape: true,
  displayHeaderFooter: true,
  printBackground: true,
  scale: 2,
  pageSize: 'Ledger',
  margins: {
    top: 2,
    bottom: 2,
    left: 2,
    right: 2
  },
  pageRanges: '1-5, 8, 11-13',
  headerTemplate: '<h1>Title</h1>',
  footerTemplate: '<div><span class="pageNumber"></span></div>',
  preferCSSPageSize: true
}).then(data => {
  fs.writeFile(pdfPath, data, (error) => {
    if (error) throw error
    console.log(`Wrote PDF successfully to ${pdfPath}`)
  })
}).catch(error => {
  console.log(`Failed to write PDF to ${pdfPath}: `, error)
})

计划重写的 API (20.0)

默认值被更改:默认情况下,渲染器不为 nodeIntegration: true 将进行沙盒处理

之前, 指定预加载脚本的渲染器默认不启用沙盒。 这意味着默认情况下,预加载脚本可以访问Node.js。 在 Electron 20中,此默认值将被更改。 从Electron 20开始,渲染器 默认情况下会被沙盒化,除非指定了 nodeIntegration: true 或 sandbox: false 。

如果预加载脚本不依赖于 Node,则无需执行任何操作。 如果 preload 脚本依赖于 Node,请重构代码,或从渲染器中删除 Node 用法 ,或者显式指定相关渲染器 sandbox: false 。

已删除:Linux 上的 skipTaskbar

在 X11上, skipTaskbar 向 X11 窗口管理器发送一条 _NET_WM_STATE_SKIP_TASKBAR 消息。 Wayland没有与其一致的功能,并且已知的 变通办法具有不可接受的理由(如,在GNOME中Window.is_skip_taskbar 需要不安全模式),因此Electron无法在Linux上支持此功能。

API Changed: session.setDevicePermissionHandler(handler)

当使用 session.setDevicePermissionHandler(handler) 时,调用的处理程序对其参数进行了更改。此处理程序不再传递框架 WebFrameMain,而是传递原点,这是检查设备权限的原点。

计划重写的 API (19.0)

已删除:IA32 Linux 二进制文件

这是由于Chromium 102.0.4999.0放弃了对IA32 Linux的支持。 因此,删除了对IA32 Linux 的支持。

计划重写的 API (18.0)

已移除: nativeWindowOpen

在 Electron 15之前, window.open 默认使用 BrowserWindowProxy。这意味着 window.open('about:blank') 无法打开可同步编写脚本的子窗口,以及其他不兼容性。自 Electron 15 起, nativeWindowOpen 将默认启用。

计划重写的 API (17.0)

已移除:渲染器中的 desktopCapturer.getSources

desktopCapturer.getSources API 现在仅在主进程中可用。 为了提高Electron 应用程序在默认情况下的安全性,已对此做了修改。

如果需要此功能,可以按如下方式替换它:

// 主进程
const { ipcMain, desktopCapturer } = require('electron')

ipcMain.handle(
  'DESKTOP_CAPTURER_GET_SOURCES',
  (event, opts) => desktopCapturer.getSources(opts)
)
// 渲染器进程
const { ipcRenderer } = require('electron')

const desktopCapturer = {
  getSources: (opts) => ipcRenderer.invoke('DESKTOP_CAPTURER_GET_SOURCES', opts)
}

然而,您应该考虑进一步限制返回到 渲染器的信息; 例如向用户显示源选择器并只 返回选定的源。

已废弃:nativeWindowOpen

在 Electron 15之前, window.open 默认使用 BrowserWindowProxy。这意味着 window.open('about:blank') 无法打开可同步编写脚本的子窗口,以及其他不兼容性。 自 Electron 15 起, nativeWindowOpen 将默认启用。

计划重写的 API (16.0)

Behavior Changed: crashReporter implementation switched to Crashpad on Linux

Linux上 crashReporter API的底层实现已经 从Breakpad更改为Crashpad,使其与Windows和Mac保持一致。 因此 子进程现在自动被监视, 且调用 process.crashReporter.start 在Node子进程中不再需要 (并且 不被建议,因为它将启动Crashpad报告器的二次实例) 。

在 Linux 上报告注释的方式也有一些细微的变化,包括长整型值将不再在附加 __1、 __2 等 附加的注释之间拆分,而是将在 (新的、更长的) 注释值限制处被截断。

已弃用:在渲染器中的 desktopCapturer.getSources

渲染器中 desktopCapturer.getSources API 的使用已被弃用,并将被删除。 此更改提高了 Electron 应用程序的默认安全性。

计划重写的 API (15.0)

默认更改: nativeWindowOpen 默认为 true

在 Electron 15之前, window.open 默认使用 BrowserWindowProxy。这意味着 window.open('about:blank') 无法打开可同步编写脚本的子窗口,以及其他不兼容性。 nativeWindowOpen 不再是实验性的,现在是默认的。

计划重写的 API (14.0)

Removed: remote module

remote 模块在 Electron 12 废弃,并将在 Electron 14 被移除. 由@electronic/remote 模块替代。

// 在 Electron 12 废除:
const { BrowserWindow } = require('electron').remote
// 替换为:
const { BrowserWindow } = require('@electron/remote')

// 在主进程中:
require('@electron/remote/main').initialize()

已移除: app.allowRendererProcessReuse

作为我们计划的一部分, app.allowRendererProcessReuse属性将被删除,以 与Chromium在安全性,性能和可维护性方面的流程模型更紧密地保持一致。

有关更多详细信息,请参阅 #18397.

Removed: Browser Window Affinity

构建新的 BrowserWindow 对象时的 affinity 选项将会被删除, 这一点将作为我们计划的一部分,以更紧密地与Chromium的流程模型保持一致,以实现安全性,高性能和可维护性。

有关更多详细信息,请参阅 #18397.

API 更改: window.open()

可选参数 frameName 将不再设置窗口的标题。 该功能现在遵循 原生文档 中的约束,由名为 windowName 的参数控制。

如果您正在使用此参数来设置窗口的标题,您可以使用 ​win.setTitle(title)​。

已移除: worldSafeExecuteJavaScript

在 Electron 14, worldSafeExecuteJavaScript 将被移除。 除此之外没有其他方式,请保证您的代码中包含该属性。 Electron 12中默认启用该属性。

若您使用了 webFrame.executeJavaScript 或 webFrame.executeJavaScriptInIsolatedWorld,这个改动会对您造成影响。 您将需要确保这些方法中任何一种返回的值都被 Context Bridge API 支持,因为这些方法使用相同的值传递语意。

Removed: BrowserWindowConstructorOptions inheriting from parent windows

在 Electron 14 之前,使用 window.open 打开的窗口将从其父窗口继承 BrowserWindow 构造函数选项,例如透明和可调整大小。从 Electron 14开始,此行为已被删除, 窗口将不会继承他们父窗口的任何 BrowserWindow constructor 选项。

相反,使用 setWindowOpenHandler 显式设置新窗口的选项:

webContents.setWindowOpenHandler((details) => {
  return {
    action: 'allow',
    overrideBrowserWindowOptions: {
      // ...
    }
  }
})

已移除: additionalFeatures

WebContents 的 new-window 和 did-create-window 事件中已弃用的 additionalFeatures 属性已被删除。由于 new-window 使用位置参数,参数仍然存在,但将始终是空数组 []。(但请注意, new-window 事件本身 已被弃用,取而代之的是 setWindowOpenHandler。)窗口功能中的裸键现在将在选项对象中显示为值为 true 的键。

// Removed in Electron 14
// Triggered by window.open('...', '', 'my-key')
webContents.on('did-create-window', (window, details) => {
  if (details.additionalFeatures.includes('my-key')) {
    // ...
  }
})

// Replace with
webContents.on('did-create-window', (window, details) => {
  if (details.options['my-key']) {
    // ...
  }
})

计划重写的 API (13.0)

API 更改: session.setPermissionCheckHandler(handler)

handler 方法的第一个参数曾是 webContents,但现在可以为 null。 为正确响应权限检查,您需要使用requestingOriginembeddingOrigin 和 securityOrigin 这些属性。 因为 webContents 现在可能为 null,您不应当依赖此参数。

// 旧代码
session.setPermissionCheckHandler((webContents, permission) => {
  if (webContents.getURL().startsWith('https://google.com/') && permission === 'notification') {
    return true
  }
  return false
})

// 变更为
session.setPermissionCheckHandler((webContents, permission, requestingOrigin) => {
  if (new URL(requestingOrigin).hostname === 'google.com' && permission === 'notification') {
    return true
  }
  return false
})

已移除:shell.moveItemToTrash()

已废弃的同步方法 shell.moveItemToTrash() 已移除。 作为替代,您应当使用异步的 shell.trashItem()

// 在 Electron 13 移除
shell.moveItemToTrash(path)
// 替换为
shell.trashItem(path).then(/* ... */)

已移除: BrowserWindow 扩展 API

移除已弃用的扩展 API:

  • BrowserWindow.addExtension(path)
  • BrowserWindow.addDevToolsExtension(path)
  • BrowserWindow.removeExtension(name)
  • BrowserWindow.removeDevToolsExtension(name)
  • BrowserWindow.getExtensions()
  • BrowserWindow.getDevToolsExtensions()

改为使用 session API:

  • ses.loadExtension(path)
  • ses.removeExtension(extension_id)
  • ses.getAllExtensions()
// 在 Electron 13 移除
BrowserWindow.addExtension(path)
BrowserWindow.addDevToolsExtension(path)
// 替换为
session.defaultSession.loadExtension(path)
// 在 Electron 13 移除
BrowserWindow.removeExtension(name)
BrowserWindow.removeDevToolsExtension(name)
// 替换为
session.defaultSession.removeExtension(extension_id)
// 在 Electron 13 移除
BrowserWindow.getExtensions()
BrowserWindow.getDevToolsExtensions()
// 替换为
session.defaultSession.getAllExtensions()

已移除: systemPreferences 中的方法

systemPreferences​ 方法已经被废弃:

  • systemPreferences.isDarkMode()
  • systemPreferences.isInvertedColorScheme()
  • systemPreferences.isHighContrastColorScheme()

使用 ​nativeTheme​ 属性作为替代:

  • nativeTheme.shouldUseDarkColors
  • nativeTheme.shouldUseInvertedColorScheme
  • nativeTheme.shouldUseHighContrastColors
// 在 Electron 13 移除
systemPreferences.isDarkMode()
// 替换为
nativeTheme.shouldUseDarkColors

// 在 Electron 13 移除
systemPreferences.isInvertedColorScheme()
// 替换为
nativeTheme.shouldUseInvertedColorScheme

// 在 Electron 13 移除
systemPreferences.isHighContrastColorScheme()
// 替换为
nativeTheme.shouldUseHighContrastColors

已废弃: WebContents new-window 事件

WebContents 中的 new-window 事件已经被废弃。 已弃用:webContents.setWindowOpenHandler()

// 在 Electron 13 废弃
webContents.on('new-window', (event) => {
  event.preventDefault()
})

// 替换为
webContents.setWindowOpenHandler((details) => {
  return { action: 'deny' }
})

Planned Breaking API Changes (12.0)

已移除:Pepper Flash 支持

Chromium 已经取消了对Flash的支持,因此我们必须效仿。 更多详细信息,请参阅 Chromium 的 Flash Roadmap

默认更改: worldSafeExecuteJavaScript 默认为 true

在 Electron 12, worldSafeExecuteJavaScript 将默认启用。 要恢复 上一个行为, worldSafeExecuteJavaScript: false 必须在 Web 首选项中指定。 请注意,设置此选项为 false 是不安全的。

此选项将在 Electron 14 中删除,所以请迁移您的代码以支持默认值。

默认更改:contextIsolation 默认为 true

在 Electron 12 中,contextIsolation 将默认启用。 要恢复 上一个行为, contextIsolation: false 必须在 Web 首选项中指定。

我们建议启用 contextIsolation 以确保应用程序的安全。

另一个含义是 require() 不能在 renderer process 中使用,除非 nodeIntegration 是 true 和 contextIsolation 是 false.

更多信息请参阅:https://github.com/electron/electron/issues/23506

Removed: crashReporter.getCrashesDirectory()

crashReporter.getCrashesDirectory 方法已被删除。 这个方法 应该被 app.getPath('crashDumps')替换。

// 在 Electron 12 移除
crashReporter.getCrashesDirectory()
// 替换为
app.getPath('crashDumps')

已移除:渲染进程中的 crashReporter 方法

crashReporter 方法在渲染进程中不再能使用:

  • crashReporter.start
  • crashReporter.getLastCrashReport
  • crashReporter.getUploadedReports
  • crashReporter.getUploadToServer
  • crashReporter.setUploadToServer
  • crashReporter.getCrashesDirectory

它们只应从主要进程中调用。

更多详细信息请访问 #23265

默认值已更改:crashReporter.start({ compress: true })

crashReporter.start 中的 compress 选项的默认值已经从 false 改为 true。 这意味着崩溃 dumps 将使用 Content-Encoding: gzip header,上传到崩溃服务器,并进行压缩。

如果 crash 服务器不支持压缩负载,则可以通过在 crash reporter 选项中指定 { compress: false } 来 关闭压缩。

已废弃: remote 模块

remote 模块在 Electron 12 废弃,并将在 Electron 14 被移除 由@electronic/remote 模块替代。

// 在 Electron 12 废除:
const { BrowserWindow } = require('electron').remote
// 替换为:
const { BrowserWindow } = require('@electron/remote')

// 在主进程中:
require('@electron/remote/main').initialize()

已废弃:shell.moveItemToTrash()

新的异步shell.trashItem()方法替代了同步的shell.moveItemToTrash()方法。

// 在 Electron 12 废弃
shell.moveItemToTrash(path)
// 替换为
shell.trashItem(path).then(/* ... */)

Planned Breaking API Changes (11.0)

移除: BrowserView 中的 BrowserView.{destroy, fromId, fromWebContents, getAllViews} 和 id 属性

实验性 API BrowserView.{destroy, fromId, fromWebContents, getAllViews} 现已被移除。 此外, BrowserView 中的 id 属性也已被移除。

更多信息见 #23578

Planned Breaking API Changes (10.0)

已废弃:crashReporter.start() 中的 companyName 参数

crashReporter.start() 中的 companyName 参数之前是必选的,现在是可选的,并且在未来将会被废弃。 如果要以不推荐的方式获得相同的行为,可以在 globalExtra 中传递 companyName 值。

// 在 Electron 10 废除
crashReporter.start({ companyName: 'Umbrella Corporation' })
// 替换为
crashReporter.start({ globalExtra: { _companyName: 'Umbrella Corporation' } })

已废弃:crashReporter.getCrashesDirectory()

crashReporter.getCrashesDirectory 方法已经被废除。 这个方法 应该被 app.getPath('crashDumps')替换。

// 在 Electron 10 废除
crashReporter.getCrashesDirectory()
// 替换为
app.getPath('crashDumps')

已废弃:渲染进程中的 crashReporter 方法

从 renderer process 调用 crashReporter,已经被废弃

  • crashReporter.start
  • crashReporter.getLastCrashReport
  • crashReporter.getUploadedReports
  • crashReporter.getUploadToServer
  • crashReporter.setUploadToServer
  • crashReporter.getCrashesDirectory

在渲染器的 crashReporter 模块中,未弃用的方法是 addExtraParameter、 removeExtraParameter 和 getParameters

当从主要进程调用时,上述所有方法均未被弃用。

更多详细信息请访问 #23265

已废弃:crashReporter.start({ compress: false })

不推荐在 crashReporter.start 中设置 { compress: false } 几乎所有的 crash 服务器都支持 gzip 压缩。 此选项将在未来版本的 Electron 中删除。

默认更改: enableRemoteModule 默认为 false

在 Electron 9,如果不在 WebPreferences 中显式开启 enableRemoteModule 参数,就使用 remote 模块,将会开始发出警告。 在 Electron 10 中,remote 模块默认处于禁用状态。 如果要使用 remote 模块,必须在 WebPreferences 中指定 enableRemoteModule: true :

const w = new BrowserWindow({
  webPreferences: {
    enableRemoteModule: true
  }
})

我们 建议远离 remote 模块

protocol.unregisterProtocol

protocol.uninterceptProtocol

这些 APIs 现在是同步的,不再需要可选的回调。

// 已废弃
protocol.unregisterProtocol(scheme, () => { /* ... */ })
// 替换为
protocol.unregisterProtocol(scheme)

protocol.registerFileProtocol

protocol.registerBufferProtocol

protocol.registerStringProtocol

protocol.registerHttpProtocol

protocol.registerStreamProtocol

protocol.interceptFileProtocol

protocol.interceptStringProtocol

protocol.interceptBufferProtocol

protocol.interceptHttpProtocol

protocol.interceptStreamProtocol

这些 APIs 现在是同步的,不再需要可选的回调。

// 已废弃
protocol.registerFileProtocol(scheme, handler, () => { /* ... */ })
// 替换为
protocol.registerFileProtocol(scheme, handler)

在导航发生之前,注册或拦截的 protocol 不会对当前页面产生影响。

protocol.isProtocolHandled

此 API 已废弃,用户应该使用 protocol.isProtocolRegistered 和 protocol.isProtocolIntercepted

// 废弃
protocol.isProtocolHandled(scheme).then(() => { /* ... */ })
// 替换为
const isRegistered = protocol.isProtocolRegistered(scheme)
const isIntercepted = protocol.isProtocolIntercepted(scheme)

计划重写的 API (9.0)

默认更改:默认在 renderer process 中禁用加载 non-context-aware native modules

从Electron 9开始,我们不允许在 renderer process 加载 non-context-aware native modules。 这是为了提高 Electron 作为一个项目的安全性、性能性和维护性。

如果这对你有影响,你可以临时将 app.allowRendererProcessReuse 设置为 false,这将恢复到旧的行为。 在 Electron 11 之前,此标志只是一个选项,因此你应该计划更换你的 native modules 模块,已进行 context aware。

有关更多详细信息,请参阅 #18397.

已废弃: BrowserWindow 扩展 API

以下扩展 APIs 已废弃:

  • BrowserWindow.addExtension(path)
  • BrowserWindow.addDevToolsExtension(path)
  • BrowserWindow.removeExtension(name)
  • BrowserWindow.removeDevToolsExtension(name)
  • BrowserWindow.getExtensions()
  • BrowserWindow.getDevToolsExtensions()

改为使用 session API:

  • ses.loadExtension(path)
  • ses.removeExtension(extension_id)
  • ses.getAllExtensions()
// 在 Electron 9 废弃
BrowserWindow.addExtension(path)
BrowserWindow.addDevToolsExtension(path)
// 替换为
session.defaultSession.loadExtension(path)
// 在 Electron 9 废弃
BrowserWindow.removeExtension(name)
BrowserWindow.removeDevToolsExtension(name)
// 替换为
session.defaultSession.removeExtension(extension_id)
// 在 Electron 9 废弃
BrowserWindow.getExtensions()
BrowserWindow.getDevToolsExtensions()
// 替换为
session.defaultSession.getAllExtensions()

已移除: <webview>.getWebContents()

此API在 Electron 8.0中被废弃,现已删除。

// 在 Electron 9.0 移除
webview.getWebContents()
// 替换为
const { remote } = require('electron')
remote.webContents.fromId(webview.getWebContentsId())

已移除:webFrame.setLayoutZoomLevelLimits()

Chromium 已经取消了对更改布局缩放级别限制的支持,它超出了 Electron 维护它的能力。 此函数在 Electron 8.x 废弃,并将在 Electron 9.x 被移除。 布局缩放级别限制现在已固定为最小 0.25 最大 5.0,定义在: 这里

行为改变: 通过 IPC 发送非 JS 对象,现在将引发异常

在 Electron 8.0 中, IPC 被更改为使用结构化克隆算法(Structured Clone Algorithm),显著提高了性能。 为了帮助简化转换,保留了旧的 IPC 序列化算法,并将其用于一些无法通过结构化克隆序列化的对象。 特别是 DOM 对象(例如:ElementLocationDOMMatrix),Node.js 中由 C++ 类支持的对象(例如:process.envStream 中的一些方法),和 Electron 中由 C++ 类支持的对象(例如:WebContentsBrowserWindowWebFrame)无法使用使用结构化克隆序列化。 每当调用到旧算法时,都会打印弃用警告。

在 Electron 9 中,旧的序列化算法已被删除,并且此类不可序列化的对象现在将会抛出一个“object could not be cloned”(对象无法被克隆) 错误。

API 变化:shell.openItem 变化为 shell.openPath

shell.openItem API 已被替换成异步的 shell.openPath API。 你可以在这里查看原始 API 提案和推理

计划重写的 API (8.0)

行为改变:通过 IPC 发送的值现在已经使用结构化克隆(Structured Clone Algorithm)算法进行序列化。

用于序列化通过 IPC 发送的对象(通过 ipcRenderer.sendipcRenderer.sendSyncWebContents.send 以及相关方法)已经从自定义算法切换到 V8 内置的 结构化克隆算法,和 postMessage 使用序列化消息的算法相同。 这将为大型消息带来了 2 倍的性能改进,但也带来一些行为上的重大变化。

  • 通过 IPC 发送的 Function、Promise、WeakMaps、WeakSets 或者包含任何此类值的对象现在将引发异常,而不是静默地将函数转换为 ​undefined
// 之前:
ipcRenderer.send('channel', { value: 3, someFunction: () => {} })
// => results in { value: 3 } arriving in the main process

// 从 Electron 8 开始:
ipcRenderer.send('channel', { value: 3, someFunction: () => {} })
// => throws Error("() => {} could not be cloned.")
  • NaNInfinity-Infinity 现在将被正确的序列化,而不是转换为 null
  • 包含循环引用的对象现在将被正确的序列化,而不是转换为 null
  • SetMapErrorRegExp 值将被正确的序列化,而不是转换为 {}
  • BigInt 值将被正确的序列化,而不是转换为 null
  • Sparse 数组将按照本身去序列化,而不是转换为具有 null 的数组。
  • Date 对象将被转换成 Date 对象,而不是转换成 ISO 字符串表达形式。
  • 类型化数组(例如 ​Uint8Array​、​Uint16Array​、​Uint32Array​ 等)将按原样传输,而不是转换为 Node.js 缓冲区。

  • Node.js Buffer 对象将作为 ​Uint8Arrays​ 传输。您可以通过包装底层 ArrayBuffer 将 ​Uint8Array​ 转换回 Node.js 缓冲区:

Buffer.from(value.buffer, value.byteOffset, value.byteLength)

发送任何非原生 JS 类型的对象,例如 DOM 对象(例如 Element、Location、DOMMatrix)、Node.js 对象(例如 process.env、Stream)或 Electron 对象(例如 WebContents、BrowserWindow、WebFrame)已被弃用.在 Electron 8 中,这些对象将像以前一样使用 DeprecationWarning 消息进行序列化,但从 Electron 9 开始,发送这些类型的对象将抛出“无法克隆”错误。

已废弃: <webview>.getWebContents()

该 API 是使用 remote 模块实现的,它同时具有性能和安全隐患。因此它的用法应该是明确的。

// Deprecated
webview.getWebContents()
// Replace with
const { remote } = require('electron')
remote.webContents.fromId(webview.getWebContentsId())

然而,建议完全避免使用 remote 模块

// main
const { ipcMain, webContents } = require('electron')

const getGuestForWebContents = (webContentsId, contents) => {
  const guest = webContents.fromId(webContentsId)
  if (!guest) {
    throw new Error(`Invalid webContentsId: ${webContentsId}`)
  }
  if (guest.hostWebContents !== contents) {
    throw new Error('Access denied to webContents')
  }
  return guest
}

ipcMain.handle('openDevTools', (event, webContentsId) => {
  const guest = getGuestForWebContents(webContentsId, event.sender)
  guest.openDevTools()
})

// renderer
const { ipcRenderer } = require('electron')

ipcRenderer.invoke('openDevTools', webview.getWebContentsId())

Deprecated: webFrame.setLayoutZoomLevelLimits()

Chromium 已经取消了对更改布局缩放级别限制的支持,它超出了 Electron 维护它的能力。 该函数将在 Electron 8.x 中发出警告,并在 Electron 9.x 中不复存在。布局缩放级别限制现在固定为最小 0.25 和最大 5.0,如此处所定义。

Deprecated events in systemPreferences

systemPreferences 事件已经被废弃:

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

改用 nativeTheme 模块上的新更新事件。

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

// Replace with
nativeTheme.on('updated', () => { /* ... */ })

已废弃:systemPreferences 中的方法

systemPreferences 方法已经被废弃:

  • systemPreferences.isDarkMode()
  • systemPreferences.isInvertedColorScheme()
  • systemPreferences.isHighContrastColorScheme()

使用 ​nativeTheme​ 属性作为替代:

  • nativeTheme.shouldUseDarkColors
  • nativeTheme.shouldUseInvertedColorScheme
  • nativeTheme.shouldUseHighContrastColors
// 已废弃
systemPreferences.isDarkMode()
// 替换为
nativeTheme.shouldUseDarkColors

// 已废弃
systemPreferences.isInvertedColorScheme()
// 替换为
nativeTheme.shouldUseInvertedColorScheme

// 已废弃
systemPreferences.isHighContrastColorScheme()
// 替换为
nativeTheme.shouldUseHighContrastColors

重大的API更新 (7.0)

Deprecated: Atom.io Node Headers URL

这是在构建原生 node 模块时在 .npmrc 文件中指定为 disturl 的 url 或是 --dist-url 命令行标志. Both will be supported for the foreseeable future but it is recommended that you switch.

Deprecated: https://atom.io/download/electron

Replace with: https://electronjs.org/headers

API Changed: session.clearAuthCache() no longer accepts options

session.clearAuthCache​ API 不再接受清除内容的选项,而是无条件清除整个缓存。

// Deprecated
session.clearAuthCache({ type: 'password' })
// Replace with
session.clearAuthCache()

API Changed: powerMonitor.querySystemIdleState is now powerMonitor.getSystemIdleState

// Removed in Electron 7.0
powerMonitor.querySystemIdleState(threshold, callback)
// Replace with synchronous API
const idleState = powerMonitor.getSystemIdleState(threshold)

API Changed: powerMonitor.querySystemIdleTime is now powerMonitor.getSystemIdleTime

// Removed in Electron 7.0
powerMonitor.querySystemIdleTime(callback)
// Replace with synchronous API
const idleTime = powerMonitor.getSystemIdleTime()

API Changed: webFrame.setIsolatedWorldInfo replaces separate methods

// Removed in Electron 7.0
webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp)
webFrame.setIsolatedWorldHumanReadableName(worldId, name)
webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin)
// Replace with
webFrame.setIsolatedWorldInfo(
  worldId,
  {
    securityOrigin: 'some_origin',
    name: 'human_readable_name',
    csp: 'content_security_policy'
  })

Removed: marked property on getBlinkMemoryInfo

此属性在 Chromium 77 中已被删除,因此不再可用。

Behavior Changed: webkitdirectory attribute for <input type="file"/> now lists directory contents

HTML 文件输入的 webkitdirectory 属性允许他们选择文件夹。 Electron 的早期版本有一个不正确的实现,其中输入的 event.target.files 返回一个 FileList,该 FileList 返回一个与所选文件夹对应的文件。

从 Electron 7 开始,该 FileList 现在是文件夹中包含的所有文件的列表,类似于 Chrome、Firefox 和 Edge(链接到 MDN 文档)。

作为说明,以具有以下结构的文件夹为例:

folder
├── file1
├── file2
└── file3

在 Electron <=6 中,这将返回一个 FileList 与一个 File 对象:

path/to/folder

在 Electron 7 中,这现在返回一个 FileList 和一个 File 对象:

/path/to/folder/file3
/path/to/folder/file2
/path/to/folder/file1

请注意,webkitdirectory 不再公开所选文件夹的路径。

API Changed: Callback-based versions of promisified APIs

Electron 5 和 Electron 6 引入了现有异步 API 的基于 Promise 的版本,并弃用了它们较旧的基于回调的对应版本。在 Electron 7 中,所有已弃用的基于回调的 API 现已被删除。

这些函数现在只返回 Promises:

  • app.getFileIcon() #15742
  • app.dock.show() #16904
  • contentTracing.getCategories() #16583
  • contentTracking.getTraceBufferUs() #16600
  • contentTracing.startRecording() #16584
  • contentTracing.stopRecording() #16584
  • contents.executeJavaScript() #17312
  • cookies.flushStore() #16464
  • cookies.get() #16464
  • cookies.remove() #16464
  • cookies.set() #16464
  • debugger.sendCommand() #16861
  • dialog.showCertificateTrustDialog() #17181
  • inAppPurchase.getProducts() #17355
  • inAppPurchase.purchaseProduct()#17355
  • netLog.stopLogging() #16862
  • session.clearAuthCache() #17259
  • session.clearCache() #17185
  • session.clearHostResolverCache() #17229
  • session.clearStorageData() #17249
  • session.getBlobData() #17303
  • session.getCacheSize() #17185
  • session.resolveProxy() #17222
  • session.setProxy() #17222
  • shell.openExternal() #16176
  • webContents.loadFile() #15855
  • webContents.loadURL() #15855
  • webContents.hasServiceWorker() #16535
  • webContents.printToPDF() #16795
  • webContents.savePage() #16742
  • webFrame.executeJavaScript() #17312
  • webFrame.executeJavaScriptInIsolatedWorld() #17312
  • webviewTag.executeJavaScript() #17312
  • win.capturePage() #15743

这些功能现在有两种形式,即同步和基于Promise的异步:

  • dialog.showMessageBox()/dialog.showMessageBoxSync() #17298
  • dialog.showOpenDialog()/dialog.showOpenDialogSync() #16973
  • dialog.showSaveDialog()/dialog.showSaveDialogSync() #17054

重大的API更新 (6.0)

API Changed: win.setMenu(null) is now win.removeMenu()

// 不推荐
win.setMenu(null)
// 替换为
win.removeMenu()

API Changed: electron.screen in the renderer process should be accessed via remote

// 不推荐
require('electron').screen
// 替换为
require('electron').remote.screen

API Changed: require()ing node builtins in sandboxed renderers no longer implicitly loads the remote version

// 不推荐
require('child_process')
// 替换为
require('electron').remote.require('child_process')

// 不推荐
require('fs')
// 替换为
require('electron').remote.require('fs')

// 不推荐
require('os')
// 替换为
require('electron').remote.require('os')

// 不推荐
require('path')
// 替换为
require('electron').remote.require('path')

Deprecated: powerMonitor.querySystemIdleState replaced with powerMonitor.getSystemIdleState

// 废弃
powerMonitor.querySystemIdleState(threshold, callback)
// 替换为 synchronous API
const idleState = powerMonitor.getSystemIdleState(threshold)

Deprecated: powerMonitor.querySystemIdleTime replaced with powerMonitor.getSystemIdleTime

// 废弃
powerMonitor.querySystemIdleTime(callback)
// 替换为 synchronous API
const idleTime = powerMonitor.getSystemIdleTime()

Deprecated: app.enableMixedSandbox() is no longer needed

// 废弃
app.enableMixedSandbox()

混合沙盒模式已默认启用。

Deprecated: Tray.setHighlightMode

在 macOS Catalina 下,我们之前的 Tray 实现中断了。 Apple 的原生替代品不支持更改突出显示行为。

// 废弃
tray.setHighlightMode(mode)
// API will be removed in v7.0 without replacement.

重大的API更新 (5.0)

Default Changed: nodeIntegration and webviewTag default to false, contextIsolation defaults to true

不推荐使用以下 webPreferences 选项默认值,以支持下面列出的新默认值。

属性 不推荐使用的默认值 新的默认值
contextIsolation false true
nodeIntegration true false
webviewTag nodeIntegration 未设置过则是 true false

如下: 重新开启 webviewTag

const w = new BrowserWindow({
  webPreferences: {
    webviewTag: true
  }
})

Behavior Changed: nodeIntegration in child windows opened via nativeWindowOpen

使用 nativeWindowOpen 选项打开的子窗口将始终禁用 Node.js 集成,除非 nodeIntegrationInSubFrames 为真。

API Changed: Registering privileged schemes must now be done before app ready

渲染器进程 API webFrame.registerURLSchemeAsPrivileged 和 webFrame.registerURLSchemeAsBypassingCSP 以及浏览器进程 API protocol.registerStandardSchemes 已被删除。新的 API protocol.registerSchemeasviliged 已被添加,并用于注册具有必要权限的自定义 scheme。 自定义 scheme 需要在 app 触发 ready 事件之前注册。

已废弃: webFrame.setIsolatedWorld* 已替换为 webFrame.setIsolatedWorldInfo

// 弃用
webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp)
webFrame.setIsolatedWorldHumanReadableName(worldId, name)
webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin)
// 替换为
webFrame.setIsolatedWorldInfo(
  worldId,
  {
    securityOrigin: 'some_origin',
    name: 'human_readable_name',
    csp: 'content_security_policy'
  })

API Changed: webFrame.setSpellCheckProvider now takes an asynchronous callback

spellCheck 回调现在是异步的,并且 autoCorrectWord 参数已被删除。

// Deprecated
webFrame.setSpellCheckProvider('en-US', true, {
  spellCheck: (text) => {
    return !spellchecker.isMisspelled(text)
  }
})
// Replace with
webFrame.setSpellCheckProvider('en-US', {
  spellCheck: (words, callback) => {
    callback(words.filter(text => spellchecker.isMisspelled(text)))
  }
})

API Changed: webContents.getZoomLevel and webContents.getZoomFactor are now synchronous

webContents.getZoomLevel 和 webContents.getZoomFactor 不再接受回调参数,而是直接返回它们的数值。

// 废弃
webContents.getZoomLevel((level) => {
  console.log(level)
})
// 替换成
const level = webContents.getZoomLevel()
console.log(level)
// 废弃
webContents.getZoomFactor((factor) => {
  console.log(factor)
})
// 替换成
const factor = webContents.getZoomFactor()
console.log(factor)

计划重写的 API (4.0)

以下列表包含了Electron4.0中重大的API更新

app.makeSingleInstance

// 已废弃
app.makeSingleInstance((argv, cwd) => {
  /* ... */
})
// 替换为
app.requestSingleInstanceLock()
app.on('second-instance', (event, argv, cwd) => {
  /* ... */
})

app.releaseSingleInstance

// 废弃
app.releaseSingleInstance()
// 替换为
app.releaseSingleInstanceLock()

app.getGPUInfo

app.getGPUInfo('complete')
// 现在的行为将与macOS下的`basic`设置一样
app.getGPUInfo('basic')

win_delay_load_hook

在为 Windows 构建本机模块时,将使 win_delay_load_hook 变量值 位于 binding.gyp 模块,必须为 true (这是默认值)。 如果这个钩子 不存在,那么本机模块将无法在 Windows 上加载,并出现错误 消息如 无法找到模块

移除: IA32 Linux 支持

Electron 18 将不再支持在 32 位 Linux 系统上运行。

重大的API更新 (3.0)

以下包含了Electron 3.0中重大的API更新

app

// 弃用
app.getAppMemoryInfo()
// 替换为
app.getAppMetrics()

// 弃用
const metrics = app.getAppMetrics()
const { memory } = metrics[0] // 弃用的属性

BrowserWindow

// 已废弃
const optionsA = { webPreferences: { blinkFeatures: '' } }
const windowA = new BrowserWindow(optionsA)
// 替换为
const optionsB = { webPreferences: { enableBlinkFeatures: '' } }
const windowB = new BrowserWindow(optionsB)

// 已废弃
window.on('app-command', (e, cmd) => {
  if (cmd === 'media-play_pause') {
    // do something
  }
})
// 替换为
window.on('app-command', (e, cmd) => {
  if (cmd === 'media-play-pause') {
    // do something
  }
})

clipboard

// 过时的
clipboard.readRtf()
// 替换为
clipboard.readRTF()

// 过时的
clipboard.writeRtf()
// 替换为
clipboard.writeRTF()

// 过时的
clipboard.readHtml()
// 替换为
clipboard.readHTML()

// 过时的
clipboard.writeHtml()
//替换为
clipboard.writeHTML()

crashReporter

// 过时的
crashReporter.start({
  companyName: 'Crashly',
  submitURL: 'https://crash.server.com',
  autoSubmit: true
})
// 替换为
crashReporter.start({
  companyName: 'Crashly',
  submitURL: 'https://crash.server.com',
  uploadToServer: true
})

nativeImage

// 弃用
nativeImage.createFromBuffer(buffer, 1.0)
// 替换为
nativeImage.createFromBuffer(buffer, {
  scaleFactor: 1.0
})

process

// 弃用
const info = process.getProcessMemoryInfo()

screen

// 弃用
screen.getMenuBarHeight()
// 替换为
screen.getPrimaryDisplay().workArea

session

// 弃用
ses.setCertificateVerifyProc((hostname, certificate, callback) => {
  callback(true)
})
// 替换为
ses.setCertificateVerifyProc((request, callback) => {
  callback(0)
})

Tray

// 过时的
tray.setHighlightMode(true)
// 替换为
tray.setHighlightMode('on')

// 过时的
tray.setHighlightMode(false)
// 替换为
tray.setHighlightMode('off')

webContents

// 弃用
webContents.openDevTools({ detach: true })
// 替换为
webContents.openDevTools({ mode: 'detach' })

// 移除
webContents.setSize(options)
// 没有该API的替代

webFrame

// 弃用
webFrame.registerURLSchemeAsSecure('app')
// 替换为
protocol.registerStandardSchemes(['app'], { secure: true })

// 弃用
webFrame.registerURLSchemeAsPrivileged('app', { secure: true })
// 替换为
protocol.registerStandardSchemes(['app'], { secure: true })

<webview>

// 移除
webview.setAttribute('disableguestresize', '')
// 没有该API的替代

// 移除
webview.setAttribute('guestinstance', instanceId)
// 没有该API的替代

// 键盘监听器在webview标签中不再起效
webview.onkeydown = () => { /* handler */ }
webview.onkeyup = () => { /* handler */ }

Node Headers URL

这是在构建原生 node 模块时在 .npmrc 文件中指定为 disturl 的 url 或是 --dist-url 命令行标志.

过时的: https://atom.io/download/atom-shell

替换为: https://atom.io/download/electron

重大的API更新 (2.0)

以下包含了Electron 2.0中重大的API更新

BrowserWindow

// 已废弃
const optionsA = { titleBarStyle: 'hidden-inset' }
const windowA = new BrowserWindow(optionsA)
// 替换为
const optionsB = { titleBarStyle: 'hiddenInset' }
const windowB = new BrowserWindow(optionsB)

menu

// 移除
menu.popup(browserWindow, 100, 200, 2)
// 替换为
menu.popup(browserWindow, { x: 100, y: 200, positioningItem: 2 })

nativeImage

// 移除
nativeImage.toPng()
// 替换为
nativeImage.toPNG()

// 移除
nativeImage.toJpeg()
// 替换为
nativeImage.toJPEG()

process

  • process.versions.electronprocess.version.chrome 将成为只读属性, 以便与其他 process.versions 属性由Node设置。

webContents

// 移除
webContents.setZoomLevelLimits(1, 2)
// 替换为
webContents.setVisualZoomLevelLimits(1, 2)

webFrame

// 被废弃
webFrame.setZoomLevelLimits(1, 2)
// 替换为
webFrame.setVisualZoomLevelLimits(1, 2)

<webview>

// 移除
webview.setZoomLevelLimits(1, 2)
// 替换为
webview.setVisualZoomLevelLimits(1, 2)

重复的 ARM 资源

每个 Electron 发布版本包含两个相同的ARM版本,文件名略有不同,如electron-v1.7.3-linux-arm.zip 和 electron-v1.7.3-linux-armv7l.zip 添加包含v7l前缀的资源向用户明确其支持的ARM版本,并消除由未来armv6l 和 arm64 资源可能产生的歧义。

没有前缀的文件仍在发布,以避免破坏可能使用它的任何设置。从2.0版本起,不带前缀的文件将不再发布。

更多详细情况,查看 6986 和 7189


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号