重大更改

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

Types of Breaking Changes

This document uses the following convention to categorize breaking changes:

  • API Changed: An API was changed in such a way that code that has not been updated is guaranteed to throw an exception.
  • Behavior Changed: The behavior of Electron has changed, but not in such a way that an exception will necessarily be thrown.
  • Default Changed: Code depending on the old default may break, not necessarily throwing an exception. The old behavior can be restored by explicitly specifying the value.
  • Deprecated: An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
  • Removed: An API or feature was removed, and is no longer supported by Electron.

Planned Breaking API Changes (10.0)

Removed: Browser Window Affinity

The affinity option when constructing a new BrowserWindow will be removed as part of our plan to more closely align with Chromiums process model for security, performance and maintainability.

For more detailed information see #18397.

Default Changed: enableRemoteModule defaults to false

In Electron 9, using the remote module without explicitly enabling it via the enableRemoteModule WebPreferences option began emitting a warning. In Electron 10, the remote module is now disabled by default. To use the remote module, enableRemoteModule: true must be specified in WebPreferences:

  1. const w = new BrowserWindow({
  2. webPreferences: {
  3. enableRemoteModule: true
  4. }
  5. })

We recommend moving away from the remote module.

Planned Breaking API Changes (9.0)

Default Changed: Loading non-context-aware native modules in the renderer process is disabled by default

As of Electron 9 we do not allow loading of non-context-aware native modules in the renderer process. This is to improve security, performance and maintainability of Electron as a project.

If this impacts you, you can temporarily set app.allowRendererProcessReuse to false to revert to the old behavior. This flag will only be an option until Electron 11 so you should plan to update your native modules to be context aware.

For more detailed information see #18397.

Removed: <webview>.getWebContents()

This API, which was deprecated in Electron 8.0, is now removed.

  1. // Removed in Electron 9.0
  2. webview.getWebContents()
  3. // Replace with
  4. const { remote } = require('electron')
  5. remote.webContents.fromId(webview.getWebContentsId())

Removed: webFrame.setLayoutZoomLevelLimits()

Chromium has removed support for changing the layout zoom level limits, and it is beyond Electron’s capacity to maintain it. The function was deprecated in Electron 8.x, and has been removed in Electron 9.x. The layout zoom level limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined here.

Behavior Changed: Sending non-JS objects over IPC now throws an exception

In Electron 8.0, IPC was changed to use the Structured Clone Algorithm, bringing significant performance improvements. To help ease the transition, the old IPC serialization algorithm was kept and used for some objects that aren’t serializable with Structured Clone. In particular, DOM objects (e.g. Element, Location and DOMMatrix), Node.js objects backed by C++ classes (e.g. process.env, some members of Stream), and Electron objects backed by C++ classes (e.g. WebContents, BrowserWindow and WebFrame) are not serializable with Structured Clone. Whenever the old algorithm was invoked, a deprecation warning was printed.

In Electron 9.0, the old serialization algorithm has been removed, and sending such non-serializable objects will now throw an “object could not be cloned” error.

API Changed: shell.openItem is now shell.openPath

The shell.openItem API has been replaced with an asynchronous shell.openPath API. You can see the original API proposal and reasoning here.

计划重写的 API (8.0)

Behavior Changed: Values sent over IPC are now serialized with Structured Clone Algorithm

The algorithm used to serialize objects sent over IPC (through ipcRenderer.send, ipcRenderer.sendSync, WebContents.send and related methods) has been switched from a custom algorithm to V8’s built-in Structured Clone Algorithm, the same algorithm used to serialize messages for postMessage. This brings about a 2x performance improvement for large messages, but also brings some breaking changes in behavior.

  • Sending Functions, Promises, WeakMaps, WeakSets, or objects containing any such values, over IPC will now throw an exception, instead of silently converting the functions to undefined.
    ```js
    // Previously:
    ipcRenderer.send(‘channel’, { value: 3, someFunction: () => {} })
    // => results in { value: 3 } arriving in the main process

// From Electron 8:
ipcRenderer.send(‘channel’, { value: 3, someFunction: () => {} })
// => throws Error(“() => {} could not be cloned.”)

  1. - `NaN`, `Infinity` and `-Infinity` will now be correctly serialized, instead of being converted to `null`.
  2. - Objects containing cyclic references will now be correctly serialized, instead of being converted to `null`.
  3. - `Set`, `Map`, `Error` and `RegExp` values will be correctly serialized, instead of being converted to `{}`.
  4. - `BigInt` values will be correctly serialized, instead of being converted to `null`.
  5. - Sparse arrays will be serialized as such, instead of being converted to dense arrays with `null`s.
  6. - `Date` objects will be transferred as `Date` objects, instead of being converted to their ISO string representation.
  7. - Typed Arrays (such as `Uint8Array`, `Uint16Array`, `Uint32Array` and so on) will be transferred as such, instead of being converted to Node.js `Buffer`.
  8. - Node.js `Buffer` objects will be transferred as `Uint8Array`s. You can convert a `Uint8Array` back to a Node.js `Buffer` by wrapping the underlying `ArrayBuffer`:
  9. ```js
  10. Buffer.from(value.buffer, value.byteOffset, value.byteLength)

Sending any objects that aren’t native JS types, such as DOM objects (e.g. Element, Location, DOMMatrix), Node.js objects (e.g. process.env, Stream), or Electron objects (e.g. WebContents, BrowserWindow, WebFrame) is deprecated. In Electron 8, these objects will be serialized as before with a DeprecationWarning message, but starting in Electron 9, sending these kinds of objects will throw a ‘could not be cloned’ error.

Deprecated: <webview>.getWebContents()

This API is implemented using the remote module, which has both performance and security implications. Therefore its usage should be explicit.

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

However, it is recommended to avoid using the remote module altogether.

  1. // main
  2. const { ipcMain, webContents } = require('electron')
  3. const getGuestForWebContents = (webContentsId, contents) => {
  4. const guest = webContents.fromId(webContentsId)
  5. if (!guest) {
  6. throw new Error(`Invalid webContentsId: ${webContentsId}`)
  7. }
  8. if (guest.hostWebContents !== contents) {
  9. throw new Error(`Access denied to webContents`)
  10. }
  11. return guest
  12. }
  13. ipcMain.handle('openDevTools', (event, webContentsId) => {
  14. const guest = getGuestForWebContents(webContentsId, event.sender)
  15. guest.openDevTools()
  16. })
  17. // renderer
  18. const { ipcRenderer } = require('electron')
  19. ipcRenderer.invoke('openDevTools', webview.getWebContentsId())

Deprecated: webFrame.setLayoutZoomLevelLimits()

Chromium has removed support for changing the layout zoom level limits, and it is beyond Electron’s capacity to maintain it. The function will emit a warning in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined here.

计划重写的 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.

过时的: https://atom.io/download/electron

替换为: https://electronjs.org/headers

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

The session.clearAuthCache API no longer accepts options for what to clear, and instead unconditionally clears the whole cache.

  1. // Deprecated
  2. session.clearAuthCache({ type: 'password' })
  3. // Replace with
  4. session.clearAuthCache()

API Changed: powerMonitor.querySystemIdleState is now powerMonitor.getSystemIdleState

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

API Changed: powerMonitor.querySystemIdleTime is now powerMonitor.getSystemIdleState

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

API Changed: webFrame.setIsolatedWorldInfo replaces separate methods

  1. // Removed in Electron 7.0
  2. webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp)
  3. webFrame.setIsolatedWorldHumanReadableName(worldId, name)
  4. webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin)
  5. // Replace with
  6. webFrame.setIsolatedWorldInfo(
  7. worldId,
  8. {
  9. securityOrigin: 'some_origin',
  10. name: 'human_readable_name',
  11. csp: 'content_security_policy'
  12. })

Removed: marked property on getBlinkMemoryInfo

This property was removed in Chromium 77, and as such is no longer available.

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

The webkitdirectory property on HTML file inputs allows them to select folders. Previous versions of Electron had an incorrect implementation where the event.target.files of the input returned a FileList that returned one File corresponding to the selected folder.

As of Electron 7, that FileList is now list of all files contained within the folder, similarly to Chrome, Firefox, and Edge (link to MDN docs).

As an illustration, take a folder with this structure:

  1. folder
  2. ├── file1
  3. ├── file2
  4. └── file3

In Electron <=6, this would return a FileList with a File object for:

  1. path/to/folder

In Electron 7, this now returns a FileList with a File object for:

  1. /path/to/folder/file3
  2. /path/to/folder/file2
  3. /path/to/folder/file1

Note that webkitdirectory no longer exposes the path to the selected folder. If you require the path to the selected folder rather than the folder contents, see the dialog.showOpenDialog API (link).

计划重写的 API (6.0)

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

  1. // 不推荐
  2. win.setMenu(null)
  3. // 替换为
  4. win.removeMenu()

API Changed: contentTracing.getTraceBufferUsage() is now a promise

  1. // Deprecated
  2. contentTracing.getTraceBufferUsage((percentage, value) => {
  3. // do something
  4. })
  5. // Replace with
  6. contentTracing.getTraceBufferUsage().then(infoObject => {
  7. // infoObject has percentage and value fields
  8. })

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

  1. // 不推荐
  2. require('electron').screen
  3. // 替换为
  4. require('electron').remote.screen

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

  1. // 不推荐
  2. require('child_process')
  3. // 替换为
  4. require('electron').remote.require('child_process')
  5. // 不推荐
  6. require('fs')
  7. // 替换为
  8. require('electron').remote.require('fs')
  9. // 不推荐
  10. require('os')
  11. // 替换为
  12. require('electron').remote.require('os')
  13. // 不推荐
  14. require('path')
  15. // 替换为
  16. require('electron').remote.require('path')

Deprecated: powerMonitor.querySystemIdleState replaced with powerMonitor.getSystemIdleState

  1. // Deprecated
  2. powerMonitor.querySystemIdleState(threshold, callback)
  3. // Replace with synchronous API
  4. const idleState = powerMonitor.getSystemIdleState(threshold)

Deprecated: powerMonitor.querySystemIdleTime replaced with powerMonitor.getSystemIdleTime

  1. // Deprecated
  2. powerMonitor.querySystemIdleTime(callback)
  3. // Replace with synchronous API
  4. const idleTime = powerMonitor.getSystemIdleTime()

Deprecated: app.enableMixedSandbox() is no longer needed

  1. // Deprecated
  2. app.enableMixedSandbox()

Mixed-sandbox mode is now enabled by default.

Deprecated: Tray.setHighlightMode

Under macOS Catalina our former Tray implementation breaks. Apple’s native substitute doesn’t support changing the highlighting behavior.

  1. // Deprecated
  2. tray.setHighlightMode(mode)
  3. // 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

  1. const w = new BrowserWindow({
  2. webPreferences: {
  3. webviewTag: true
  4. }
  5. })

Behavior Changed: nodeIntegration in child windows opened via nativeWindowOpen

Child windows opened with the nativeWindowOpen option will always have Node.js integration disabled, unless nodeIntegrationInSubFrames is true.

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

Renderer process APIs webFrame.registerURLSchemeAsPrivileged and webFrame.registerURLSchemeAsBypassingCSP as well as browser process API protocol.registerStandardSchemes have been removed. 新的 API protocol.registerSchemeasviliged 已被添加,并用于注册具有必要权限的自定义 scheme。 自定义 scheme 需要在 app 触发 ready 事件之前注册。

Deprecated: webFrame.setIsolatedWorld* replaced with webFrame.setIsolatedWorldInfo

  1. // 弃用
  2. webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp)
  3. webFrame.setIsolatedWorldHumanReadableName(worldId, name)
  4. webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin)
  5. // 替换为
  6. webFrame.setIsolatedWorldInfo(
  7. worldId,
  8. {
  9. securityOrigin: 'some_origin',
  10. name: 'human_readable_name',
  11. csp: 'content_security_policy'
  12. })

API Changed: webFrame.setSpellCheckProvider now takes an asynchronous callback

The spellCheck callback is now asynchronous, and autoCorrectWord parameter has been removed.

  1. // Deprecated
  2. webFrame.setSpellCheckProvider('en-US', true, {
  3. spellCheck: (text) => {
  4. return !spellchecker.isMisspelled(text)
  5. }
  6. })
  7. // Replace with
  8. webFrame.setSpellCheckProvider('en-US', {
  9. spellCheck: (words, callback) => {
  10. callback(words.filter(text => spellchecker.isMisspelled(text)))
  11. }
  12. })

计划重写的 API (4.0)

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

app.makeSingleInstance

  1. // 弃用
  2. app.makeSingleInstance((argv, cwd) => {
  3. /* ... */
  4. })
  5. // 替换为
  6. app.requestSingleInstanceLock()
  7. app.on('second-instance', (event, argv, cwd) => {
  8. /* ... */
  9. })

app.releaseSingleInstance

  1. // 废弃
  2. app.releaseSingleInstance()
  3. // 替换为
  4. app.releaseSingleInstanceLock()

app.getGPUInfo

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

win_delay_load_hook

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

重大的API更新 (3.0)

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

app

  1. // 弃用
  2. app.getAppMemoryInfo()
  3. // 替换为
  4. app.getAppMetrics()
  5. // 弃用
  6. const metrics = app.getAppMetrics()
  7. const { memory } = metrics[0] // 弃用的属性

BrowserWindow

  1. // 弃用
  2. let optionsA = { webPreferences: { blinkFeatures: '' } }
  3. let windowA = new BrowserWindow(optionsA)
  4. // 替换为
  5. let optionsB = { webPreferences: { enableBlinkFeatures: '' } }
  6. let windowB = new BrowserWindow(optionsB)
  7. // 弃用
  8. window.on('app-command', (e, cmd) => {
  9. if (cmd === 'media-play_pause') {
  10. // do something
  11. }
  12. })
  13. // 替换为
  14. window.on('app-command', (e, cmd) => {
  15. if (cmd === 'media-play-pause') {
  16. // do something
  17. }
  18. })

clipboard

  1. // 弃用
  2. clipboard.readRtf()
  3. // 替换为
  4. clipboard.readRTF()
  5. // 弃用
  6. clipboard.writeRtf()
  7. // 替换为
  8. clipboard.writeRTF()
  9. // 弃用
  10. clipboard.readHtml()
  11. // 替换为
  12. clipboard.readHTML()
  13. // 弃用
  14. clipboard.writeHtml()
  15. // 替换为
  16. clipboard.writeHTML()

crashReporter

  1. // 弃用
  2. crashReporter.start({
  3. companyName: 'Crashly',
  4. submitURL: 'https://crash.server.com',
  5. autoSubmit: true
  6. })
  7. // 替换为
  8. crashReporter.start({
  9. companyName: 'Crashly',
  10. submitURL: 'https://crash.server.com',
  11. uploadToServer: true
  12. })

nativeImage

  1. // 弃用
  2. nativeImage.createFromBuffer(buffer, 1.0)
  3. // 替换为
  4. nativeImage.createFromBuffer(buffer, {
  5. scaleFactor: 1.0
  6. })

process

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

screen

  1. // 弃用
  2. screen.getMenuBarHeight()
  3. // 替换为
  4. screen.getPrimaryDisplay().workArea

session

  1. // 弃用
  2. ses.setCertificateVerifyProc((hostname, certificate, callback) => {
  3. callback(true)
  4. })
  5. // 替换为
  6. ses.setCertificateVerifyProc((request, callback) => {
  7. callback(0)
  8. })

Tray

  1. // 弃用
  2. tray.setHighlightMode(true)
  3. // 替换为
  4. tray.setHighlightMode('on')
  5. // 弃用
  6. tray.setHighlightMode(false)
  7. // 替换为
  8. tray.setHighlightMode('off')

webContents

  1. // 弃用
  2. webContents.openDevTools({ detach: true })
  3. // 替换为
  4. webContents.openDevTools({ mode: 'detach' })
  5. // 移除
  6. webContents.setSize(options)
  7. // 没有该API的替代

webFrame

  1. // 弃用
  2. webFrame.registerURLSchemeAsSecure('app')
  3. // 替换为
  4. protocol.registerStandardSchemes(['app'], { secure: true })
  5. // 弃用
  6. webFrame.registerURLSchemeAsPrivileged('app', { secure: true })
  7. // 替换为
  8. protocol.registerStandardSchemes(['app'], { secure: true })

<webview>

  1. // 移除
  2. webview.setAttribute('disableguestresize', '')
  3. // 没有该API的替代
  4. // 移除
  5. webview.setAttribute('guestinstance', instanceId)
  6. // 没有该API的替代
  7. // 键盘监听器在webview标签中不再起效
  8. webview.onkeydown = () => { /* handler */ }
  9. 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

  1. // 弃用
  2. let optionsA = { titleBarStyle: 'hidden-inset' }
  3. let windowA = new BrowserWindow(optionsA)
  4. // 替换为
  5. let optionsB = { titleBarStyle: 'hiddenInset' }
  6. let windowB = new BrowserWindow(optionsB)

menu

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

nativeImage

  1. // 移除
  2. nativeImage.toPng()
  3. // 替换为
  4. nativeImage.toPNG()
  5. // 移除
  6. nativeImage.toJpeg()
  7. // 替换为
  8. nativeImage.toJPEG()

process

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

webContents

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

webFrame

  1. // 移除
  2. webFrame.setZoomLevelLimits(1, 2)
  3. // 替换为
  4. webFrame.setVisualZoomLevelLimits(1, 2)

<webview>

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

重复的 ARM 资源

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

为了防止可能导致安装器毁坏的中断,不带前缀的文件仍然将被发布。 Starting at 2.0, the unprefixed file will no longer be published.

更多详细情况,查看 69867189