Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Importing classes from files that import other classes results in failed compile for Angular 8 when using WebWorker

I am using Angular v8. I have a file called model.ts that looks like the following.

import {map} from 'rxjs/operators';

export class Person {
 constructor() { }
}

I then have a WebWorker file called test.worker.ts that looks like the following.

/// <reference lib="webworker" />
import {Person} from './bo/model';

addEventListener('message', ({ data }) => {
  const response = `worker response to ${data}`;
  postMessage(response);
});

When I type in ng compile I get the following ERROR.

ERROR in ./src/app/test.worker.ts (./node_modules/worker-plugin/dist/loader.js!./src/app/test.worker.ts)
Module build failed (from ./node_modules/worker-plugin/dist/loader.js):
Error: node_modules/rxjs/internal/types.d.ts(45,13): error TS2339: Property 'observable' does not exist on type 'SymbolConstructor'.

    at AngularCompilerPlugin._update (/Users/jwayne/my-app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:767:31)
    at processTicksAndRejections (internal/process/task_queues.js:89:5)
    at async AngularCompilerPlugin._make (/Users/jwayne/my-app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:658:13)

If I comment out import {map} from 'rxjs/operators', then I can compile. Are there limitations on importing libraries that import other libraries?

Interestingly, if I do this import import {HttpClient} from '@angular/common/http'; then I get a different error as follows.

ERROR in ./src/app/test.worker.ts (./node_modules/worker-plugin/dist/loader.js!./src/app/test.worker.ts)
Module build failed (from ./node_modules/worker-plugin/dist/loader.js):
Error: node_modules/@angular/core/core.d.ts(1470,29): error TS2304: Cannot find name 'Element'.
node_modules/@angular/core/core.d.ts(1471,29): error TS2304: Cannot find name 'Element'.
node_modules/@angular/core/core.d.ts(1538,26): error TS2304: Cannot find name 'Node'.
node_modules/@angular/core/core.d.ts(1539,29): error TS2304: Cannot find name 'Node'.
node_modules/@angular/core/core.d.ts(7082,33): error TS2304: Cannot find name 'Node'.
node_modules/@angular/core/core.d.ts(8711,81): error TS2304: Cannot find name 'HTMLElement'.
node_modules/@angular/core/core.d.ts(8822,15): error TS2304: Cannot find name 'HTMLElement'.
node_modules/@angular/core/core.d.ts(9753,62): error TS2304: Cannot find name 'Element'.
node_modules/@angular/core/core.d.ts(9755,62): error TS2304: Cannot find name 'Node'.
node_modules/@angular/core/core.d.ts(9778,59): error TS2304: Cannot find name 'Element'.
node_modules/@angular/core/core.d.ts(9820,82): error TS2304: Cannot find name 'HTMLElement'.
node_modules/@angular/core/core.d.ts(10214,83): error TS2304: Cannot find name 'HTMLElement'.
node_modules/@angular/core/core.d.ts(12863,20): error TS2304: Cannot find name 'Document'.
node_modules/@angular/core/core.d.ts(12866,13): error TS2304: Cannot find name 'HTMLElement'.
node_modules/@angular/core/core.d.ts(12874,20): error TS2304: Cannot find name 'Document'.
node_modules/@angular/core/core.d.ts(12877,13): error TS2304: Cannot find name 'Document'.
node_modules/@angular/core/core.d.ts(12885,20): error TS2304: Cannot find name 'Document'.
node_modules/@angular/core/core.d.ts(12888,13): error TS2304: Cannot find name 'Window'.

    at AngularCompilerPlugin._update (/Users/jwayne/my-app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:767:31)
    at processTicksAndRejections (internal/process/task_queues.js:89:5)
    at async AngularCompilerPlugin._make (/Users/jwayne/my-app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:658:13)

Even more interesting, if import import {Observable, of} from 'rxjs'; then I get absolutely no errors! What's going on here?

Note that I am using ng-cli v8.0.2.

like image 412
Jane Wayne Avatar asked Oct 27 '22 13:10

Jane Wayne


1 Answers

I'm not sure what the issue is with the rxjs/operators import, but I know what the issue is with the HttpClient import.

The problem is that Web Workers cannot access the DOM (https://stackoverflow.com/a/58414760/10452581). You can't use @angular/common since it accesses the DOM. I'm dealing with a similar issue (I'm trying to use pipes in my worker, which import from @angular/common). It's quite frustrating since the methods and classes of @angular/common I'm using have nothing to do with the DOM. The only potential solution I've found so far is to do what work you need to do with the libraries that manipulate the DOM outside of the worker (if possible).

TL;DR: You can't access the DOM in the web worker or even use libraries that access it, so do it outside of the worker if possible.

edit: as a better explanation, it is not just that web workers cannot access the DOM, they cannot have access to the DOM for thread safety. (https://stackoverflow.com/a/56715738/10452581) and (https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#about_thread_safety).

like image 131
Danny Diesel Avatar answered Nov 12 '22 15:11

Danny Diesel