在使用 WebWorker 时,从导入其他类的文件中导入类会导致 Angular 8 编译失败

Posted

技术标签:

【中文标题】在使用 WebWorker 时,从导入其他类的文件中导入类会导致 Angular 8 编译失败【英文标题】:Importing classes from files that import other classes results in failed compile for Angular 8 when using WebWorker 【发布时间】:2019-10-23 11:35:44 【问题描述】:

我正在使用 Angular v8。我有一个名为 model.ts 的文件,如下所示。

import map from 'rxjs/operators';

export class Person 
 constructor()  

然后我有一个名为 test.worker.ts 的 WebWorker 文件,如下所示。

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

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

当我输入ng compile 时,我得到以下ERROR

./src/app/test.worker.ts (./node_modules/worker-plugin/dist/loader.js!./src/app/test.worker.ts) 中的错误 模块构建失败(来自 ./node_modules/worker-plugin/dist/loader.js): 错误:node_modules/rxjs/internal/types.d.ts(45,13):错误 TS2339:“SymbolConstructor”类型上不存在“可观察”属性。 在 AngularCompilerPlugin._update (/Users/jwayne/my-app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:767:31) 在 processTicksAndRejections (internal/process/task_queues.js:89:5) 在异步 AngularCompilerPlugin._make (/Users/jwayne/my-app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:658:13)

如果我注释掉import map from 'rxjs/operators',那么我可以编译。导入其他库的库是否有限制?

有趣的是,如果我这样做 import import HttpClient from '@angular/common/http'; 然后我得到一个不同的错误,如下所示。

./src/app/test.worker.ts 中的错误 (./node_modules/worker-plugin/dist/loader.js!./src/app/test.worker.ts) 模块构建失败(来自 ./node_modules/worker-plugin/dist/loader.js): 错误:node_modules/@angular/core/core.d.ts(1470,29):错误 TS2304:找不到名称“元素”。 node_modules/@angular/core/core.d.ts(1471,29):错误 TS2304:找不到名称“元素”。 node_modules/@angular/core/core.d.ts(1538,26):错误 TS2304:找不到名称“节点”。 node_modules/@angular/core/core.d.ts(1539,29):错误 TS2304:找不到名称“节点”。 node_modules/@angular/core/core.d.ts(7082,33):错误 TS2304:找不到名称“节点”。 node_modules/@angular/core/core.d.ts(8711,81):错误 TS2304:找不到名称“htmlElement”。 node_modules/@angular/core/core.d.ts(8822,15):错误 TS2304:找不到名称“HTMLElement”。 node_modules/@angular/core/core.d.ts(9753,62):错误 TS2304:找不到名称“元素”。 node_modules/@angular/core/core.d.ts(9755,62):错误 TS2304:找不到名称“节点”。 node_modules/@angular/core/core.d.ts(9778,59):错误 TS2304:找不到名称“元素”。 node_modules/@angular/core/core.d.ts(9820,82):错误 TS2304:找不到名称“HTMLElement”。 node_modules/@angular/core/core.d.ts(10214,83):错误 TS2304:找不到名称“HTMLElement”。 node_modules/@angular/core/core.d.ts(12863,20):错误 TS2304:找不到名称“文档”。 node_modules/@angular/core/core.d.ts(12866,13):错误 TS2304:找不到名称“HTMLElement”。 node_modules/@angular/core/core.d.ts(12874,20):错误 TS2304:找不到名称“文档”。 node_modules/@angular/core/core.d.ts(12877,13):错误 TS2304:找不到名称“文档”。 node_modules/@angular/core/core.d.ts(12885,20):错误 TS2304:找不到名称“文档”。 node_modules/@angular/core/core.d.ts(12888,13):错误 TS2304:找不到名称“窗口”。 在 AngularCompilerPlugin._update (/Users/jwayne/my-app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:767:31) 在 processTicksAndRejections (internal/process/task_queues.js:89:5) 在异步 AngularCompilerPlugin._make (/Users/jwayne/my-app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:658:13)

更有趣的是,如果 import import Observable, of from 'rxjs'; 那么我绝对不会出错!这是怎么回事?

请注意,我使用的是 ng-cli v8.0.2。

【问题讨论】:

FWIW,我现在的一个解决方法是将所有依赖于这些外部库(包括 Angular 库)的代码重构到它们自己的文件中。我意识到 Web Worker 正在自己的线程中运行,因此它不与 Angular 应用程序共享内存;尽管您可以导入类,但状态会丢失,您必须将它们序列化到网络工作者并再次重新创建/实例化对象。 我想知道您是否可以将您的工作作为要点分享。 【参考方案1】:

我不确定rxjs/operators 导入有什么问题,但我知道HttpClient 导入有什么问题。

问题是 Web Workers 无法访问 DOM (https://***.com/a/58414760/10452581)。您不能使用@angular/common,因为它会访问 DOM。我正在处理一个类似的问题(我试图在我的工作人员中使用管道,从@angular/common 导入)。这很令人沮丧,因为我使用的 @angular/common 的方法和类与 DOM 无关。到目前为止,我发现的唯一可能的解决方案是使用在 worker 之外操作 DOM 的库(如果可能的话)做你需要做的工作。

TL;DR:您无法在 web worker 中访问 DOM,甚至无法使用访问它的库,因此请尽可能在 worker 之外进行。

edit:作为一个更好的解释,网络工作者不仅不能访问 DOM,他们也不能访问 DOM 以保证线程安全。 (https://***.com/a/56715738/10452581) 和 (https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#about_thread_safety)。

【讨论】:

以上是关于在使用 WebWorker 时,从导入其他类的文件中导入类会导致 Angular 8 编译失败的主要内容,如果未能解决你的问题,请参考以下文章

html5 的web worker中不能用jq

Web Worker 案例

如何从上下文中获取bean?

Python从导入的模块中获取类的行号

(转载)WebWorker是什么鬼?

IE 11、XMLHttpRequest、xhr.upload 未在 Webworker 中设置