ContextBridge remains undefined in preload.js giving error: Cannot read property 'exposeInMainWorld' of undefined in packaged Electron app?

Viewed 2952

I have an angular application wrapped in Electron. I have generated the installer using electron-builder. As per the recommendations for communication with renderer process I have used preload.js as preload script.

The script works fine in the development environment. However, once I package the app and install it, it shows me the error Cannot read property 'exposeInMainWorld' of undefined

Here is my preload.js

window.onload = () => {
    const {
        contextBridge,
        ipcRenderer
    } = require("electron");

    const validChannels = ['event-1', 'event-2', 'event-3'];

    // Expose protected methods that allow the renderer process to use the ipcRenderer without exposing the entire object
    contextBridge.exposeInMainWorld(
        "api", {
        send: (channel, data) => {
            // whitelist channels To Main Process
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, data);
            }
        },
        receive: (channel, func) => {
            // From Main Process
            if (validChannels.includes(channel)) {
                console.log('receive: ' + channel);
                ipcRenderer.on(channel, (event, ...args) => func(...args));
            }
        }
    }
    );
};

My Main.js

        this._win = new BrowserWindow({
            width: 1024,
            height: 768,
            webPreferences: {
                nodeIntegration: false,
                webSecurity: true,
                allowEval: false,
                allowRunningInsecureContent: false,
                contextIsolation: true, // protect against prototype pollution
                enableRemoteModule: false, // turn off remote
                preload: path.join(__dirname, "./preload.js") // use a preload script
            },
            title: this._appTitle,
            autoHideMenuBar: true,
            icon: path.join(__dirname, '/../dist/some-path/favicon.ico')
        });

I have kept both main.js and preload.js inside a folder electron at the root level where package.json is available. In case you need to check my builder-config.yaml, it's present at this link.

Please suggest what to do.

P.S. : the preload.js works absolutely fine while in dev mode. The issue is only after packaging the app with electron-builder

2 Answers

I got this kind of error when I wrote:

getPlatform: () => window.remote.getPlatform(),

Then I get Uncaught Error: Uncaught TypeError: Cannot read property 'getPlatform' of undefined

in

console.log('window.remote.getPlatform()', window.remote.getPlatform && window.remote?.getPlatform())

When I change it to

getPlatform: () => process.platform,

everything works just fine.

I got this one working. Actually the version of electron mentioned in my builder-config.yaml was 5.0.13. The contextbridge api was not introduced then. When I changed the version of electron to 9 and above, it works just fine. Thanks

Related