Embed the Web Worker's external JS code to the main file -possible?

This is the first time I lay hands on Web Workers, I have recreated the webgl worker offscreencanvas example locally to experiment with Web Workers using modules and a bundler and it works, but is it possible to eliminate the external Web Worker JS file completely and embed its code to the main file?

eg, instead of:

const worker = new Worker('./offscreen.js', { type: 'module' } );

…convert the offscreen.js code to stringUrl and pass that to the Worker function.

I know how to stringify objects, but that’s JS code, not just objects, so JSON.stringify() doesn’t work.

Or perhaps there is a more direct alternative.

The reason:
On this example 3 files are required: a scene.js file, an offscreen.js (worker) file and the main JS file. Both the offscreen.js and the main JS file have to import the scene.js file.
If the offscreen.js code will be embedded on the main js file, then the 3 JS files can merge to a single JS file.

The Web Worker API does require a script that it can find at some given URL, at least until/unless proposals like GitHub - tc39/proposal-js-module-blocks are accepted. If you don’t want to, or can’t, include a separate file, the only other option I’m aware of is to stringify a specific function:

function MyWorker () {

  // ... worker code here ...

}

const fn = MyWorker.toString();
const fnBody = fn.substring( fn.indexOf( '{' ) + 1, fn.lastIndexOf( '}' ) );
const workerSourceURL = URL.createObjectURL( new Blob( [ fnBody ] ) );
const worker = new Worker( workerSourceURL );

Certain three.js loaders, like DRACOLoader and KTX2Loader, use this approach.

But unfortunately this has some significant limitations:

  1. Only the content of the function is serialized, not its scope. So you can’t refer to external variables, classes, or modules.
  2. The worker script is a Blob URL, so you can’t use relative imports inside it (javascript - Using importsScripts within Blob in a karma environment - Stack Overflow). Absolute imports still work.
  3. Blob URLs may require configuration changes if you’re using a Content Security Policy (CSP).
1 Like

Thanks donmccurdy! That’s very useful! :+1:

Maybe you need to see worker-loader.

yarn add worker-loader

emm… i have a example :

@puxiao Nice work, congrats! :+1:
Although In my case I’m not sure whether I’ll use OrbitContols in my non-VR version yet (I have a different, custom approach in mind), it’s definitely a useful contribution and example, thanks!