Angular 7.0.1中的Web Worker设置

23

我正在尝试在我的现有Angular 7.0.1项目(中型项目)中设置Web Worker。 在查看以下链接后,我完成了设置:

以下是我对每个文件进行的更改:

./src/main.ts

import 'zone.js';
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();
}

console.log("main.ts file loaded!");
bootstrapWorkerUi('webworker.js');

./src/workerLoader.ts

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

console.log("workerLoader.ts file loaded!");

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

platformWorkerAppDynamic().bootstrapModule(AppModule);

./angular.json

"projects": {
  "[project name]": {
    "architect": {
      "build": {
        "builder": "@angular-builders/custom-webpack:browser",
        "options": {
          "customWebpackConfig": {
            "path": "./extra-webpack.config.js"
          }
          ...
          ...
        }
      }
    }
  }
}

./extra-webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    "entry": {
        "webworker": [
            "./src/workerLoader.ts"
        ]
    },
    "plugins": [
        new HtmlWebpackPlugin({
            "excludeChunks": [
                "webworker"
            ],
        })
    ],
    "output": {
        "globalObject": 'this'
    }
}

./tsconfig.json

:这是 TypeScript 项目的配置文件,它描述了编译器如何编译 TypeScript 代码。
{
    ...
    ...
    "angularCompilerOptions": {
        "entryModule": "./app/app.module#AppModule"
    }
}

这里是演示。你可能想要查看我的研究笔记

我可能走了完全错误的方向,因为我只需要在 Angular 项目中包含并运行一个 angular service worker 库(应该非常容易)。

我尝试包含 webworker 的主要目的是让 Web 应用程序在多线程上运行,以便屏幕上的动画、复选框、自定义下拉框和滚动效果可以顺畅地执行。


2
喜欢你的研究笔记哈哈, - Milad
@Mr_Green 我也遇到了同样的问题。似乎代码没有在 worker 上运行。workerLoader.ts 文件已加载!日志未执行。你有什么进展吗? - Serginho
@Serginho 不是的...幸运/不幸的是,这已经不再是必要条件了。 - Mr_Green
我记得在一个Angular4(Ionic 3项目)中使用了WebWorker,但是我将该worker作为独立的javascript文件,并手动注入到index.html中...或者类似这样...不幸的是,我无法提供更具体的信息,因为这是我以前的工作,现在我无法访问代码。 - distante
1个回答

4

以下是我回答此问题的副本:

好消息,大家,我已经成功在Angular 7中实现了这个!

要求npm install --save-dev @angular-builders/custom-webpack html-webpack-plugin请确保您的env文件中有production:true,如果您只想从下面复制/粘贴代码。

步骤1:按照以下方式编辑您的angular.json文件:

"architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
                "path": "./webpack.client.config.js",
                "replaceDuplicatePlugins": true
             },
            ...
          }

你只需要编辑build这一部分,因为在开发服务器中你不太需要整个worker。 步骤2:在项目根目录下创建webpack.client.config.js文件。如果你不使用SSR,可以移除exclude: ['./server.ts'],
const path = require('path');
const webpack = require('webpack');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const { AngularCompilerPlugin } = require('@ngtools/webpack');

module.exports = {
  entry: {
    webworker: [
      "./src/workerLoader.ts"
    ],
    main: [
      "./src/main.ts"
    ],
    polyfills: [
      "./src/polyfills.ts"
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      excludeChunks: [
        "webworker"
      ],
      chunksSortMode: "none"
    }),
    new AngularCompilerPlugin({
      mainPath: "./src/main.ts",
      entryModule: './src/app/app.module#AppModule',
      tsConfigPath: "src/tsconfig.app.json",
      exclude: ['./server.ts'],
      sourceMap: true,
      platform: 0
    }),
  ],
  optimization: {
    splitChunks: {
      name: "inline"
    }
  }
}

步骤三:编辑您的 AppModule:

import { BrowserModule } from '@angular/platform-browser'
import { WorkerAppModule } from '@angular/platform-webworker'

const AppBootstrap =
            environment.production
            ? WorkerAppModule
            : BrowserModule.withServerTransition({ appId: 'myApp' })

    imports: [
        ...
        AppBootstrap,
        ...
    ]

步骤4:编辑您的main.ts文件。

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
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');
}

else {
  document.addEventListener('DOMContentLoaded', () => {
    platformBrowserDynamic().bootstrapModule(AppModule);
  });
}

第五步: 编译程序没有问题,但是由于应用中的DOM操作可能会导致运行时问题。此时,您只需要删除任何DOM操作,并将其替换为其他内容即可。我还在努力弄清楚这一部分,并将在以后编辑我的答案,以解决这个问题。

如果您没有进行过多的DOM操作,那么使用免费的主线程并使用Lighthouse审核您的应用程序时不应再显示最小化主线程工作,因为除UI以外的大部分应用程序都在第二个线程中加载。


1
你错过了创建 workerLoader.ts 文件的步骤!请参考 https://blog.angularindepth.com/angular-with-web-workers-step-by-step-dc11d5872135。 - Guido Dizioli
@GuidoDizioli 的链接已经失效,请知道新链接的话请更新。 - Mr_Green

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接