electron: 'nodeIntegrationInWorker' no longer affects worklets, enabling node integration and 'require' impossible? (regression)

Preflight Checklist

  • I have read the Contributing Guidelines for this project.
  • I agree to follow the Code of Conduct that this project adheres to.
  • I have searched the issue tracker for an issue that matches the one I want to file, without success.

Issue Details

  • Electron Version: 8.0.3 7.0.0 to 11.x
  • Operating System: Windows 10 (1909)
  • Last Known Working Electron version: 4.0.0-beta.4 6.1.9

Expected Behavior

Given a worklet thread, such as an AudioWorklet thread (AudioWorkletGlobalScope), spawned from a BrowserWindow main thread that has both nodeIntegration and nodeIntegrationInWorker enabled, require should work exactly as it does in regular web workers (i.e. DedicatedWorkerGlobalScope) and node integration should be generally available.

Actual Behavior

Unlike in regular worker threads, node integration no longer gets enabled in worklet threads, and calling require results in the following error message:

'require' is not defined.

To Reproduce

Reproducing the issue itself is very simple, but it involves some setup.

Spawn a BrowserWindow process with nodeIntegration and nodeIntegrationInWorker enabled, and from within, inside an AudioWorklet, attempt to call require. This will result in an error, as node integration fails to become enabled in AudioWorklet threads (I assume every worklet thread is affected).

I understand this may not be trivial to setup, and as such I’ll try to put together a complete example if I have the time. For the time being, reproducing the issue itself is as simple as calling require from an AudioWorklet thread, which (unlike a require call from a regular web worker thread) will throw due to being missing.

Additional Information

The current workaround is to revert to an older version of Electron, which is a solid confirmed fix. As of yet I’m unsure when this broke, but I know for certain that it used to work in 4.0.0-beta.4. I’ll keep this issue updated.

I also know for certain that the availability of require (and co) in worklets used to be influenced by the nodeIntegrationInWorker setting before, identical to regular workers.

Edit: this still works in 6.0.0

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 4
  • Comments: 23 (4 by maintainers)

Most upvoted comments

For what it’s worth my experience with AudioWorklets in Electron v13 matches that described by @marcelblum for v12.

I’m currently using Electron v13.1.7 but I’ve seen the same behavior for a while. IIRC it started with Electron v7 but was not an issue in v6.

I’ve got nodeIntegrationInWorker set to true and I’m using several AudioWorkletProcessor implementations that are bootstrapped more or less like Marcel’s example (loading the raw source code for the worklet as a blob and taking pains to ensure each AudioWorkletProcessor-implementing class is only registered (via registerProcessor) once as I’m pretty sure I ran into problems without that).

I’m able to require external modules (package.json dependencies) in my worklets without any problem. I’m not currently loading any local files - in part because I had trouble getting that to work consistently for packaged and un-packaged apps, but the absolute-path topic probably explains that. (To be clear, as it happens some of my worklets are completely dependency-free - no require calls at all - and exhibit the same symptoms, so I don’t think that require is a direct trigger.)

Each time registerProcessor is invoked for a new type of AudioWorkletProcessor a pair of error messages is logged:

electron/js2c/worker_init.js:121 Electron worker_init.js script failed to run
(anonymous) @ electron/js2c/worker_init.js:121

electron/js2c/worker_init.js:121 ReferenceError: self is not defined
    at Object.<anonymous> (electron/js2c/worker_init.js:97)
    at Object../lib/worker/init.ts (electron/js2c/worker_init.js:97)
    at __webpack_require__ (electron/js2c/worker_init.js:1)
    at electron/js2c/worker_init.js:1
    at electron/js2c/worker_init.js:1
    at NativeModule.compileForInternalLoader (internal/bootstrap/loaders.js:283)
    at NativeModule.compileForPublicLoader (internal/bootstrap/loaders.js:225)
    at loadNativeModule (internal/modules/cjs/helpers.js:35)
    at Module._load (internal/modules/cjs/loader.js:747)
    at Function.f._load (electron/js2c/asar_bundle.js:5)
(anonymous) @ electron/js2c/worker_init.js:121

The exact error message may have changed slightly from release to release of Electron, but it’s otherwise the exact same message and trace every time.

This happens once for each AudioWorkletProcessor implementation I invoke.

I don’t think this causes any other specific problem. I.e., as far as I know there are no side-effects other than these error messages appearing in the log. If that’s true this is more of an annoyance than a problem.

But the error itself is a little a confidence-shaking. Worklets seem a little fussy in general so (for me at least) it’s a little hard to tell if quirks I encounter in Electron (like needing to load the worklet as a Blob via createObjectURL) are working as intended or if they point to some underlying limitations or problems.

Is there any way (or anyone) to confirm that this is just a spurious error message that one can more-or-less ignore?

If it can help, running an app with nodeIntegrationInWorker: true, and using an AudioWorklet results in:

terminal:

[3860:0909/024426.701283:ERROR:CONSOLE(116)] “Request Network.enable failed. {“code”:-32601,“message”:”‘Network.enable’ wasn’t found"}", source: devtools://devtools/bundled/protocol_client/protocol_client.js (116)

webTools console:

Uncaught ReferenceError: self is not defined at Object…/lib/renderer/webpack-provider.ts (electron/js2c/worker_init.js:97) at webpack_require (electron/js2c/worker_init.js:1) at Object…/lib/worker/init.js (electron/js2c/worker_init.js:101) at webpack_require (electron/js2c/worker_init.js:1) at electron/js2c/worker_init.js:1 at electron/js2c/worker_init.js:1 at NativeModule.compileForInternalLoader (internal/bootstrap/loaders.js:279) at NativeModule.compileForPublicLoader (internal/bootstrap/loaders.js:219) at loadNativeModule (internal/modules/cjs/helpers.js:26) at Module._load (internal/modules/cjs/loader.js:852)

also, after reload no errors are logged (main nor renderer) and the html script is “half executed”

sorry for bad comment formatting, never commented before but I’d like to fix this issue

Can confirm still broken in 10.1.5, running on Linux (Ubuntu 20.04). Seeing the same logs as above https://github.com/electron/electron/issues/22503#issuecomment-689346726

Still broken in 10.1.3, which now forces worklet node integration to run on an Electron version that’s 4 major versions behind latest, because it’s been broken ever since. Anything we can do to help move this forward?

@arcusfelis nodeIntegrationInWorker is not broken. That’s just an apparently inconsequential error message that appears in the console. require in AudioWorklets still seems to be working fine as of latest Electron 20.1.4.

@nornagon sure here is a repro based on electron fiddle.

worklet_bug.zip

The errors happen when nodeIntegrationInWorker: true and a worklet is used. Doesn’t seem to effect to working of the worklet, just weird js errors pop in console:

electron/js2c/worker_init.js:121 Electron worker_init.js script failed to run
(anonymous) @ electron/js2c/worker_init.js:121
electron/js2c/worker_init.js:121 ReferenceError: self is not defined
    at Object.<anonymous> (electron/js2c/worker_init.js:97)
    at Object../lib/worker/init.ts (electron/js2c/worker_init.js:97)
    at __webpack_require__ (electron/js2c/worker_init.js:1)
    at electron/js2c/worker_init.js:1
    at electron/js2c/worker_init.js:1
    at NativeModule.compileForInternalLoader (internal/bootstrap/loaders.js:283)
    at NativeModule.compileForPublicLoader (internal/bootstrap/loaders.js:225)
    at loadNativeModule (internal/modules/cjs/helpers.js:35)
    at Module._load (internal/modules/cjs/loader.js:747)
    at Function.f._load (electron/js2c/asar_bundle.js:5)

Looks like this was fixed in the latest electron releases via #37041. Error message now gone, at least in my project using v.22.2.1 on Windows.

There is an issue with fixing the problem:

  • An init script inside electron is used to initialize node environment for worker thread (lib/worker/init.js or lib/worker/init.ts).
  • The script is used as well for any type of worklets, including AudioWorklet.
  • The script currently relies on location symbol of WorkerGlobalScope for proper module initialization. The path to js file with worker implementation from location allows to use __dirname and make require able to import modules by relative path.
  • location symbol is not exposed in any worklet scope (e.g. AudioWorkletGlobalScope), so there is no way to get the actual path of the module with worklet implementation and make require work as expected.

As a workaround that could be done, I proposed adding preloadInWorker option: the preload script can use node API without any limitation and define some functions with require inside to be used in the worklet scope. (see details https://github.com/electron/electron/issues/28620).