From 6c4ca2d833981bd0f5570be4dfcb965254a13e0c Mon Sep 17 00:00:00 2001 From: Maxime Robert Date: Thu, 17 Dec 2020 13:41:19 +0100 Subject: [PATCH] show only what's really needed to use a web worker within a library --- angular.json | 2 + .../demo-lib-consuming-webworker.component.ts | 39 +++++++++++++++++-- .../src/lib/fibonacci.token.ts | 5 +++ .../fibonacci-webworker/src/lib/fibonacci.ts | 11 ++++++ .../fibonacci-webworker/src/public-api.ts | 1 + .../fibonacci-webworker/tsconfig.lib.json | 2 +- projects/fibonacci/src/lib/fibonacci.ts | 12 ++++++ src/app/app.component.html | 1 + src/app/app.module.ts | 36 ++++++++++++----- tsconfig.worker.json | 12 ++++++ 10 files changed, 108 insertions(+), 13 deletions(-) create mode 100644 projects/fibonacci-webworker/src/lib/fibonacci.token.ts create mode 100644 projects/fibonacci-webworker/src/lib/fibonacci.ts create mode 100644 projects/fibonacci-webworker/src/public-api.ts create mode 100644 projects/fibonacci/src/lib/fibonacci.ts create mode 100644 tsconfig.worker.json diff --git a/angular.json b/angular.json index a1320a7..ffc9628 100644 --- a/angular.json +++ b/angular.json @@ -22,6 +22,7 @@ "assets": ["src/favicon.ico", "src/assets"], "styles": ["src/styles.css"], "scripts": [], + "webWorkerTsConfig": "tsconfig.worker.json" }, "configurations": { "production": { @@ -90,6 +91,7 @@ "tsconfig.app.json", "tsconfig.spec.json", "e2e/tsconfig.json", + "tsconfig.worker.json" ], "exclude": ["**/node_modules/**"] } diff --git a/projects/demo-lib-consuming-webworker/src/lib/demo-lib-consuming-webworker.component.ts b/projects/demo-lib-consuming-webworker/src/lib/demo-lib-consuming-webworker.component.ts index 8e95fb7..aa093ca 100644 --- a/projects/demo-lib-consuming-webworker/src/lib/demo-lib-consuming-webworker.component.ts +++ b/projects/demo-lib-consuming-webworker/src/lib/demo-lib-consuming-webworker.component.ts @@ -1,7 +1,40 @@ -import { Component } from '@angular/core'; +import { Component, Inject } from '@angular/core'; +import { FIBONACCI_WEBWORKER_FACTORY } from 'fibonacci-webworker'; +import { interval } from 'rxjs'; @Component({ selector: 'lib-demo-lib-consuming-webworker', - template: ``, + template: ` +

+ Timer just to prove that the page isn't frozen while we compute fibonacci + (which it would if we were doing it on the main thread!): + {{ timer$ | async }} +

+ +
+

Fibonacci 45

+

{{ result | json }}

+
+ + + Computing fibonacci(45)... Be patient =)! + + `, }) -export class DemoLibConsumingWebworkerComponent {} +export class DemoLibConsumingWebworkerComponent { + public result; + + public timer$ = interval(1000); + + constructor( + @Inject(FIBONACCI_WEBWORKER_FACTORY) fibonacciWebworkerFactory: () => Worker + ) { + const fibonacciWebworker = fibonacciWebworkerFactory(); + + fibonacciWebworker.onmessage = ({ data }) => { + this.result = data; + }; + + fibonacciWebworker.postMessage(45); + } +} diff --git a/projects/fibonacci-webworker/src/lib/fibonacci.token.ts b/projects/fibonacci-webworker/src/lib/fibonacci.token.ts new file mode 100644 index 0000000..17d0c13 --- /dev/null +++ b/projects/fibonacci-webworker/src/lib/fibonacci.token.ts @@ -0,0 +1,5 @@ +import { InjectionToken } from '@angular/core'; + +export const FIBONACCI_WEBWORKER_FACTORY = new InjectionToken<() => Worker>( + 'fibonacci' +); diff --git a/projects/fibonacci-webworker/src/lib/fibonacci.ts b/projects/fibonacci-webworker/src/lib/fibonacci.ts new file mode 100644 index 0000000..db0a49d --- /dev/null +++ b/projects/fibonacci-webworker/src/lib/fibonacci.ts @@ -0,0 +1,11 @@ +/// + +// this file is excluded from the compilation of the `fibonacci-webworker` library +// this is due to the fact that an app has to import it directly (instead of a path +// coming from a ts alias path) + +import { fibonacci } from 'fibonacci'; + +addEventListener('message', ({ data }) => { + postMessage(fibonacci(data)); +}); diff --git a/projects/fibonacci-webworker/src/public-api.ts b/projects/fibonacci-webworker/src/public-api.ts new file mode 100644 index 0000000..75678fa --- /dev/null +++ b/projects/fibonacci-webworker/src/public-api.ts @@ -0,0 +1 @@ +export * from './lib/fibonacci.token'; diff --git a/projects/fibonacci-webworker/tsconfig.lib.json b/projects/fibonacci-webworker/tsconfig.lib.json index c754a25..e8118e4 100644 --- a/projects/fibonacci-webworker/tsconfig.lib.json +++ b/projects/fibonacci-webworker/tsconfig.lib.json @@ -15,5 +15,5 @@ "strictMetadataEmit": true, "enableResourceInlining": true }, - "exclude": ["src/test.ts", "**/*.spec.ts"] + "exclude": ["src/lib/fibonacci.ts", "src/test.ts", "**/*.spec.ts"] } diff --git a/projects/fibonacci/src/lib/fibonacci.ts b/projects/fibonacci/src/lib/fibonacci.ts new file mode 100644 index 0000000..ce91437 --- /dev/null +++ b/projects/fibonacci/src/lib/fibonacci.ts @@ -0,0 +1,12 @@ +// I've chosen a slow implementation of fibonacci on purpose +// so that it takes more time to run otherwise an optimised +// version could take less than 1s to compute fibonacci(3000) +// while this one will struggle with fibonacci(30) +// https://stackoverflow.com/questions/11287418/why-is-this-js-code-so-slow +export const fibonacci = (n) => { + if (n < 2) { + return n; + } else { + return fibonacci(n - 1) + fibonacci(n - 2); + } +}; diff --git a/src/app/app.component.html b/src/app/app.component.html index e69de29..0680b43 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -0,0 +1 @@ + diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f657163..542757c 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,16 +1,34 @@ -import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; - +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { FIBONACCI_WEBWORKER_FACTORY } from 'fibonacci-webworker'; import { AppComponent } from './app.component'; @NgModule({ - declarations: [ - AppComponent - ], + declarations: [AppComponent], imports: [ - BrowserModule + BrowserModule, + RouterModule.forRoot([ + { + path: '', + loadChildren: () => + import('demo-lib-consuming-webworker').then( + (m) => m.DemoLibConsumingWebworkerModule + ), + }, + ]), + ], + providers: [ + { + provide: FIBONACCI_WEBWORKER_FACTORY, + useValue: function (): Worker { + return new Worker('projects/fibonacci-webworker/src/lib/fibonacci', { + name: 'fibonacci.worker', + type: 'module', + }); + }, + }, ], - providers: [], - bootstrap: [AppComponent] + bootstrap: [AppComponent], }) -export class AppModule { } +export class AppModule {} diff --git a/tsconfig.worker.json b/tsconfig.worker.json new file mode 100644 index 0000000..9180bb5 --- /dev/null +++ b/tsconfig.worker.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/worker", + "lib": ["es2018", "webworker"], + "types": [] + }, + "include": [ + "src/**/*.worker.ts", + "projects/fibonacci-webworker/src/lib/fibonacci.ts" + ] +}