Search code examples
javascripturlcross-domainweb-worker

Cross domain worker url, how to make it work?


I have been trying to make cross domain worker url work, this might be a duplicate question but I couldn't make any solution to work, here is what I am doing:

  const url = new URL('./worker/a.worker.js', import.meta.url);
  const workerBlob = new Blob([
      'importScripts(' + JSON.stringify(url) + ')',
    ], { type: 'application/javascript' });
  const blobUrl = window.URL.createObjectURL(workerBlob);
  this.WasmVisionWorker = new Worker(blobUrl);

This is throwing error - *

Cannot use import statement outside a module at ....

Basically, in my worker I am importing different scripts using ES6 'import' i.e.

import scan from '../scan.js';

I read here - ES modules in service workers

to use import statements, we have to provide - type: 'module' while creating new worker:

this.WasmVisionWorker = new Worker(blobUrl, {type: 'module');

With this, getting error - cannot use 'importScripts()' with modules, should be related to this:

const workerBlob = new Blob(['importScripts(' + JSON.stringify(url) + ')',
    ], { type: 'application/javascript' });

What am I doing wrong?


Solution

  • If your worker script really is stored in an other domain, then what your "loader" script should look like to load a module script is

    import "${ url }";
    

    So with everything:

    const url = new URL('./worker/a.worker.js', import.meta.url);
    const workerBlob = new Blob([`import "${ url }"`], { type: 'text/javascript' });
    const blobUrl = window.URL.createObjectURL(workerBlob);
    this.WasmVisionWorker = new Worker(blobUrl, { type: 'module' });
    

    This will load your script as a module script.

    However note that your script must be sent with the appropriate Access-Control-Allow-Origin headers for this to work (the same would be true in non Worker environment).