Webpack,Typescript和Angular2提前编译(AOT)编译?

时间:2016-08-23 21:46:21

标签: angular typescript webpack angular-cli aot

最新版本的Angular2允许在app.bootstrap.ts文件中使用此代码进行提前(AOT)编译:

// The browser platform without a compiler
import { platformBrowser } from '@angular/platform-browser';

// The app module factory produced by the static offline compiler
import { AppModuleNgFactory } from './app.module.ngfactory';

// Launch with the app module factory.
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

Angular2 Official Documentation

我们如何将Webpack和Typescript加载器与Angular2的AOT编译器集成?

似乎可能还没有这样做的选项,但我问的是关于Stack溢出的问题,所以当它可用时,答案很容易找到。

更新10/12/16 - 我明白了,请看下面的答案。

2 个答案:

答案 0 :(得分:8)

我终于开始工作,看到我的回购Angular2 Webpack2 DotNET Starter

有几个必要的技巧。请注意,AOT编译不支持Angular 2组件中的任何require()语句。它们需要转换为import语句。

首先,您需要有第二个tsconfig.json文件,其中包含AOT编译的特殊选项。我用.aot.json扩展名指定了这个。

tsconfig.aot.json:

{
   "compilerOptions": {
      "target": "es5",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "allowSyntheticDefaultImports": false,
      "noEmitHelpers": true,
      "pretty": true,
      "strictNullChecks": false,
      "baseUrl": ".",
      "sourceMap": true,
      "sourceRoot": ".",
      "lib": [
         "es6",
         "dom"
      ],
      "types": [
         "lodash",
         "hammerjs",
         "jasmine",
         "node",
         "selenium-webdriver",
         "source-map",
         "uglify-js",
         "webpack",
         "materialize-css",
         "jquery",
         "kendo-ui"
      ],
      "typeRoots": [
         "./node_modules/@types"
      ],
      "outDir": "./compiled/src"
   },
   "exclude": [
      "./node_modules",
      "./**/*.e2e.ts",
      "./**/*.spec.ts",
   ],
   "awesomeTypescriptLoaderOptions": {
      "useWebpackText": true,
      "forkChecker": true,
      "useCache": true
   },
   "compileOnSave": false,
   "buildOnSave": false,
   "atom": {
      "rewriteTsconfig": false
   },
   "angularCompilerOptions": {
      "genDir": "./compiled/aot",
      "debug": true
   }
}

您还需要Angular2的完全正确的组合。 @angular/core@2.0.2@angular/common@2.0.2对我不起作用,我必须使用2.0.0ngc无法编译AOT文件。以下是我成功使用的内容:

package.json:

  "dependencies": {
    "@angular/core": "2.0.0",
    "@angular/common": "2.0.0",
    "@angular/compiler": "2.0.0",
    "@angular/compiler-cli": "0.6.2",
    "@angular/forms": "^2.0.1",
    "@angular/http": "2.0.0",
    "@angular/platform-browser": "2.0.0",
    "@angular/platform-browser-dynamic": "2.0.0",
    "@angular/platform-server": "2.0.0",
    "@angular/router": "3.0.0",
    "@angular/tsc-wrapped": "0.3.0"
}

此外,您还需要一些漂亮的webpack加载器,同时还允许webpack查看./src文件夹以及AOT编译文件输出到的文件夹。 (*.component.ngfactory.ts

最后一部分非常重要!如果你不告诉webpack将它包含在那些文件夹中,它就不会工作。在此示例中,AOT文件将输出到根文件夹中的/aot-compiled

<强> webpack.common.js

  loaders: [
     {
        test: /\.ts$/,
        include: [helpers.paths.appRoot, helpers.root('./compiled/aot')],
        exclude: [/\.(spec|e2e)\.ts$/],
        loaders: [
           '@angularclass/hmr-loader',
           'awesome-typescript-loader',
           'angular2-template-loader',
           'angular2-router-loader?loader=system',
           "angular2-load-children-loader" // this loader replaces loadChildren value to work with AOT/JIT
        ],
     },
  ]

要生成AOT文件,您需要一个NPM脚本才能为您完成

<强>的package.json

   "scripts": {
      "compile:aot": "./node_modules/.bin/ngc -p ./tsconfig.aot.json",
   }

您还需要让您的webpack配置读取app.bootstrap.ts的AOT版本 - 这与JIT版本不同。我将其区分为.aot.ts扩展名,以便在生产中,webpack使用AOT(app.bootstrap.aot.ts),但在开发模式下,它使用JIT webpack-dev-serverapp.bootstrap.ts)。

最后,您首先运行npm run compile:aot。 将AOT文件输出到磁盘后,可以使用webpackwebpack-dev-server运行webpack构建。

有关工作示例,请参阅我的回购Angular2 Webpack2 DotNET Starter。它与.NET Core 1.0集成,但对于那些不使用.NET的人,您仍然可以看到Webpack 2和Angular 2是如何配置的。

答案 1 :(得分:1)

tsconfig.json

    {
      "compilerOptions": {
        "target": "es5",
        "module": "es2015",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "lib": ["es2015", "dom"],
        "noImplicitAny": true,
        "suppressImplicitAnyIndexErrors": true,
        "typeRoots": [
          "./node_modules/@types/"
        ]
      },
      "angularCompilerOptions": {
        "genDir": "aot",
        "skipMetadataEmit" : true
      }
    }

<强>配置/的WebPack-aot.config.js

/**
 * webpack2 config file for ng2 AOT compile
 * location : config/webpack.aot.js
 */
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');

const ngToolsWebpack = require('@ngtools/webpack');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
console.log(helpers.root('src', 'app', 'app.module#AppModule'));
module.exports = {
  devtool: 'source-map',
  entry: {
    'polyfills': './src/polyfills.ts',
    'app': './src/main.ts'
  },
  resolve: {
    extensions: ['*', '.ts', '.js']
  },
  output: {
    path: helpers.root('dist'),
    publicPath: '/',
    filename: '[name].[hash].js',
    chunkFilename: '[id].[hash].chunk.js'
  },

  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: '@ngtools/webpack'
      },
      {
        test: /\.html$/,
        loader: 'html-loader'
      },
      {
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
        include: helpers.root('public', 'images'),
        loader: 'file-loader',
        options: {
          //name: '/assets/[name].[hash].[ext]'  <-file-loaderError
          name: 'assets/[name].[ext]'
        }
      },
      {
        test: /\.css$/,
        exclude: helpers.root('src', 'app'),
        loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
      },
      {
        test: /\.css$/,
        include: helpers.root('src', 'app'),
        loader: 'raw-loader'
      },
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        loaders: ['raw-loader', 'sass-loader']
      },
      {
        test: /\.sass$/,
        exclude: /node_modules/,
        loaders: ['raw-loader', 'sass-loader']
      }
    ]
  },

  plugins: [
    // If you want to use jquery in ng2 uncomment this
    /*
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery"
    }),*/
    new ngToolsWebpack.AotPlugin({
      tsConfigPath: helpers.root('tsconfig-aot.json'),
      basePath: helpers.root(''),
      entryModule: helpers.root('src', 'app', 'app.module#AppModule'),
      mainPath: helpers.root('src', 'main.ts')
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: ['app', 'polyfills']
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true,
      options: {
        htmlLoader: {
          minimize: false
        }
      }
    }),
    new HtmlWebpackPlugin({
      template: 'public/index.html'
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
          warnings: false,
          drop_console: true
      },
      output: {
          comments: false
      }
    }),
    new ExtractTextPlugin('[name].[hash].css'),
    new webpack.DefinePlugin({
      'process.env': {
        'ENV': JSON.stringify(ENV)
      }
    })
  ]
};

我使用了这个webpack配置,我使用angular2延迟加载进行了AOT编译。 你可以看到AOT / JIT的示例应用程序使用angular2延迟加载进行生产模式和开发模式。

angular2-webpack2-aot