Angular CLI使用Web Workers生成应用程序

Enr*_*iol 28 web-worker angular

阅读Angular文档,您可以找到几个引用Web Worker中的整个Angular应用程序的引用,因此您的UI不会被大量的JS使用阻止.

但是,目前还没有关于如何做到这一点的官方信息,以及Angular Doc中的唯一信息.这是一个实验性的功能.

我如何使用这种方法来利用Angular中的Web工作者?

Enr*_*iol 73

对于Angular 7,请参阅下面的答案.

我花了很多时间来弄清楚如何做到这一点,所以我希望这可以帮助别人.

前提条件

我假设你有一个使用Angular CLI 1.0或更高版本生成的Angular项目(版本2或4).

使用CLI生成项目并不是必须遵循此步骤,但我将提供的与webpack文件相关的说明基于CLI webpack配置.

脚步

1.解压缩webpack文件

从Angular CLI v1.0开始,就有"弹出"功能,它允许您提取webpack配置文件并根据需要进行操作.

  • 运行,ng eject以便Angular CLI生成webpack.config.js文件.

  • 运行npm install以便满足CLI生成的新依赖项

2.安装webworker引导程序依赖项

npm install --save @angular/platform-webworker @angular/platform-webworker-dynamic

3. UI线程引导程序的更改

3.1 app.module.ts中的更改

更换BrowserModuleWorkerAppModule在app.module.ts文件.您还需要更新import语句才能使用@angular/platform-webworker库.

//src/app/app.module.ts

import { WorkerAppModule } from '@angular/platform-webworker';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
//...other imports...

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    WorkerAppModule,
    //...other modules...
  ],
  providers: [/*...providers...*/],
  bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

3.2 src/main.ts的变化

用以下内容替换引导过程:( bootstrapWorkerUI也更新导入).

您需要传递一个URL,其中包含定义Web worker的文件.使用一个名为的文件webworker.bundle.js,不用担心,我们很快就会创建这个文件.

//main.ts

import { enableProdMode } from '@angular/core';
import { bootstrapWorkerUi } from '@angular/platform-webworker';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

bootstrapWorkerUi('webworker.bundle.js');
Run Code Online (Sandbox Code Playgroud)

3.3创建workerLoader.ts文件

  • 创建一个新文件src/workerLoader.ts.
  • 当你的Web工作将是一个包含所有需要的东西,一个单一的文件,你需要包括polyfills.ts,@angular/core@angular/common包.在接下来的步骤中,您将更新Webpack以便转换并构建包含结果的包.
  • 进口 platformWorkerAppDynamic
  • 导入AppModule(从main.ts中删除导入)并使用此platformWorkerAppDynamic平台引导它.

// workerLoader.ts

import 'polyfills.ts';
import '@angular/core';
import '@angular/common';

import { platformWorkerAppDynamic } from '@angular/platform-webworker-dynamic';
import { AppModule } from './app/app.module';

platformWorkerAppDynamic().bootstrapModule(AppModule);
Run Code Online (Sandbox Code Playgroud)

4.更新webpack以构建您的webworker

webpack自动生成的配置文件很长,但您只需要将注意力集中在以下方面:

  • 为我们的文件添加webworker入口点workerLoader.ts.如果查看输出,您会看到它将bundle.js前缀附加到所有块.这就是为什么在我们使用的引导步骤中webworker.bundle.js

  • 转到HtmlWebpackPlugin并排除webworker入口点,因此生成的Web Worker文件不包含在index.html文件中.

  • 转到CommonChunksPlugin,对于inline公共块,请明确设置条目块以防止webworker包含.

  • 转到AotPlugin并明确设置entryModule

// webpack.config.js

//...some stuff...
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CommonsChunkPlugin } = require('webpack').optimize;
const { AotPlugin } = require('@ngtools/webpack');
//...some stuff...

module.exports = {
  //...some stuff...
  "entry": {
    "main": [
      "./src/main.ts"
    ],
    "polyfills": [
      "./src/polyfills.ts"
    ],
    "styles": [
      "./src/styles.css"
    ],
    "webworker": [
      "./src/workerLoader.ts"
    ]
  },
  "output": {
    "path": path.join(process.cwd(), "dist"),
    "filename": "[name].bundle.js",
    "chunkFilename": "[id].chunk.js"
  },
  "module": { /*...a lot of stuff...*/ },
  "plugins": [
    //...some stuff...
    new HtmlWebpackPlugin({
      //...some stuff...
      "excludeChunks": [
        "webworker"
      ],
      //...some more stuff...
    }),
    new BaseHrefWebpackPlugin({}),
    new CommonsChunkPlugin({
      "name": "inline",
      "minChunks": null,
      "chunks": [
        "main",
        "polyfills",
        "styles"
      ]
    }),
    //...some stuff...
    new AotPlugin({
      "mainPath": "main.ts",
      "entryModule": "app/app.module#AppModule",
      //...some stuff...
    })
  ],
  //...some more stuff...
};
Run Code Online (Sandbox Code Playgroud)

你准备好了

如果您已正确遵循前面的步骤,那么现在只需要编译代码并尝试结果.

npm start

Angular应用程序的所有逻辑都应该在WebWorker中运行,从而使UI更流畅.

Furter指出

npm start运行webpack-dev服务器,webworkers在控制台日志上抛出错误消息时遇到了一些问题.无论如何,网络工作者似乎运行良好.如果您使用webpack命令编译应用程序并从任何http服务器(如simplehttpserver)提供它,则错误消失;)

示例代码和演示

您可以从此repo获取整个代码(webpack config,app.module.ts,...).

您还可以在此处观看实时演示,以查看是否使用Web Workers之间的差异

  • @MurhafSousli如果您使用的是material2,则无法使用webworker,因为它会调用很多来操作DOM.目前,材料2和网络工作者都不是首发. (2认同)