Search code examples
javascriptweb-worker

Import classic script and module in web worker


I'm trying to work with web workers and I need to be able to import dynamically classic scripts and also modules scripts. So I need to do something like this:

new Worker("worker1.js", { type: "module" });

In my worker :

importScripts('/scripts/classic.js');
import('/scripts/module.js').then((module) => {
    // Something
});

The problem is that it seems impossible to use importScripts in a module worker since I get the following error: Failed to execute 'importScripts' on 'WorkerGlobalScope': Module scripts don't support importScripts()

Would there be a solution to do what I want or I am forced to choose between importing classic scripts or importing modules scripts ?


Solution

  • Indeed, from a module Worker the importScripts() method is not available.
    It is indeed expected that when you are in a module script, all your dependencies will adhere to ESM too.

    However it's quite surprising to see that the code you do use would actually work, in a classic worker.
    There, the dynamic import() method will be available, along with the traditional importScripts() one:

    const makeScriptURL = (content) => {
      const blob = new Blob([content], { type: "text/javascript" });
      return URL.createObjectURL(blob);
    }
    
    const moduleScriptURL = makeScriptURL(`
      export const foo = "bar";
    `);
    
    const defaultScriptURL = makeScriptURL(`
      self.bar = "baz";
    `);
    
    const workerURL = makeScriptURL(`
      importScripts("${defaultScriptURL}");
        import("${moduleScriptURL}")
          .then(({foo}) => postMessage({foo, bar}))
          .catch((err) => postMessage(err.message));
    `);
    
    const worker = new Worker(workerURL);
    worker.onmessage = ({data}) => console.log(data);
    worker.onerror = (evt) => console.error(evt.message);

    However note that the browser support for dynamic import() in a classic Worker is the same as module Worker support (i.e no Firefox yet).