I already have Workers in my Angular app. But I'm trying to create a Shared Worker, and it fails, saying "Failed to fetch a worker script." in the console.
const worker = new SharedWorker('../../../workers/my.shared.worker', { name: 'mySharedWorker', type: 'module' });
If I replace SharedWorker with Worker - it works perfectly.
Of course, I made everything as needed. Created an additional .tsconfig file:
/// tsconfig.worker.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/worker",
"lib": [
"es2018",
"webworker"
]
},
"include": [
"src/workers/*.worker.ts"
]
}
And added webWorkerTsConfig to angular.json config:
projects.myProject.architect.build.options.webWorkerTsConfig: "tsconfig.worker.json"
I found this article by Nikita Barsukov but it works only if your Worker is stored as a single file in the assets folder. But my SharedWorker contains dozen of .ts files, that should be bundled just like an ordinary Worker.
Seems Angular-CLI now (as for v10.0.7) supports Workers only. But not SharedWorkers.
Angular-CLI uses worker-plugin under the hood. And actually, it can load SharedWorkers, but it should be enabled in WebpackConfig.
So there are two options.
Use @angular-builders/custom-webpack and add sharedWorker parameter to WorkerPlugin in custom webpack config. But I was unable to make it work.
Use custom-webpack loader (this options works for me):
import workerUrl from 'worker-plugin/loader?name=mySharedWorker!../../../workers/my.shared.worker.ts';
// ....
const worker = new SharedWorker(workerUrl, { name: 'mySharedWorker', type: 'module' });
Where name=mySharedWorker is the name of future bundle file. If you omit it, it will use something like 0.worker.js, but it can cause a collision with ordinary Worker bundling because it'll use the same name. So always specify the name of your bundle in loader params.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With