我正在尝试将Angular 2应用程序的整个执行移动到Web工作者,但我发现现在所有可用的示例都使用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中收到错误未捕获的SyntaxError:意外的令牌导入。
这个问题似乎与webpack有关,并且在网页工作者方面缺少@angular libs的导入,正如Tamas Gegedus和MathMate所建议的那样,所以下一步是修改webpack配置文件以提供所有必需的libs到网络工作者。我会继续努力。
----------- UPDATE -----------
由于angular-cli不提供对webpack.config.js文件的访问,我已经包含了我的,在代码中做了很少的更改,因此它可以工作。我在webpack配置文件中创建了第二个入口点,我收到错误 VM33:106未捕获的ReferenceError:窗口未定义。
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分别包含polyfill和angular libs。
我创建了2个入口点,生成2个输出(app.js和webworker.js)。
使用HtmlWebpackPlugin,第一个包含在index.html文件中,但不包含在第二个文件中。
当包含index.html时,会调用 main.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:窗口未定义,并且除了来自index.html的加载消息之外,不显示任何内容。
另一方面,我认为webpack配置没问题,因为如果在没有webworker模式下使用webpack运行应用程序,它可以正常工作。
现在我认为这个问题与webworker bootstrap有关,但我在这里很困惑。
任何帮助将不胜感激;)
答案 0 :(得分:9)
注意:如果您使用 Angular CLI 1.0 或更高版本生成项目,您现在可以使用自己的webpack配置文件,这简化了整个过程。 检查this answer in that case。
使用我的自定义webpack配置运行代码后,我意识到错误 VM33:106未捕获的ReferenceError:窗口未定义是由 webpack-dev-server <引起的/ EM> 强>
我解决了它:
1 - 做独立的webpack构建
$: webpack --watch #this creates the bundes at myProject/dist
和
2 - 与另一个devserver工具一起运行,例如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.config.js
文件的访问权限,自定义网络包是使用网络工作者的关键,我已经包含了我的代码。
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分别包含polyfill和angular libs。
我创建了2个入口点,生成2个输出(app.js和webworker.js)。
使用HtmlWebpackPlugin,第一个包含在index.html文件中,但不包含在第二个文件中。
当包含index.html时,会调用 main.ts (包含在app.js中)并像这样引导网络工程:
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 { }
为了更容易理解差异,我创建了一个项目,展示了如何在基于Web的工作者中转换常规角度2项目。检查此回购:https://github.com/kaikcreator/webWorkerFactorialExample
您将在master分支中看到“单线程”代码,并在 webWorkers分支中看到使用Web worker运行代码的更改。
答案 1 :(得分:1)
正如Tamas Hegedus在评论中已提到的,很可能你的webpack包仍然在引用loader.js的es6文件。
您需要使用加载程序脚本的入口点创建单独的bundle。
如果你共享你的webpack配置,那么就更容易分辨出事情可能出错的地方。
此外,您的加载程序脚本需要具有所需的polyfill。你可以添加
import'core-js / es7 / reflect'; import'zone.js / dist / zone';