Table of contents

  1. 1. main process
    1. 1.1. Concerns
  2. 2. renderer process
    1. 2.1. Concerns
    2. 2.2. Characteristics
    3. 2.3. Example
  3. 3. Inter-process communication (IPC)
  4. 4. Webview Preload Script

Overview of main concepts in Electron 4 applications.

main process

Every Electron app has one (and just one!) main process. The main process is used to display a GUI and started from the main script defined package.json.

Concerns

renderer process

Each web page in Electron runs in a separate renderer process. If not limited, web pages running in a renderer process have to power to access Node.js modules.

Concerns

Characteristics

Example

1
2
3
4
5
6
7
const {desktopCapturer, ipcRenderer, webFrame} = require('electron');
const {app} = require('electron').remote

webFrame.setZoomFactor(1.0);
webFrame.setVisualZoomLevelLimits(1, 1);

console.log('App configuration directory', app.getPath('userData'));

Inter-process communication (IPC)

Using inter-process communication a renderer process can exchange messages with a main process:

renderer.js
1
2
3
4
5
6
7
import {ipcRenderer} from 'electron';

const updateBtn = document.getElementById('updateBtn')

updateBtn.addEventListener('click', () => {
ipcRenderer.send('my-app-event', document.getElementById('notifyVal').value);
});
main.ts
1
2
3
4
5
6
7
import {BrowserWindow, ipcMain, IpcMessageEvent} from 'electron';

const main = new BrowserWindow();

ipcMain.on('my-app-event', (event: IpcMessageEvent, price: number) => {
main.webContents.send('target-price', price);
});

Note: ipcRenderer does not send messages to itself, it sends them to ipcMain. If you want to access the messages within a renderer process, you need to check ipcMain using electron.remote:

renderer.js
1
2
3
4
5
6
7
import {remote} from 'electron';

// ...

remote.ipcMain.on('my-app-event', (event, price) => {
console.log(`Received "${price}" in renderer process.`);
});

Webview Preload Script

index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<script>
require('./renderer.js');
</script>
<body>
<webview
preload="./preload.js"
src="https://benny.work"
></webview>
</body>
</html>

You can assign a preload script programmatically:

1
2
3
4
5
6
7
8
9
import fileUrl = require('file-url');

const main = new BrowserWindow();

const contents = main.webContents;

contents.on('will-attach-webview', (event, webPreferences, params) => {
webPreferences.preloadURL = fileUrl('./preload.js');
});
preload.js
1
2
3
4
5
6
7
8
9
10
11
12
13
const {ipcRenderer} = require('electron');

window.addEventListener('DOMContentLoaded', () => {
// From guest (webview content) to host (main process)
window.addEventListener(z.event.WebApp.LIFECYCLE.RESTART, (event) => {
ipcRenderer.send(EVENT_TYPE.WRAPPER.RELAUNCH);
});

// From host (main process) to guest (webview content)
ipcRenderer.on(EVENT_TYPE.WRAPPER.RELAUNCHED, () => {
window.dispatchEvent(new CustomEvent(EVENT_TYPE.ACTION.CREATE_ACCOUNT));
});
});
main.ts
1
2
3
4
5
6
7
8
9
10
11
import {BrowserWindow} from 'electron';

const main = new BrowserWindow();
main.loadFile('index.html');
ipcMain.on(
EVENT_TYPE.WRAPPER.RELAUNCH,
async (event: IpcMessageEvent) => {
console.log('Do some work and send a reply...');
main.webContents.send(EVENT_TYPE.WRAPPER.RELAUNCHED);
}
);