This may be a false negative.
I am expecting test to be logged out onto the console when the application fires up, but it isn’t.
The output location of console.log
calls depends on where those calls were made:
-
From the main thread: see the terminal that launched the app.
-
From the renderer thread: see the Chrome DevTools console.
So please make sure you were looking for the expected output at the right place.
If that didn’t work then here’s a little demo on how to setup IPC communication between the main and renderer processes.
main.js
You’ll notice that I did set up both nodeIntegration
and contextIsolation
to their default value. This was done on purpose to make it clear that you do not need to lower the security bar of your app to allow messages between your main and renderer processes.
What’s going on here?
The main process waits until the renderer has finished loading before sending its “ping” message. The IPC communication will be handled by the preload script.
Note the console.log
call and see where it appears in the screencast below.
const {app, BrowserWindow} = require('electron'); // <-- v15
const path = require('path');
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
devTools: true,
preload: path.resolve(__dirname, 'preload.js'),
nodeIntegration: false, // <-- This is the default value
contextIsolation: true // <-- This is the default value
}
});
win.loadFile('index.html');
win.webContents.openDevTools();
win.webContents.on('did-finish-load', () => {
win.webContents.send('ping', '🏓');
});
// This will not show up in the Chrome DevTools Console
// This will show up in the terminal that launched the app
console.log('this is from the main thread');
});
preload.js
We’re using the contextBridge
API. This allows to expose a privileged API to your renderer process without enabling nodeIntegration
or breaking context isolation.
The API will be available under a very silly namespace (BURRITO) to make it clear that you can change this.
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('BURRITO', {
whenPing: () => new Promise((res) => {
ipcRenderer.on('ping', (ev, data) => {
res(data);
});
})
});
renderer.js
Using the API provided by the preload script we start listening for the ping message. When we do get it we put the data communicated by the main process in the renderer page. We also log a message which you can see in the screencast below.
BURRITO.whenPing().then(data => {
document.querySelector('div').textContent = data;
// This will show up in the Chrome DevTools Console
console.log(`this is the renderer thread, received ${data} from main thread`);
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>IPC Demo</title>
</head>
<body>
<div></div>
<script src="./renderer.js"></script>
</body>
</html>
Run the app with:
npx electron main.js
You can see that the two console.log
calls produced output in two different places.