6

Building an electron app and got stuck with an error. I don't understand why my preload.js doesn't find the 'dnode' nor the 'path' modules, but it does find the 'url' module.

preload.js:

const { ipcRenderer } = require('electron');
const url = require('url');
const dnode = require('dnode'); // It breaks here with 'Error: module not found: dnode'

process.once('loaded', () => {
  window.addEventListener('message', event => {
    const message = event.data;

    if (message.myTypeField === 'handler') {
      // TO-DO
    }

  });
});

main.js

const url = require('url');
const path = require('path');

const {app, ipcMain, BrowserWindow} = require('electron');

let mainWindow;

app.on('ready', () => {
    mainWindow = new BrowserWindow({
        backgroundColor: '#fff',
        webPreferences: {
            preload: path.join(__dirname, './preload.js'),
            nodeIntegration: false,
            enableRemoteModule: false,
            contextIsolation: true,
            sandbox: true
        }
    });

    mainWindow.loadURL(url.format({
        pathname: path.join(__dirname, 'index.html'),
        protocol:'file:',
        slashes: true
    }));

});

My main.js finds the 'path' and 'dnode' modules tho, I've tried changing preload.js to the root directory of the project next to the node_modules folder and It didn't work.

Pitipaty
  • 279
  • 7
  • 21

3 Answers3

9

I'm pretty sure that's because you're sandboxing your window.

See the docs (original on web.archive.org, current):

With this option enabled, the renderer must communicate via IPC to the main process in order to access node APIs.

...

A sandboxed renderer doesn't have a Node.js environment running and doesn't expose Node.js JavaScript APIs to client code. The only exception is the preload script, which has access to a subset of the Electron renderer API.

If you truly need your renderer process to be sandboxed, then you must instead require ipcRenderer and use its send function to communicate to the main process that can then require all your fancy node modules and send some response back through your preload.

snwflk
  • 3,341
  • 4
  • 25
  • 37
pushkin
  • 9,575
  • 15
  • 51
  • 95
  • That's exactly what was happening, I really want to max security so I'll stick with sandbox. Thanks! – Pitipaty Nov 01 '19 at 02:41
7

if after setting contextIsolation:true,the problem still persist then set the sandbox: false option on your BrowserWindow to access Node APIs in your preload.

eons
  • 388
  • 4
  • 21
0

you should set nodeIntegration as true:

const mainWindow = new BrowserWindow({
  width: 800,
  height: 600,
  webPreferences: {
    preload: path.join(__dirname, 'preload.js'),
    nodeIntegration: true, // like here
    webSecurity: false
  },
});
Роман
  • 479
  • 6
  • 7