This project is no longer maintained, pull requests are no longer being reviewed or merged and issues are no longer being responded to.
remote
The Quickest of Quick Starts
Calling main process modules from a renderer
import { createProxyForMainProcessModule } from 'electron-remote'; // app is now a proxy for the app module in the main process const app = createProxyForMainProcessModule('app'); // The difference is all methods return a Promise instead of blocking const memoryInfo = await app.getAppMemoryInfo();
Calling code in other windows
import { createProxyForRemote } from 'electron-remote'; // myWindowJs is now a proxy object for myWindow's `window` global object const myWindowJs = createProxyForRemote(myWindow); // Functions suffixed with _get will read a value userAgent = await myWindowJs.navigator.userAgent_get()
Renderer Taskpool
import { requireTaskPool } from 'electron-remote'; const myCoolModule = requireTaskPool(require.resolve('./my-cool-module')); // This method will run synchronously, but in a background BrowserWindow process // so that your app will not block let result = await myCoolModule.calculateDigitsOfPi(100000);
But I like Remote!
Remote is super convenient! But it also has some downsides - its main downside is that its action is synchronous. This means that both the main and window processes will wait for a method to finish running. Even for quick methods, calling it too often can introduce scroll jank and generally cause performance problems.
electron-remote is a version of remote that, while less ergonomic, guarantees that it won't block the calling thread.
Using createProxyForRemote
createProxyForRemoteexecuteJavaScriptwindowremote
This provides a number of very important advantages:
createProxyForRemoteeval
How do I get properties if everything is a Promise tho???
_get()
import { createProxyForRemote } from 'electron-remote'; // myWindowJs is now a proxy object for myWindow's `window` global object const myWindowJs = createProxyForRemote(myWindow); // Functions suffixed with _get will read a value myWindowJs.navigator.userAgent_get() .then((agent) => console.log(`The user agent is ${agent}`));
But do this first!
createProxyForRemoteinitializeEvalHandler()
Bringing it all together
// In my window's main.js initializeEvalHandler(); window.addNumbers = (a,b) => a + b; // In my main process let myWindowProxy = createProxyForRemote(myWindow); myWindowProxy.addNumbers(5, 5) .then((x) => console.log(x)); >>> 10
Using createProxyForMainProcessModule
remotecreateProxyForRemoteevalipc.sendSync
Here Be Dragons
electron-remote has a number of significant caveats versus the remote module that you should definitely be aware of:
- Remote values must be Serializable
JSON.stringify
let myWindowProxy = createProxyForRemote(myWindow); // XXX: BAD - HTML elements aren't serializable let obj = myWindowProxy.document.createElement('h1');
- Remote event listeners aren't supported
Anything that involves an event handler isn't going to work:
// XXX: BAD - You can't add event handlers myWindowProxy.document.addEventListener('onBlur', (e) => console.log("Blur!"));
The Renderer Taskpool
Renderer Taskpools provide an automatic way to use BrowserWindows as "background processes" that auto-scales based on usage, similar to Grand Central Dispatch or the .NET TPL Taskpool. This works by allowing you to provide a Module that you'd like to load in the remote processes, which will be loaded and unloaded on the fly according to demand.
Let's look at the example again:
import { requireTaskPool } from 'electron-remote'; const myCoolModule = requireTaskPool(require.resolve('./my-cool-module')); // This method will run synchronously, but in a background BrowserWindow process // so that your app will not block let result = await myCoolModule.calculateDigitsOfPi(100000);
requireTaskPool
More Dragons
requireTaskPool
The remote-ajax module
remote-ajax
import { requireTaskPool } from 'electron-remote'; const remoteAjax = requireTaskPool(require.resolve('electron-remote/remote-ajax')); // Result is the object that XmlHttpRequest gives you let result = await remoteAjax.get('https://httpbin.org/get'); console.log(result.url) >>> 'https://httpbin.org/get'
See the documentation for Rx-DOM for how these methods work.
downloadFileOrUrl
/** * Downloads a path as either a file path or a HTTP URL to a specific place * * @param {string} pathOrUrl Either an HTTP URL or a file path. * @return {string} The contents as a UTF-8 decoded string. */ function downloadFileOrUrl(pathOrUrl, target)