Home > Back-end >  How do you 'require' external modules in Electron with the new, secure, default settings?
How do you 'require' external modules in Electron with the new, secure, default settings?

Time:12-21

I have an Electron app from several years back that I'm trying to update to use the latest versions of Node, Electron, and all the external modules I've used. It's been a very frustrating experience as all the paradigms have shifted, especially around security, but I want to keep my app using the secure settings if possible.

From my understanding, the relevant default settings for Electron (I am using version 16.0.5) are

nodeIntegration: false
contextIsolation: true
sandbox: true

Here's what I have in my createWindow block:

const createWindow = () => {
  // Create the browser window.
  const win = new BrowserWindow({
      width: 1280,
      height: 720,
      webPreferences: {
        preload: path.join(__dirname, 'preload.js'),
      }
  });

  // and load the index.html of the app.
  win.loadFile('index.html');

  // Open the DevTools.
  win.webContents.openDevTools();
}

As you can see, I am not changing the defaults at all. This is desired, following the security instructions from the Electron website.

However, I've been completely unable to restore previous functionality of my app due to this. The biggest problem I'm having is that I can't figure out a way to require any external dependencies at all. As far as I understand it, the preload file can only require specific Electron modules, and normal renderer JavaScript files cannot require anything at all (you get a require() is not defined error). From what I understand from the documentation, the main.js file has normal require access and you are meant to use ipc to communicate between main.js and preload.js so that only your main process has full access to remote modules.

That's fine and dandy, except I can't even require anything in main.js leaving me extremely confused:

// in main.js
const google = require('googleapis');
App threw an error during load
Error: Cannot find module 'googleapis'

I've made sure I've yarn installed properly, have tried with different modules, changed the ordering, etc. I also have not been able to find a single example online of someone using the new default security settings but using require for external modules. Every single one of them uses require for built-in things and the preload.js file examples, either from Google or the official documentation, just show how you can expose basic built in stuff like window and document calls using preload.js which really isn't all that helpful.

So is it just not possible? I have to wonder what in the world the point of a Node/Electron app that can't use any public Node modules is, so if the default security settings preclude you from having an app that provides any sort of useful functionality, I don't know why they are the defaults. What am I missing? How can I get back to using external modules like googleapis and ffmpeg without disabling these apparently critical security features?

CodePudding user response:

It turns out that the reason I was having 'Cannot find module' errors was because I was using Yarn with pnp. Electron doesn't support packages not in the node_modules folder, see discussion on Yarn GitHub and semi-confirmation of issue on Electron GitHub

Switching to nodelinker: node-modules or nodelinker: pnpm to .yarnrc.yml in place of nodelinker: pnp solves it.

This still only partially helps me as I have to figure out how to allow sandboxed renderers and preloads access to external module methods, but it's a starting point and solves my initial frustration of "wait--you can't require anything external?"

  • Related