mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
685 lines
17 KiB
Markdown
685 lines
17 KiB
Markdown
# Breaking Changes
|
||
|
||
Breaking changes will be documented here, and deprecation warnings added to JS code where possible, at least [one major version](../tutorial/electron-versioning.md#semver) before the change is made.
|
||
|
||
## `FIXME` comments
|
||
|
||
The `FIXME` string is used in code comments to denote things that should be fixed for future releases. See https://github.com/electron/electron/search?q=fixme
|
||
|
||
## Planned Breaking API Changes (8.0)
|
||
|
||
### 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][SCA], 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.")
|
||
```
|
||
- `NaN`, `Infinity` and `-Infinity` will now be correctly serialized, instead
|
||
of being converted to `null`.
|
||
- Objects containing cyclic references will now be correctly serialized,
|
||
instead of being converted to `null`.
|
||
- `Set`, `Map`, `Error` and `RegExp` values will be correctly serialized,
|
||
instead of being converted to `{}`.
|
||
- `BigInt` values will be correctly serialized, instead of being converted to
|
||
`null`.
|
||
- Sparse arrays will be serialized as such, instead of being converted to dense
|
||
arrays with `null`s.
|
||
- `Date` objects will be transferred as `Date` objects, instead of being
|
||
converted to their ISO string representation.
|
||
- Typed Arrays (such as `Uint8Array`, `Uint16Array`, `Uint32Array` and so on)
|
||
will be transferred as such, instead of being converted to Node.js `Buffer`.
|
||
- 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`:
|
||
```js
|
||
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.
|
||
|
||
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
|
||
|
||
### `<webview>.getWebContents()`
|
||
|
||
This API is implemented using the `remote` module, which has both performance
|
||
and security implications. Therefore its usage should be explicit.
|
||
|
||
```js
|
||
// Deprecated
|
||
webview.getWebContents()
|
||
// Replace with
|
||
const { remote } = require('electron')
|
||
remote.webContents.fromId(webview.getWebContentsId())
|
||
```
|
||
|
||
However, it is recommended to avoid using the `remote` module altogether.
|
||
|
||
```js
|
||
// main
|
||
const { ipcMain, webContents } = require('electron')
|
||
|
||
const getGuestForWebContents = function (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())
|
||
```
|
||
|
||
### `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](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
|
||
|
||
## Planned Breaking API Changes (7.0)
|
||
|
||
### Node Headers URL
|
||
|
||
This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url`
|
||
command line flag when building native Node modules. 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
|
||
|
||
### `session.clearAuthCache(options)`
|
||
|
||
The `session.clearAuthCache` API no longer accepts options for what to clear, and instead unconditionally clears the whole cache.
|
||
|
||
```js
|
||
// Deprecated
|
||
session.clearAuthCache({ type: 'password' })
|
||
// Replace with
|
||
session.clearAuthCache()
|
||
```
|
||
|
||
### `powerMonitor.querySystemIdleState`
|
||
|
||
```js
|
||
// Removed in Electron 7.0
|
||
powerMonitor.querySystemIdleState(threshold, callback)
|
||
// Replace with synchronous API
|
||
const idleState = getSystemIdleState(threshold)
|
||
```
|
||
|
||
### `powerMonitor.querySystemIdleTime`
|
||
|
||
```js
|
||
// Removed in Electron 7.0
|
||
powerMonitor.querySystemIdleTime(callback)
|
||
// Replace with synchronous API
|
||
const idleTime = getSystemIdleTime()
|
||
```
|
||
|
||
### webFrame Isolated World APIs
|
||
|
||
```js
|
||
// 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'
|
||
})
|
||
```
|
||
|
||
### Removal of deprecated `marked` property on getBlinkMemoryInfo
|
||
|
||
This property was removed in Chromium 77, and as such is no longer available.
|
||
|
||
### `webkitdirectory` attribute for `<input type="file"/>`
|
||

|
||
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](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory)).
|
||

|
||
As an illustration, take a folder with this structure:
|
||
```console
|
||
folder
|
||
├── file1
|
||
├── file2
|
||
└── file3
|
||
```
|
||

|
||
In Electron <=6, this would return a `FileList` with a `File` object for:
|
||
```console
|
||
path/to/folder
|
||
```
|
||

|
||
In Electron 7, this now returns a `FileList` with a `File` object for:
|
||
```console
|
||
/path/to/folder/file3
|
||
/path/to/folder/file2
|
||
/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](https://github.com/electron/electron/blob/master/docs/api/dialog.md#dialogshowopendialogbrowserwindow-options)).
|
||
|
||
## Planned Breaking API Changes (6.0)
|
||
|
||
### `win.setMenu(null)`
|
||
|
||
```js
|
||
// Deprecated
|
||
win.setMenu(null)
|
||
// Replace with
|
||
win.removeMenu()
|
||
```
|
||
|
||
### `contentTracing.getTraceBufferUsage()`
|
||
|
||
```js
|
||
// Deprecated
|
||
contentTracing.getTraceBufferUsage((percentage, value) => {
|
||
// do something
|
||
})
|
||
// Replace with
|
||
contentTracing.getTraceBufferUsage().then(infoObject => {
|
||
// infoObject has percentage and value fields
|
||
})
|
||
```
|
||
|
||
### `electron.screen` in renderer process
|
||
|
||
```js
|
||
// Deprecated
|
||
require('electron').screen
|
||
// Replace with
|
||
require('electron').remote.screen
|
||
```
|
||
|
||
### `require` in sandboxed renderers
|
||
|
||
```js
|
||
// Deprecated
|
||
require('child_process')
|
||
// Replace with
|
||
require('electron').remote.require('child_process')
|
||
|
||
// Deprecated
|
||
require('fs')
|
||
// Replace with
|
||
require('electron').remote.require('fs')
|
||
|
||
// Deprecated
|
||
require('os')
|
||
// Replace with
|
||
require('electron').remote.require('os')
|
||
|
||
// Deprecated
|
||
require('path')
|
||
// Replace with
|
||
require('electron').remote.require('path')
|
||
```
|
||
|
||
### `powerMonitor.querySystemIdleState`
|
||
|
||
```js
|
||
// Deprecated
|
||
powerMonitor.querySystemIdleState(threshold, callback)
|
||
// Replace with synchronous API
|
||
const idleState = getSystemIdleState(threshold)
|
||
```
|
||
|
||
### `powerMonitor.querySystemIdleTime`
|
||
|
||
```js
|
||
// Deprecated
|
||
powerMonitor.querySystemIdleTime(callback)
|
||
// Replace with synchronous API
|
||
const idleTime = getSystemIdleTime()
|
||
```
|
||
|
||
### `app.enableMixedSandbox`
|
||
|
||
```js
|
||
// Deprecated
|
||
app.enableMixedSandbox()
|
||
```
|
||
|
||
Mixed-sandbox mode is now enabled by default.
|
||
|
||
### `Tray`
|
||
|
||
Under macOS Catalina our former Tray implementation breaks.
|
||
Apple's native substitute doesn't support changing the highlighting behavior.
|
||
|
||
```js
|
||
// Deprecated
|
||
tray.setHighlightMode(mode)
|
||
// API will be removed in v7.0 without replacement.
|
||
```
|
||
|
||
## Planned Breaking API Changes (5.0)
|
||
|
||
### `new BrowserWindow({ webPreferences })`
|
||
|
||
The following `webPreferences` option default values are deprecated in favor of the new defaults listed below.
|
||
|
||
| Property | Deprecated Default | New Default |
|
||
|----------|--------------------|-------------|
|
||
| `contextIsolation` | `false` | `true` |
|
||
| `nodeIntegration` | `true` | `false` |
|
||
| `webviewTag` | `nodeIntegration` if set else `true` | `false` |
|
||
|
||
E.g. Re-enabling the webviewTag
|
||
|
||
```js
|
||
const w = new BrowserWindow({
|
||
webPreferences: {
|
||
webviewTag: true
|
||
}
|
||
})
|
||
```
|
||
|
||
### `nativeWindowOpen`
|
||
|
||
Child windows opened with the `nativeWindowOpen` option will always have Node.js integration disabled, unless `nodeIntegrationInSubFrames` is `true.
|
||
|
||
### Privileged Schemes Registration
|
||
|
||
Renderer process APIs `webFrame.setRegisterURLSchemeAsPrivileged` and `webFrame.registerURLSchemeAsBypassingCSP` as well as browser process API `protocol.registerStandardSchemes` have been removed.
|
||
A new API, `protocol.registerSchemesAsPrivileged` has been added and should be used for registering custom schemes with the required privileges. Custom schemes are required to be registered before app ready.
|
||
|
||
### webFrame Isolated World APIs
|
||
|
||
```js
|
||
// Deprecated
|
||
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'
|
||
})
|
||
```
|
||
|
||
## `webFrame.setSpellCheckProvider`
|
||
The `spellCheck` callback is now asynchronous, and `autoCorrectWord` parameter has been removed.
|
||
```js
|
||
// 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)))
|
||
}
|
||
})
|
||
```
|
||
|
||
## Planned Breaking API Changes (4.0)
|
||
|
||
The following list includes the breaking API changes made in Electron 4.0.
|
||
|
||
### `app.makeSingleInstance`
|
||
|
||
```js
|
||
// Deprecated
|
||
app.makeSingleInstance((argv, cwd) => {
|
||
/* ... */
|
||
})
|
||
// Replace with
|
||
app.requestSingleInstanceLock()
|
||
app.on('second-instance', (event, argv, cwd) => {
|
||
/* ... */
|
||
})
|
||
```
|
||
|
||
### `app.releaseSingleInstance`
|
||
|
||
```js
|
||
// Deprecated
|
||
app.releaseSingleInstance()
|
||
// Replace with
|
||
app.releaseSingleInstanceLock()
|
||
```
|
||
|
||
### `app.getGPUInfo`
|
||
|
||
```js
|
||
app.getGPUInfo('complete')
|
||
// Now behaves the same with `basic` on macOS
|
||
app.getGPUInfo('basic')
|
||
```
|
||
|
||
### `win_delay_load_hook`
|
||
|
||
When building native modules for windows, the `win_delay_load_hook` variable in
|
||
the module's `binding.gyp` must be true (which is the default). If this hook is
|
||
not present, then the native module will fail to load on Windows, with an error
|
||
message like `Cannot find module`. See the [native module
|
||
guide](/docs/tutorial/using-native-node-modules.md) for more.
|
||
|
||
## Breaking API Changes (3.0)
|
||
|
||
The following list includes the breaking API changes in Electron 3.0.
|
||
|
||
### `app`
|
||
|
||
```js
|
||
// Deprecated
|
||
app.getAppMemoryInfo()
|
||
// Replace with
|
||
app.getAppMetrics()
|
||
|
||
// Deprecated
|
||
const metrics = app.getAppMetrics()
|
||
const { memory } = metrics[0] // Deprecated property
|
||
```
|
||
|
||
### `BrowserWindow`
|
||
|
||
```js
|
||
// Deprecated
|
||
let optionsA = { webPreferences: { blinkFeatures: '' } }
|
||
let windowA = new BrowserWindow(optionsA)
|
||
// Replace with
|
||
let optionsB = { webPreferences: { enableBlinkFeatures: '' } }
|
||
let windowB = new BrowserWindow(optionsB)
|
||
|
||
// Deprecated
|
||
window.on('app-command', (e, cmd) => {
|
||
if (cmd === 'media-play_pause') {
|
||
// do something
|
||
}
|
||
})
|
||
// Replace with
|
||
window.on('app-command', (e, cmd) => {
|
||
if (cmd === 'media-play-pause') {
|
||
// do something
|
||
}
|
||
})
|
||
```
|
||
|
||
### `clipboard`
|
||
|
||
```js
|
||
// Deprecated
|
||
clipboard.readRtf()
|
||
// Replace with
|
||
clipboard.readRTF()
|
||
|
||
// Deprecated
|
||
clipboard.writeRtf()
|
||
// Replace with
|
||
clipboard.writeRTF()
|
||
|
||
// Deprecated
|
||
clipboard.readHtml()
|
||
// Replace with
|
||
clipboard.readHTML()
|
||
|
||
// Deprecated
|
||
clipboard.writeHtml()
|
||
// Replace with
|
||
clipboard.writeHTML()
|
||
```
|
||
|
||
### `crashReporter`
|
||
|
||
```js
|
||
// Deprecated
|
||
crashReporter.start({
|
||
companyName: 'Crashly',
|
||
submitURL: 'https://crash.server.com',
|
||
autoSubmit: true
|
||
})
|
||
// Replace with
|
||
crashReporter.start({
|
||
companyName: 'Crashly',
|
||
submitURL: 'https://crash.server.com',
|
||
uploadToServer: true
|
||
})
|
||
```
|
||
|
||
### `nativeImage`
|
||
|
||
```js
|
||
// Deprecated
|
||
nativeImage.createFromBuffer(buffer, 1.0)
|
||
// Replace with
|
||
nativeImage.createFromBuffer(buffer, {
|
||
scaleFactor: 1.0
|
||
})
|
||
```
|
||
|
||
### `process`
|
||
|
||
```js
|
||
// Deprecated
|
||
const info = process.getProcessMemoryInfo()
|
||
```
|
||
|
||
### `screen`
|
||
|
||
```js
|
||
// Deprecated
|
||
screen.getMenuBarHeight()
|
||
// Replace with
|
||
screen.getPrimaryDisplay().workArea
|
||
```
|
||
|
||
### `session`
|
||
|
||
```js
|
||
// Deprecated
|
||
ses.setCertificateVerifyProc((hostname, certificate, callback) => {
|
||
callback(true)
|
||
})
|
||
// Replace with
|
||
ses.setCertificateVerifyProc((request, callback) => {
|
||
callback(0)
|
||
})
|
||
```
|
||
|
||
### `Tray`
|
||
|
||
```js
|
||
// Deprecated
|
||
tray.setHighlightMode(true)
|
||
// Replace with
|
||
tray.setHighlightMode('on')
|
||
|
||
// Deprecated
|
||
tray.setHighlightMode(false)
|
||
// Replace with
|
||
tray.setHighlightMode('off')
|
||
```
|
||
|
||
### `webContents`
|
||
|
||
```js
|
||
// Deprecated
|
||
webContents.openDevTools({ detach: true })
|
||
// Replace with
|
||
webContents.openDevTools({ mode: 'detach' })
|
||
|
||
// Removed
|
||
webContents.setSize(options)
|
||
// There is no replacement for this API
|
||
```
|
||
|
||
### `webFrame`
|
||
|
||
```js
|
||
// Deprecated
|
||
webFrame.registerURLSchemeAsSecure('app')
|
||
// Replace with
|
||
protocol.registerStandardSchemes(['app'], { secure: true })
|
||
|
||
// Deprecated
|
||
webFrame.registerURLSchemeAsPrivileged('app', { secure: true })
|
||
// Replace with
|
||
protocol.registerStandardSchemes(['app'], { secure: true })
|
||
```
|
||
|
||
### `<webview>`
|
||
|
||
```js
|
||
// Removed
|
||
webview.setAttribute('disableguestresize', '')
|
||
// There is no replacement for this API
|
||
|
||
// Removed
|
||
webview.setAttribute('guestinstance', instanceId)
|
||
// There is no replacement for this API
|
||
|
||
// Keyboard listeners no longer work on webview tag
|
||
webview.onkeydown = () => { /* handler */ }
|
||
webview.onkeyup = () => { /* handler */ }
|
||
```
|
||
|
||
### Node Headers URL
|
||
|
||
This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url`
|
||
command line flag when building native Node modules.
|
||
|
||
Deprecated: https://atom.io/download/atom-shell
|
||
|
||
Replace with: https://atom.io/download/electron
|
||
|
||
## Breaking API Changes (2.0)
|
||
|
||
The following list includes the breaking API changes made in Electron 2.0.
|
||
|
||
### `BrowserWindow`
|
||
|
||
```js
|
||
// Deprecated
|
||
let optionsA = { titleBarStyle: 'hidden-inset' }
|
||
let windowA = new BrowserWindow(optionsA)
|
||
// Replace with
|
||
let optionsB = { titleBarStyle: 'hiddenInset' }
|
||
let windowB = new BrowserWindow(optionsB)
|
||
```
|
||
|
||
### `menu`
|
||
|
||
```js
|
||
// Removed
|
||
menu.popup(browserWindow, 100, 200, 2)
|
||
// Replaced with
|
||
menu.popup(browserWindow, { x: 100, y: 200, positioningItem: 2 })
|
||
```
|
||
|
||
### `nativeImage`
|
||
|
||
```js
|
||
// Removed
|
||
nativeImage.toPng()
|
||
// Replaced with
|
||
nativeImage.toPNG()
|
||
|
||
// Removed
|
||
nativeImage.toJpeg()
|
||
// Replaced with
|
||
nativeImage.toJPEG()
|
||
```
|
||
|
||
### `process`
|
||
|
||
* `process.versions.electron` and `process.version.chrome` will be made
|
||
read-only properties for consistency with the other `process.versions`
|
||
properties set by Node.
|
||
|
||
### `webContents`
|
||
|
||
```js
|
||
// Removed
|
||
webContents.setZoomLevelLimits(1, 2)
|
||
// Replaced with
|
||
webContents.setVisualZoomLevelLimits(1, 2)
|
||
```
|
||
|
||
### `webFrame`
|
||
|
||
```js
|
||
// Removed
|
||
webFrame.setZoomLevelLimits(1, 2)
|
||
// Replaced with
|
||
webFrame.setVisualZoomLevelLimits(1, 2)
|
||
```
|
||
|
||
### `<webview>`
|
||
|
||
```js
|
||
// Removed
|
||
webview.setZoomLevelLimits(1, 2)
|
||
// Replaced with
|
||
webview.setVisualZoomLevelLimits(1, 2)
|
||
```
|
||
|
||
### Duplicate ARM Assets
|
||
|
||
Each Electron release includes two identical ARM builds with slightly different
|
||
filenames, like `electron-v1.7.3-linux-arm.zip` and
|
||
`electron-v1.7.3-linux-armv7l.zip`. The asset with the `v7l` prefix was added
|
||
to clarify to users which ARM version it supports, and to disambiguate it from
|
||
future armv6l and arm64 assets that may be produced.
|
||
|
||
The file _without the prefix_ is still being published to avoid breaking any
|
||
setups that may be consuming it. Starting at 2.0, the unprefixed file will
|
||
no longer be published.
|
||
|
||
For details, see
|
||
[6986](https://github.com/electron/electron/pull/6986)
|
||
and
|
||
[7189](https://github.com/electron/electron/pull/7189).
|