web-dev-qa-db-ja.com

WebPackを使用してWebワーカーでAngular 2 app

Angular 2アプリの実行全体をWebワーカーに移動しようとしていますが、現在利用可能なすべての例でSystem.jsを使用していることがわかりました。 WebPackベースのプロジェクト(angular-cliでビルド)でそうしようとしています。

誰かがこれを行ったか、WebPackでこれを行う方法についてアイデアを持っていますか?

以下は私のmain.ts bootstrapファイルです:

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 libsのインポートの欠如に関連しているようです。したがって、次のステップは、webpack構成ファイルを変更して、必要なすべてのlibをwebworkerに提供することです。 。私はそれに取り組みます。

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

Angle-cliはwebpack.config.jsファイルへのアクセスを提供しないので、私は私のものを含め、それが機能するようにコードに少し変更を加えました。 webpack構成ファイルで2番目のエントリポイントを作成しましたが、エラーが発生します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 libsが含まれます。

2つの出力(app.jsとwebworker.js)を生成する2つのエントリポイントを作成しました。

HtmlWebpackPluginを使用すると、最初のファイルはindex.htmlファイルに含まれますが、2番目のファイルは含まれません。

Index.htmlが含まれている場合、main.ts(app.jsに含まれています)が呼び出され、が=を試行します。 bootstrap webpack(webworker.js)の2番目の出力を使用するwebworker

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

webworker.jsは、以前のloader.jsと同様ですが、いくつかのインポートを含む、workerLoader.tsエントリを使用してwebpackによって生成されています。

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ワーカーが生成されていることはわかっていますが、画像に示すように、エラーVM33:106 Uncaught ReferenceError:window is not defined、index.htmlからの読み込みメッセージ以外は何も表示されません。 web worker instance

一方、webpackをNO webworkerモードで実行すると、正常に動作するため、webpackの構成は問題ないと思います。

今のところ、この問題はwebworkerのブートストラップに関連していると思いますが、私はここでかなり立ち往生しています。

どんな助けもいただければ幸いです;)

12
Enrique Oriol

私はついに問題を解決しました:)

注:generateAngle CLI 1.0 /を使用するプロジェクトがある場合以降では、独自のwebpack構成ファイルを使用できるようになり、プロセス全体が簡素化されます。チェック その場合はこの回答

カスタムwebpack設定でコードを実行した後、エラー VM33:106 Uncaught ReferenceError:window is not defined が原因であることに気付きました webpack-dev-server

私はそれを解決しました:

1-スタンドアロンのwebpackビルドを実行する

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

そして

2 simplehttpserver のような別のdevserverツールで実行する

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

そして、voilà、エラーはなくなり、それは単に機能します!

Angle-cliプロジェクトに適用される変更:Webpack config

元のAngular-CLIプロジェクトに関するWebpackの変更を要約します。

angular-cliwebpack.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 libsが含まれます。

2つの出力(app.jsとwebworker.js)を生成する2つのエントリポイントを作成しました。

HtmlWebpackPluginを使用すると、最初のファイルはindex.htmlファイルに含まれますが、2番目のファイルは含まれません。

Index.htmlが含まれている場合、main.ts(app.jsに含まれています)が呼び出され、このようにWebworkerをブートストラップします

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

webworker.jsは、workerLoader.tsエントリを使用して生成されたコードwebpackです。

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 { }

コード例

違いを理解しやすくするために、通常のangular 2プロジェクトをWebワーカーベースのプロジェクトに変換する方法を示すプロジェクトを作成しました。このリポジトリを確認してください: https:/ /github.com/kaikcreator/webWorkerFactorialExample

Masterブランチに「シングルスレッド」コードが表示され、webWorkersブランチに、Webワーカーを使用してコードを実行するための変更が表示されます。

9
Enrique Oriol

Tamas Hegedusがすでにコメントで言及しているように、おそらくあなたのwebpackバンドルはまだloader.jsのes6ファイルを参照しています。

ローダースクリプトのエントリポイントを含む別のバンドルを作成する必要があります。

Webpackの設定を共有すると、どこで問題が発生しているのかがわかりやすくなります。

また、ローダースクリプトには必要なポリフィルが必要です。あなたは付け加えられます

インポート 'core-js/es7/Reflect'; import'zone.js/dist/zone ';

1
MathMate