Search code examples
webpackweb-worker

Bundle Worker with Webpack 5 without starting the worker


I want to bundle a WebWorker script using Webpack 5. The way to do this given the current documentation is:

const worker = new Worker('./path_to_worker.js', import.meta.url)

However I want to start the worker in a different context of where I defined it. I want to get the url string for the worker and actually start it elsewhere.

const workerUrl = ... get webpack bundled path to worker...


... somewhere else in the code ...
let worker = new Worker(workerUrl)

Dynamic imports could generate the bundle for the Worker, but I am unable to get the url of the imported script so I can pass it to the worker constructor at later moment in the program execution.

How would I be able to do this?


Solution

  • This horrible hack is the best I could come up with at the present time:

    function getWorkerUrl() {
    
        class FakeWorker {
           constructor(url: string | URL) {}
        }
    
        let oldWorker = self.Worker
    
        // override the default Worker class temporarily to prevent the worker from launching
        //@ts-ignore
        self.Worker = FakeWorker
    
        // this will generate the worker bundle with a specified name 
        let worker = new Worker(new URL("./worker.ts" /* webpackChunkName: 'bundle-worker.js' */, import.meta.url))
    
        // determine the path to the bundle
        const url = './path_to_js/bundle-worker.js'
    
        // restore the original Worker api
        self.Worker = oldWorker
    
        return url
    }