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 ?
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).