Angular 2 AOT - 引用尚未创建的 AppModuleNgFactory

Angular 2 AOT - referencing not-yet-created AppModuleNgFactory

我在一个模块中有一组组件,在同一项目的不同模块下有一个示例应用程序。我有一个运行良好的现有 JIT 构建,我正在尝试过渡到遇到问题的 AOT 构建。具体来说,/src/index.aot.ts (2,34): Cannot find module './aot/app/examples/app.module.ngfactory'.

如何使用 AotPlugin 设置 webpack 以将我的应用程序的 AOT 版本正确构建到本地 dist 目录?

/src/index.aot.ts

在此文件中,AppModuleNgFactory 无法解析,因为它不存在。当前没有任何 aot 目录生成任何内容,我不确定为什么。

import 'core-js/client/shim';
import 'zone.js/dist/zone';

import '@angular/common';
import 'rxjs';

import {enableProdMode} from '@angular/core';
import {AppModuleNgFactory} from '../aot/app/examples/app.module.ngfactory';
import {platformBrowser} from '@angular/platform-browser';

enableProdMode();
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

/tsconfig.json

{
  "compilerOptions": {
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "typeRoots": [
      "node_modules/@types/"
    ],
    "target": "ES5",
    "types": [
      "node",
      "jasmine",
      "es6-shim"
    ]
  },
  "compileOnSave": false,
  "filesGlob": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "!node_modules/**"
  ],
  "exclude": [
    "node_modules",
    "dist/",
    "**/*.spec.ts"
  ],
  "angularCompilerOptions": {
    "genDir": "aot/",
    "skipMetadataEmit": true
  }
}

webpack-dist.conf

...imports     
module.exports = {
  entry: {
    app: './src/index.aot.ts'
  },
  module: {
    loaders: [
      {
        test: /\.json$/,
        loaders: [
          'json-loader'
        ]
      },
      {
        test: /\.(ttf|otf|eot|svg|png|jpg|woff(2)?)(\?[a-z0-9]+)?$/,
        loader: 'file-loader'
      },
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        loader: 'tslint-loader',
        enforce: 'pre'
      },
      {
        test: /\.css$/,
        loaders: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: 'css-loader?minimize!sass-loader!postcss-loader'
        })
      },
      {
        test: /\.scss$/,
        loaders: ['raw-loader', 'sass-loader']
      },
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        loaders: [
          '@ngtools/webpack'
        ]
      },
      {
        test: /\.html$/,
        loaders: [
          'html-loader'
        ]
      }
    ]
  },
  plugins: [
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
    FailPlugin,
    new HtmlWebpackPlugin({
      template: conf.path.src('index.html')
    }),
    new webpack.ContextReplacementPlugin(
      /angular(\|\/)core(\|\/)(esm(\|\/)src|src)(\|\/)linker/,
      conf.paths.src
    ),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"production"'
    }),
    new ExtractTextPlugin('index-[contenthash].css'),
    new webpack.optimize.CommonsChunkPlugin({name: 'vendor'}),
    new webpack.LoaderOptionsPlugin({
      options: {
        postcss: () => [autoprefixer],
        resolve: {},
        ts: {
          configFileName: 'tsconfig.json'
        },
        tslint: {
          configuration: require('../tslint.json')
        }
      }
    }),
    new CopyWebpackPlugin([
      {from: 'index.html'}
    ]),
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery',
      Tether: 'tether'
    }),
    new AotPlugin({
      tsConfigPath: './tsconfig.json',
      entryModule: './src/app/examples/index.ts#AppModule'
    }),
    new webpack.optimize.UglifyJsPlugin({
      output: {comments: false},
      compress: {unused: true, dead_code: true, warnings: false} // eslint-disable-line camelcase
    })
  ],
  output: {
    path: path.join(process.cwd(), conf.paths.dist, 'aot'),
    filename: '[name]-[hash].js'
  },
  resolve: {
    extensions: [
      '.webpack.js',
      '.web.js',
      '.js',
      '.ts'
    ]
  }
};

我错过了什么?为什么我需要引用 bootstrap 文件中不存在的文件,例如 index.aot.ts?

完整的错误输出:

ERROR in ~/work/project/src/index.aot.ts (2,34): Cannot find module './aot/app/examples/app.module.ngfactory'.

ERROR in Could not resolve "./src/app/examples/app.module" from "./src/app/examples/app.module".

ERROR in ./src/index.aot.ts
Module not found: Error: Can't resolve './aot/app/examples/app.module.ngfactory' in '~/work/project/src'
 @ ./src/index.aot.ts 4:29-79

编辑:删除 platformBrowser() 和生成的导入后,我遇到了这个莫名其妙的错误:

ERROR in ./src/index.ts
Module not found: Error: Can't resolve './../$$_gendir/src/app/examples/app.module.ts.ngfactory'

不需要将以下内容放入main.ts:

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

您必须在 main.ts 中保留与非 AOT 构建相同的 bootstrap 代码:

platformBrowserDynamic().bootstrapModule(AppModule)

Angular AOT 加载器在生成 AOT 构建时会将代码重构为 bootstrapModuleFactory。参见 here in the sources。重要的是 skipCodeGeneration 选项应该是 false - 这是默认的。