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 install
ed 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?"