Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I register a Service Worker in Electron when node integration is enabled in workers?

I am trying to register a service worker in a simple Electron app (for reproduction you can use https://github.com/Robinfr/electron-react-typescript) but it keeps crashing. More specifically, the window opens but then the DevTools always crash and get disconnected, hence the application does not load.

I am trying to use the service worker to intercept networks requests which I need for an app I am working on.

I found that the problem occurs in particular when you enable node integration in workers, via nodeIntegrationInWorker. When this option is disabled it works and I can install a SW. However, when you enable this option, everything falls apart.

To reproduce this you can clone the boilerplate from above and use the following window configuration:

new BrowserWindow({
  width: 800,
  height: 600,
  webPreferences: {
    nodeIntegration: true,
    sandbox: false,
    nodeIntegrationInWorker: true // <-- this causes the DevTools to crash
  }
});

Also you have to modify the webpack.renderer.dev.config.js and add the following options to the devServer:

contentBase: path.resolve(__dirname, 'public'),
watchContentBase: true,

Then, create a folder called public in the root of the project and add a file called sw.js.

The problem is that for the app I am working on I not only the a SW but also node inside web workers. So I need to find a solution to this problem.

I have spent some time looking for similar issues but I cannot find anything, especially not a solution to my problem.

And ideas?

like image 740
LordTribual Avatar asked Oct 27 '25 05:10

LordTribual


1 Answers

I have finally figured out how to use a service worker if node integration is enabled for both the renderer thread as well as workers. Took me a while but you can achieve this with the webview tag, see the Documentation. According to the Chromium documentation, the webview tag can be used to:

[...] embed 'guest' content (such as web pages) in your Chrome App. The guest content is contained within the webview container; an embedder page within your Chrome App controls how the guest content is laid out and rendered.

So it's similar to an iframe, but a webview runs in a separate process than your app. It doesn't have the same permissions as your web page and all interactions between your app and embedded content will be asynchronous.

In Electron, a webview is not treated as a worker and because it's in a different process, meaning is not running in the renderer thread, it doesn't have access to node APIs if node integration is enabled for the renderer and workers. There is an option to enable this also for a webview but in my case I specifically didn't want node access, because somehow that was always causing my Electron app to crash.

My Solution:

Embed a webview onto the page that loads an HTML file which registers the SW.

This seems to be working, but I have to admit that I am still unsure why exactly Electron crashes if you try to register a SW in the renderer thread if node integration is enabled. Maybe it has something to do with the fact that native Node modules have been written assuming a single-threaded environment. Here an excerpt from their docs on multithreading.

Any native Node.js module can be loaded directly in Web Workers, but it is strongly recommended not to do so. Most existing native modules have been written assuming single-threaded environment, using them in Web Workers will lead to crashes and memory corruptions.

like image 70
LordTribual Avatar answered Oct 28 '25 20:10

LordTribual



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!