|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- # @electron/remote
-
- `@electron/remote` is an [Electron](https://electronjs.org) module that bridges
- JavaScript objects from the main process to the renderer process. This lets you
- access main-process-only objects as if they were available in the renderer
- process.
-
- > ⚠️ **Warning!** This module has [many subtle
- > pitfalls][remote-considered-harmful]. There is almost always a better way to
- > accomplish your task than using this module. For example, [`ipcRenderer.invoke`](https://www.electronjs.org/docs/api/ipc-renderer#ipcrendererinvokechannel-args) can serve many common use cases.
-
- `@electron/remote` is a replacement for the built-in `remote` module in
- Electron, which is deprecated and will eventually be removed.
-
- ## Migrating from `remote`
-
- > **NOTE:** `@electron/remote` requires Electron 10 or higher.
-
- There are three things you need to do to migrate from the built-in `remote`
- module to `@electron/remote`.
-
- First, you need to install it from NPM:
-
- ```shell
- $ npm install --save @electron/remote
- ```
-
- Second, `@electron/remote/main` must be initialized in the main
- process before it can be used from the renderer:
-
- ```javascript
- // in the main process:
- require('@electron/remote/main').initialize()
- ```
-
- Third, `require('electron').remote` in the renderer process must be
- replaced with `require('@electron/remote')`.
-
- ```javascript
- // in the renderer process:
-
- // Before
- const { BrowserWindow } = require('electron').remote
-
- // After
- const { BrowserWindow } = require('@electron/remote')
- ```
-
- **Note:** Since this is requiring a module through npm rather than a built-in
- module, if you're using `remote` from a sandboxed process, you'll need to
- configure your bundler appropriately to package the code of `@electron/remote`
- in the preload script. Of course, [using `@electron/remote` makes the sandbox
- much less effective][remote-considered-harmful].
-
- **Note:** `@electron/remote` respects the `enableRemoteModule` WebPreferences
- value. You must pass `{ webPreferences: { enableRemoteModule: true } }` to
- the constructor of `BrowserWindow`s that should be granted permission to use
- `@electron/remote`.
-
-
- # API Reference
-
- The `remote` module provides a simple way to do inter-process communication
- (IPC) between the renderer process (web page) and the main process.
-
- In Electron, GUI-related modules (such as `dialog`, `menu` etc.) are only
- available in the main process, not in the renderer process. In order to use them
- from the renderer process, the `ipc` module is necessary to send inter-process
- messages to the main process. With the `remote` module, you can invoke methods
- of the main process object without explicitly sending inter-process messages,
- similar to Java's [RMI][rmi]. An example of creating a browser window from a
- renderer process:
-
- ```javascript
- const { BrowserWindow } = require('@electron/remote')
- let win = new BrowserWindow({ width: 800, height: 600 })
- win.loadURL('https://github.com')
- ```
-
- In order for this to work, you first need to initialize the main-process side
- of the remote module:
-
- ```javascript
- // in the main process:
- require('@electron/remote/main').initialize()
- ```
-
- **Note:** The remote module can be disabled for security reasons in the following contexts:
- - [`BrowserWindow`](browser-window.md) - by setting the `enableRemoteModule` option to `false`.
- - [`<webview>`](webview-tag.md) - by setting the `enableremotemodule` attribute to `false`.
-
- ## Remote Objects
-
- Each object (including functions) returned by the `remote` module represents an
- object in the main process (we call it a remote object or remote function).
- When you invoke methods of a remote object, call a remote function, or create
- a new object with the remote constructor (function), you are actually sending
- synchronous inter-process messages.
-
- In the example above, both `BrowserWindow` and `win` were remote objects and
- `new BrowserWindow` didn't create a `BrowserWindow` object in the renderer
- process. Instead, it created a `BrowserWindow` object in the main process and
- returned the corresponding remote object in the renderer process, namely the
- `win` object.
-
- **Note:** Only [enumerable properties][enumerable-properties] which are present
- when the remote object is first referenced are accessible via remote.
-
- **Note:** Arrays and Buffers are copied over IPC when accessed via the `remote`
- module. Modifying them in the renderer process does not modify them in the main
- process and vice versa.
-
- ## Lifetime of Remote Objects
-
- Electron makes sure that as long as the remote object in the renderer process
- lives (in other words, has not been garbage collected), the corresponding object
- in the main process will not be released. When the remote object has been
- garbage collected, the corresponding object in the main process will be
- dereferenced.
-
- If the remote object is leaked in the renderer process (e.g. stored in a map but
- never freed), the corresponding object in the main process will also be leaked,
- so you should be very careful not to leak remote objects.
-
- Primary value types like strings and numbers, however, are sent by copy.
-
- ## Passing callbacks to the main process
-
- Code in the main process can accept callbacks from the renderer - for instance
- the `remote` module - but you should be extremely careful when using this
- feature.
-
- First, in order to avoid deadlocks, the callbacks passed to the main process
- are called asynchronously. You should not expect the main process to
- get the return value of the passed callbacks.
-
- For instance you can't use a function from the renderer process in an
- `Array.map` called in the main process:
-
- ```javascript
- // main process mapNumbers.js
- exports.withRendererCallback = (mapper) => {
- return [1, 2, 3].map(mapper)
- }
-
- exports.withLocalCallback = () => {
- return [1, 2, 3].map(x => x + 1)
- }
- ```
-
- ```javascript
- // renderer process
- const mapNumbers = require('@electron/remote').require('./mapNumbers')
- const withRendererCb = mapNumbers.withRendererCallback(x => x + 1)
- const withLocalCb = mapNumbers.withLocalCallback()
-
- console.log(withRendererCb, withLocalCb)
- // [undefined, undefined, undefined], [2, 3, 4]
- ```
-
- As you can see, the renderer callback's synchronous return value was not as
- expected, and didn't match the return value of an identical callback that lives
- in the main process.
-
- Second, the callbacks passed to the main process will persist until the
- main process garbage-collects them.
-
- For example, the following code seems innocent at first glance. It installs a
- callback for the `close` event on a remote object:
-
- ```javascript
- require('@electron/remote').getCurrentWindow().on('close', () => {
- // window was closed...
- })
- ```
-
- But remember the callback is referenced by the main process until you
- explicitly uninstall it. If you do not, each time you reload your window the
- callback will be installed again, leaking one callback for each restart.
-
- To make things worse, since the context of previously installed callbacks has
- been released, exceptions will be raised in the main process when the `close`
- event is emitted.
-
- To avoid this problem, ensure you clean up any references to renderer callbacks
- passed to the main process. This involves cleaning up event handlers, or
- ensuring the main process is explicitly told to dereference callbacks that came
- from a renderer process that is exiting.
-
- ## Accessing built-in modules in the main process
-
- The built-in modules in the main process are added as getters in the `remote`
- module, so you can use them directly like the `electron` module.
-
- ```javascript
- const app = require('@electron/remote').app
- console.log(app)
- ```
-
- ## Methods
-
- The `remote` module has the following methods:
-
- ### `remote.require(module)`
-
- * `module` String
-
- Returns `any` - The object returned by `require(module)` in the main process.
- Modules specified by their relative path will resolve relative to the entrypoint
- of the main process.
-
- e.g.
-
- ```sh
- project/
- ├── main
- │ ├── foo.js
- │ └── index.js
- ├── package.json
- └── renderer
- └── index.js
- ```
-
- ```js
- // main process: main/index.js
- const { app } = require('@electron/remote')
- app.whenReady().then(() => { /* ... */ })
- ```
-
- ```js
- // some relative module: main/foo.js
- module.exports = 'bar'
- ```
-
- ```js
- // renderer process: renderer/index.js
- const foo = require('@electron/remote').require('./foo') // bar
- ```
-
- ### `remote.getCurrentWindow()`
-
- Returns `BrowserWindow` - The window to which this web page belongs.
-
- **Note:** Do not use `removeAllListeners` on `BrowserWindow`. Use of this can
- remove all [`blur`](https://developer.mozilla.org/en-US/docs/Web/Events/blur)
- listeners, disable click events on touch bar buttons, and other unintended
- consequences.
-
- ### `remote.getCurrentWebContents()`
-
- Returns `WebContents` - The web contents of this web page.
-
- ### `remote.getGlobal(name)`
-
- * `name` String
-
- Returns `any` - The global variable of `name` (e.g. `global[name]`) in the main
- process.
-
- ## Properties
-
- ### `remote.process` _Readonly_
-
- A `NodeJS.Process` object. The `process` object in the main process. This is the same as
- `remote.getGlobal('process')` but is cached.
-
- # Overriding exposed objects
-
- Without filtering, `@electron/remote` will provide access to any JavaScript
- object that any renderer requests. In order to control what can be accessed,
- `@electron/remote` provides an opportunity to the app to return a custom result
- for any of `getGlobal`, `require`, `getCurrentWindow`, `getCurrentWebContents`,
- or any of the builtin module properties.
-
- The following events will be emitted first on the `app` Electron module, and
- then on the specific `WebContents` which requested the object. When emitted on
- the `app` module, the first parameter after the `Event` object will be the
- `WebContents` which originated the request. If any handler calls
- `preventDefault`, the request will be denied. If a `returnValue` parameter is
- set on the result, then that value will be returned to the renderer instead of
- the default.
-
- ## Events
-
- ### Event: 'remote-require'
-
- Returns:
-
- * `event` Event
- * `moduleName` String
-
- Emitted when `remote.require()` is called in the renderer process of `webContents`.
- Calling `event.preventDefault()` will prevent the module from being returned.
- Custom value can be returned by setting `event.returnValue`.
-
- ### Event: 'remote-get-global'
-
- Returns:
-
- * `event` Event
- * `globalName` String
-
- Emitted when `remote.getGlobal()` is called in the renderer process of `webContents`.
- Calling `event.preventDefault()` will prevent the global from being returned.
- Custom value can be returned by setting `event.returnValue`.
-
- ### Event: 'remote-get-builtin'
-
- Returns:
-
- * `event` Event
- * `moduleName` String
-
- Emitted when `remote.getBuiltin()` is called in the renderer process of
- `webContents`, including when a builtin module is accessed as a property (e.g.
- `require("@electron/remote").BrowserWindow`).
- Calling `event.preventDefault()` will prevent the module from being returned.
- Custom value can be returned by setting `event.returnValue`.
-
- ### Event: 'remote-get-current-window'
-
- Returns:
-
- * `event` Event
-
- Emitted when `remote.getCurrentWindow()` is called in the renderer process of `webContents`.
- Calling `event.preventDefault()` will prevent the object from being returned.
- Custom value can be returned by setting `event.returnValue`.
-
- ### Event: 'remote-get-current-web-contents'
-
- Returns:
-
- * `event` Event
-
- Emitted when `remote.getCurrentWebContents()` is called in the renderer process of `webContents`.
- Calling `event.preventDefault()` will prevent the object from being returned.
- Custom value can be returned by setting `event.returnValue`.
-
- [rmi]: https://en.wikipedia.org/wiki/Java_remote_method_invocation
- [enumerable-properties]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
- [remote-considered-harmful]: https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31
|