angular - 使用 WebPack 在 Web Worker 中运行 Angular 2 应用程序

标签 angular webpack web-worker angular-cli

我正在尝试将 Angular 2 应用程序的整个执行过程移交给网络 worker ,但我发现现在所有可用的示例都在使用 System.js,我正在尝试使用基于 WebPack 的项目(使用 angular-cli 构建)。

有没有人这样做过或知道如何使用 WebPack 做到这一点?

下面是我的 main.ts 引导文件:

import './polyfills.ts';


import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';


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

import {bootstrapWorkerUi} from '@angular/platform-webworker';
bootstrapWorkerUi('/app/loader.js');

我的 loader.js 看起来像这样:

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

platformWorkerAppDynamic().bootstrapModule(AppModule);

我的app.module.ts是这样声明@NgModule的:

import { NgModule } from '@angular/core';
import {WorkerAppModule} from '@angular/platform-webworker';


import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    WorkerAppModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
 export class AppModule { }

但是,当我运行它时,我在 loader.js:1 中收到错误 Uncaught SyntaxError: Unexpected token import

正如 Tamas Gegedus 和 MathMate 所建议的那样,该问题似乎与 webpack 以及在 webworker 端缺少@angular 库的导入有关,因此下一步是修改 webpack 配置文件以提供所有必需的库给网络 worker 。我会努力的。

------------ 更新 ----------

由于 angular-cli 不提供对 webpack.config.js 文件的访问,我已经包含了我的文件,对代码进行了一些小的改动,以便它可以工作。我在 webpack 配置文件中创建了第二个入口点,但出现错误 VM33:106 Uncaught ReferenceError: window is not defined

Webpack 配置文件如下所示:

var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var helpers = require('./config/helpers');


module.exports = {
  entry: {
    'app': ['./src/polyfills.ts', './src/vendor.ts', './src/main.ts'],
    'webworker': ['./src/workerLoader.ts']
  },

  resolve: {
    extensions: ['', '.ts', '.js']
  },

  output: {
    path: helpers.root('dist'),
    publicPath: 'http://localhost:8080/',
    filename: '[name].js'
  },

  devtool: 'cheap-module-eval-source-map',

  module: {
    loaders: [
      {
        test: /\.ts$/,
        loaders: ['awesome-typescript-loader?tsconfig=./src/tsconfig.json', 'angular2-template-loader']
      },
      {
        test: /\.html$/,
        loader: 'html'
      },
      {
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
        loader: 'file?name=assets/[name].[hash].[ext]'
      },
      {
        test: /\.css$/,
        exclude: helpers.root('src', 'app'),
        loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
      },
      {
        test: /\.css$/,
        include: helpers.root('src', 'app'),
        loader: 'raw'
      }
    ]
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: 'src/index.html',
      excludeChunks: ['webworker']
    }),

    new ExtractTextPlugin('[name].css')
  ]
};

其中 polyfills.ts 和 vendor.ts 分别包含 polyfills 和 Angular 库。

我创建了 2 个入口点,生成 2 个输出(app.js 和 webworker.js)。

对于 HtmlWebpackPlugin,第一个包含在 index.html 文件中,但第二个不包含。

当包含 index.html 时,调用 ma​​in.ts(包含在 app.js 中)并尝试使用 webpack (webworker.js) 的第二个输出来引导 webworker:

import {bootstrapWorkerUi} from '@angular/platform-webworker';
bootstrapWorkerUi('../webworker.js');

webworker.js 是由 webpack 使用 workerLoader.ts 条目生成的,这与之前的 loader.js 类似,但包括一些导入。

WorkerLoader.ts 文件如下所示:

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

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

platformWorkerAppDynamic().bootstrapModule(AppModule);

我知道已经生成了 web worker,如下图所示,但是如图所示,我得到错误 VM33:106 Uncaught ReferenceError: window is not defined,并且除了来自 index.html 的正在加载消息外,没有显示任何内容。 web worker instance

另一方面,我认为 webpack 配置没问题,因为如果在 NO webworker 模式下使用 webpack 运行应用程序,它工作正常。

现在我认为这个问题与 webworker bootstrap 有关,但我被困在这里。

任何帮助将不胜感激;)

最佳答案

我终于解决了这个问题:)

NOTE: if you have generated the project using Angular CLI 1.0 or higher, you can now use their own webpack config file, and that simplifies the whole process. Check this answer in that case.

在使用我的自定义 webpack 配置运行代码后,我意识到错误 VM33:106 Uncaught ReferenceError: window is not defined 是由 webpack-dev-server< 引起的/em>.

我是这样解决的:

1 - 进行独立的 webpack 构建

$: webpack --watch #this creates the bundes at myProject/dist

2 - 使用另一个开发服务器工具运行,例如 simplehttpserver

$: npm install simplehttpserver -g
$: simplehttpserver -p 8080 dist/ #as my webpack bundle is included in index.html using that port by default

瞧,错误消失了,它很简单!

应用于 angular-cli 项目的更改:Webpack 配置

让我总结一下关于原始 Angular-CLI 项目的 webpack 变化。

由于 angular-cli 不提供对 webpack.config.js 文件的访问,自定义 webpack 是使用 webworkers 的关键,我已经包含了我的,只做了一些小改动在代码中。

Webpack 配置文件如下所示:

var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var helpers = require('./config/helpers');


module.exports = {
  entry: {
    'app': ['./src/polyfills.ts', './src/vendor.ts', './src/main.ts'],
    'webworker': ['./src/workerLoader.ts']
  },

  resolve: {
    extensions: ['', '.ts', '.js']
  },

  output: {
    path: helpers.root('dist'),
    publicPath: 'http://localhost:8080/',
    filename: '[name].js'
  },

  devtool: 'cheap-module-eval-source-map',

  module: {
    loaders: [
      {
        test: /\.ts$/,
        loaders: ['awesome-typescript-loader?tsconfig=./src/tsconfig.json', 'angular2-template-loader']
      },
      {
        test: /\.html$/,
        loader: 'html'
      },
      {
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
        loader: 'file?name=assets/[name].[hash].[ext]'
      },
      {
        test: /\.css$/,
        exclude: helpers.root('src', 'app'),
        loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
      },
      {
        test: /\.css$/,
        include: helpers.root('src', 'app'),
        loader: 'raw'
      }
    ]
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: 'src/index.html',
      excludeChunks: ['webworker']
    }),

    new ExtractTextPlugin('[name].css')
  ]
};

其中 polyfills.ts 和 vendor.ts 分别包含 polyfills 和 Angular 库。

我创建了 2 个入口点,生成 2 个输出(app.js 和 webworker.js)。

对于 HtmlWebpackPlugin,第一个包含在 index.html 文件中,但第二个不包含。

当包含 index.html 时,将调用 ma​​in.ts(包含在 app.js 中)并像这样引导网络 worker :

import {bootstrapWorkerUi} from '@angular/platform-webworker';
bootstrapWorkerUi('../webworker.js');

webworker.js是webpack使用workerLoader.ts入口生成的代码

WorkerLoader.ts 文件如下所示:

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

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

platformWorkerAppDynamic().bootstrapModule(AppModule);

AppModule 看起来像这样:

import { NgModule } from '@angular/core';
import {WorkerAppModule} from '@angular/platform-webworker';


import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    WorkerAppModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
 export class AppModule { }

代码示例

为了更容易理解差异,我创建了一个项目来展示如何在基于 Web Worker 的项目中转换常规的 Angular 2 项目。检查此 repo 协议(protocol):https://github.com/kaikcreator/webWorkerFactorialExample

您将在 master 分支中看到“单线程”代码,在 webWorkers 分支 中看到使用 web workers 运行代码的更改。

关于angular - 使用 WebPack 在 Web Worker 中运行 Angular 2 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40130142/

相关文章:

javascript - Webpack:-p vs NODE_ENV=生产 vs process.env.NODE_ENV

javascript - Web Worker 如何实现递归函数?

javascript - 使用 webworker 的 chrome 多线程功能?

node.js - 我可以在 AWS Lambda 中使用 WebWorkers( Node 6.10)

根级别的 Angular 代理

javascript - Node JS 和 Webpack 意外 token <

javascript - RxJ 和 switchMap

angular - RouterModule.forRoot 调用了两次

Angular 6 : Create dynamic reactive form but got an Error: "formGroup expects a FormGroup instance. Please pass one in"

javascript - 类型 'filter' 上不存在属性 'Observable<Event>'