Fixing cesiumWorkerBootstrapper when using Electron+React+Webpack

When using Cesium in React via Webpack in Electron with the BrowserWindow option nodeIntegrationInWorker: true, Cesium throws exceptions in cesiumWorkerBootstrapper as require() becomes the nodejs implementation, not the requirejs implementation (assuming I'm interpreting the errors and execution correctly).

Unfortunately the example Electron app shown in the blog post below didn't have the issue so I'm assuming it's something more like the combination of React and/or Webpack in combination with Electron.

https://cesium.com/blog/2016/04/04/an-introduction-to-cesium-desktop-apps-with-electron/

I need to run my own web worker code with node integration in Electron, but setting the value causes Cesium to fail in our setup (which is obviously complicated). We're using npm: cesium@1.42.1, Win10 x64, Electron 1.8.1 (Chrome 59.0.3071.115).

The fix was to simply set the following line near the start of the minified cesiumWorkerBootstrapper.js from:

var requirejs, require, define;

to

var requirejs = undefined, require = undefined, define = undefined;

Whilst the original code probably exists to avoid multiple redefines of require, in cesium's web worker context it should be fine to explicitly reset the variables to undefined as they're isolated, thus fixing the issue here and not affecting existing consumers.

If I'm on the right track, any chance this could be changed upstream? If I've grossly misinterpreted the situation, please let me know what ramifications this may have :slight_smile:

Hi there,

Have you seen to Cesium and Webpack tutorial? We walk through getting Cesium up and running with webpack and the recommended configuration.

In particular specifying this in your webpack configuration object should “fix” how requireJS is being built with webpack in Cesium:

amd: {
    // Enable webpack-friendly use of require in Cesium
    toUrlUndefined: true
},

Enter code here…

Thanks, hopefully that helps!

Gabby

Hi Gabby,

Yep followed everything in that tutorial and I double-checked my webpack config just in case. It definitely didn't work without the config shown in that tutorial so the current issue is something else unfortunately.

Cheers,
Stuart

OK, if you have a fix and want to open a pull request with your changes, we’d be happy to take a look at them!

Thanks,

Gabby

Thanks Gabby,

I’ll try to isolate the exact issue so there is a clearer bug report / pull request for review.

Cheers,

Stuart

We are running into the same issue with cesiumWorkerBootstrapper and Electron with nodeIntegrationInWorker: true, however, we are not using Webpack, but rather the minified build output at node_modules/cesium/Build/Cesium/Cesium.js. We can apply the fix in an ad-hoc fashion as part of our build (hacky). I could not find a PR resulting from this discussion. Is cesiumWorkerBootstrapper ever intended to run in a node context rather than a browser context?

No, the Cesium’s use of web workers were designed for use in a browser. Processes that use web workers, like creating geometry, normally have a “asynchronous” option that you can set to false, which allows them to run as part of the main thread without attempting to spin up a we worker.

I'm not familiar with how that file is generated, but the issue is that requirejs (or whatever sets up requirejs) does not replace functions like 'require' if they already exist (the node context's 'require' function already exists). In cesiumWorkerBootstrapper's case it should, because nothing but Cesium code is running within Cesium's own web worker.

In our app we simply turned off 'nodeIntegrationInWorker' in Electron (because what we were using it for is running into a separate Electron bug) and it works. However, I expect we will want it back on as soon as Electron fixes their issue.

I’m confused what the setup is here exactly. People have had success running Cesium in Electron with and without webpack. Can you provide your configuration and what Cesium files you are including?

This doesn’t necessarily have anything to do with Electron. However, using nodeIntegrationInWorker: true will provide a nodejs context within the Web Worker, meaning that 'require()` and other node items are already present on the global ‘self’ object when cesiumWorkerBootstrapper.js loads.

Since cesiumWorkerBootstrapper.js only ever needs the browser context, it shouldn’t be so careful about replacing functions that already exist. It should just overwrite them and set itself up. This would be a bad idea in the main thread, but in a worker which has nothing running alongside it, it should be fine.

Ideally, Electron would also provide a way to select which workers get node integration, rather than just blanket providing it for everything.