Electron 重大更改
这里将记录重大更改,并在可能的情况下向JS代码添加弃用警告,在这更改之前至少会有一个重要版本.
重大更改的类型
本文档使用以下约定对重大更改进行分类:
- API 更改:已更改的 API 会以某种方式使未更新的代码必定抛出异常。
- 行为改变:Electron 的行为已经改变,但并不一定抛出相应的异常。
- 默认值更改:依赖于默认值的代码的行为可能被破坏,但不保证会抛出相应的异常。 您可以通过显式指定该值的方式恢复旧的默认行为。
- 已废弃:该 API 已标记为废弃。 该 API 依旧可正常运作,但会抛出已废弃警告,并在将来会移除。
- 已移除:该 API 或功能已移除,Electron团队不再对此提供支持。
计划重写的 API (23.0)
已删除:BrowserWindow scroll-touch-* 事件
在 BrowserWindow 上已弃用的 scroll-touch-begin
、scroll-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-begin
、scroll-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
。 为正确响应权限检查,您需要使用requestingOrigin
、embeddingOrigin
和 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 对象(例如:Element
、Location
、DOMMatrix
),Node.js 中由 C++ 类支持的对象(例如:process.env
、Stream
中的一些方法),和
Electron 中由 C++ 类支持的对象(例如:WebContents
、BrowserWindow
、WebFrame
)无法使用使用结构化克隆序列化。 每当调用到旧算法时,都会打印弃用警告。
在 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.send
、ipcRenderer.sendSync
、WebContents.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.")
NaN
、Infinity
、-Infinity
现在将被正确的序列化,而不是转换为null
。- 包含循环引用的对象现在将被正确的序列化,而不是转换为
null
。 Set
、Map
、Error
、RegExp
值将被正确的序列化,而不是转换为{}
。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()
#15742app.dock.show()
#16904contentTracing.getCategories()
#16583contentTracking.getTraceBufferUs()
#16600contentTracing.startRecording()
#16584contentTracing.stopRecording()
#16584contents.executeJavaScript()
#17312cookies.flushStore()
#16464cookies.get()
#16464cookies.remove()
#16464cookies.set()
#16464debugger.sendCommand()
#16861dialog.showCertificateTrustDialog()
#17181inAppPurchase.getProducts()
#17355inAppPurchase.purchaseProduct()
#17355netLog.stopLogging()
#16862session.clearAuthCache()
#17259session.clearCache()
#17185session.clearHostResolverCache()
#17229session.clearStorageData()
#17249session.getBlobData()
#17303session.getCacheSize()
#17185session.resolveProxy()
#17222session.setProxy()
#17222shell.openExternal()
#16176webContents.loadFile()
#15855webContents.loadURL()
#15855webContents.hasServiceWorker()
#16535webContents.printToPDF()
#16795webContents.savePage()
#16742webFrame.executeJavaScript()
#17312webFrame.executeJavaScriptInIsolatedWorld()
#17312webviewTag.executeJavaScript()
#17312win.capturePage()
#15743
这些功能现在有两种形式,即同步和基于Promise的异步:
dialog.showMessageBox()
/dialog.showMessageBoxSync()
#17298dialog.showOpenDialog()
/dialog.showOpenDialogSync()
#16973dialog.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.electron
和process.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版本起,不带前缀的文件将不再发布。
更多建议: