'Referencing BrowserWindow from another file electron

I am trying to reference BrowserWindow from another file (not main) in Electron so that I can send a message to the renderer thread.

Here's what I'm doing now:

otherFile.js:

const { BrowserWindow } = require("electron");


module.exports.buildProject = (project) => {
    BrowserWindow.webContents.send('build-console-log', "building " + project);
}

When this runs it shows

Cannot read property 'send' of undefined

Not sure why this wouldn't be working



Solution 1:[1]

To send a message from the main thread to a specific render thread requires the use of WebContents.send. An understanding of Inter-Process Communication and Context Isolation is required.

Communication between the main thread and render threads aside, the easiest method to share a 'window' object between two of more scripts is to use a 'getter' function.

In the below example the file myWindow.js creates the window and stores it in a variable called myWindow so it can be returned at anytime through the use of the exported get() function.

myWindow.js (main thread)

const electronBrowserWindow = require('electron').BrowserWindow;

const nodePath = require('path');

let myWindow;

function create() {
    // Create the window.
    myWindow = new electronBrowserWindow ({
        x: 0,
        y: 0,
        width: 800,
        height: 600,
        show: false,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            preload: nodePath.join(__dirname, 'preload.js')
        }
    })

    // Load the window.
    myWindow.loadFile(nodePath.join(__dirname, 'window.html'))
        .then(() => { window.show(); })

    // Return window should the script creating the window need it.
    return myWindow;
}

function get() {
    return myWindow;
}

// Export the publicly available functions.
module.exports = {create, get};

In this answer, I am assuming you have configured you preload.js script correctly. IE: A main to render thread channel named build-console-log.


To reference the Electron myWindow object, include the myWindow.js module and use the appWindow.get() function.

When the buildProject() function is called, send a message via the channel build-console-log.

otherFile.js (main thread)

const nodePath = require('path');

const appWindow = require(nodePath.join(__dirname, 'myWindow'));

function buildProject(project) {
    // Send message to render thread.
    appWindow.get().webContents.send('build-console-log', 'building ' + project);
}

module.exports = {buildProject};

Ensure the html page is listening for a message over the build-console-log channel.

window.html (render thread)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Title</title>
        <link rel="stylesheet" href="index.css" />
    </head>

    <body>...</body>

    <script>
        (function() => {
            window.ipcRender.receive('build-console-log', (event, message) => { display(message); }
        })();

        display(message) { console.log(message); }
    </script>
</html>

Now, let's message the render.

message.js (main thread)

const nodePath = require('path');

const otherFile = require(nodePath.join(__dirname, 'otherFile'));

// Message the render.
otherFile.buildProject('project name');

Console output in the render should be building project name.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 midnight-coding