Is it possible to register a ServiceWorker written in TypeScript with @angular/service-worker?
currently registering a service worker looks like this in app.module.ts:
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: environment.production
})
Is it somehow possible to register a ngsw-worker.ts?
At least this is possible with web workers in Angular:
const worker = new Worker('../my-worker.worker', {
type: 'module'
});
my-worker.worker.ts
/// <reference lib="webworker" />
import {someMethod} from './some-method';
addEventListener('message', ({ data }) => {
const response = `worker response to ${data}`;
postMessage(response);
someMethod();
});
Any help is appreciated - thanks
As a beginner with Angular/TypeScript/Javascript I've tried the same for a few days. My intents were to use TypeScript as my main language to use it as an es5 transpiler, so I don't have to worry about:
And I think I've got a nice, yet weird solution with uses the worker-plugin, available starting with Angular8. Adjusted for Angular16.
First of all: you need to enable webworkers in angular and serviceworker. The angular.json then contains
"build": {
"options": {
"webWorkerTsConfig": "tsconfig.workers.json",
...
}
"configurations": {
"production": {
"serviceWorker": true,
"ngswConfigPath": "src/ngsw-config.json"
...
}
}
}
Note: This is only in production mode. Probably to keep browser/cache/install sideeffects away from ng serve. Somehow I've also lost this configuration during an ng update.
Allowing all kinds of web-workers
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/workers",
"lib": [
"es2018",
"webworker"
],
"types": []
},
"include": [
"src/**/*.worker.ts"
]
}
This is the example target code.
// Import angular serviceworker
importScripts("ngsw-worker.js");
// custom code
addEventListener("message", (data) => {
console.log(data);
});
Angular generates hashed names for its *.js output. We need to grab this name.
import { environment } from "../../environments/environment";
export let generatedServiceWorkerUrl: string = null;
(function generateUrl(): void {
// Override the real Worker with a stub
// to return the filename, which will be generated/replaced by the worker-plugin.
// @ts-ignore
Worker = class WorkerStub {
constructor(public stringUrl: string, public options?: WorkerOptions) {}
};
const worker = new Worker(new URL("./service-worker.worker", import.meta.url), { type: "module" }) as any;
generatedServiceWorkerUrl = worker.stringUrl;
})();
export const serviceWorkerConfig = {
enabled: environment.production,
serviceWorkerUrl: generatedServiceWorkerUrl
};
import { serviceWorkerConfig } from "./workers/service-worker-config";
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
[...],
ServiceWorkerModule.register(serviceWorkerConfig.serviceWorkerUrl, { enabled: serviceWorkerConfig.enabled })
],
providers: [...],
bootstrap: [AppComponent]
})
export class AppModule {}
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