I can set the importmap type in a tag in the HTML file. But the web worker can not set access a dom element. How can I set importmap in it?
How can I set importmap in a web worker
594 Views Asked by Mixwind At
        	2
        	
        There are 2 best solutions below
0
                 On
                        
                            
                        
                        
                            On
                            
                                                    
                    
                We have done the approach by a small bypass via the ES shims (based on the example posted on 4th Nov 2022). Basically you start a worker, enable the worker by es shims to load modules and read these.
We use the item to run a raycaster on a three.js scene which is not visible, but should work generally.
workermanager.js:
let worker = new Worker('./workerloader.js');
worker.addEventListener("error", (e) => {
    console.error("the worker died");
    console.error(e);
})
worker.addEventListener("message", function(evt) {
    let result = evt.data;
    if (result === "loaded loader"){
         console.log("loaded the workerloaded");
    } else if (result === "Module worker Loaded")
        worker.postMessage("Init Message");
    else
        console.log(`message from worker: `, evt);
});
workerloader.js
const shimCodeUrl = "https://ga.jspm.io/npm:[email protected]/dist/es-module-shims.wasm.js"
const importMap = {
    "imports": {
        "three":"/whatever_path/three/build/three.module.js",
        "three/":"/whatever_path/three/"
    }
}
postMessage("loaded loader");
importScripts(shimCodeUrl);
importShim.addImportMap(importMap);
importShim("./worker.module.js") /*controllerworker.module.js*/
    .then((res) => {
        console.log("module has been loaded");
    })
    .catch(e => setTimeout(() => { throw e; }));
worker.module.js:
import * as THREE from "three";
class WorkerClass
{
    constructor()
    {
        console.log(new THREE.Vector3(0,1,2));
    }
    onMessage(event)
    {
        console.log(event.data);
    }
}
let workerclass = new WorkerClass();
self.addEventListener("message", evt => workerclass.onMessage(evt));
self.postMessage("Module worker Loaded");
First, thank you hsc for posting your answer. You helped me out a ton. Second, I just wanted to add one small thing that might make life easier for some folks.
I have basically the same structure, except that I am wrapping the import code in an event listener.
Then on my main thread script I am fetching my import map that I am already using and passing it on to the webworker. This is handy if you are looking for a quick means to ensure that both the webworker and the main thread have access to the same imports.