web-dev-qa-db-ja.com

Webpack、TypeScript、Angular2 with Ahead Of Time(AOT)コンパイル?

Angular2の最新リリースでは、app.bootstrap.tsファイルで次のコードを使用して、Ahead of Time(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公式ドキュメント

どのようにしてWebpackとTypeScriptローダーをAngular2のAOTコンパイラと統合できますか?

まだそうするためのオプションがないようですが、私はスタックオーバーフローについて質問しているので、利用可能になったときに簡単に答えを見つけることができます。

UPDATE 10/12/16-機能しました。以下の私の回答を参照してください。

16
TetraDev

私は最終的にそれを動かしました、私のリポジトリを見てください Angular2 Webpack2 DotNET Starter

いくつかのトリックが必要です。 AOTコンパイルは、Angular 2コンポーネント内のrequire()ステートメントをサポートしていません。これらはimportステートメントに変換する必要があります。

まず、AOTコンパイル用の特別なオプションを備えた2番目のtsconfig.jsonファイルが必要です。これを.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/[email protected]@angular/[email protected]は機能しませんでした。両方に2.0.0を使用するか、ngcが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ローダーが必要ですが、./srcフォルダーとAOTコンパイル済みファイルの出力先フォルダーをwebpackで確認することもできます。 (*.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",
   }

また、JITバージョンとは異なるapp.bootstrap.tsのAOTバージョンをwebpack構成に読み込ませる必要もあります。私はそれを.aot.ts拡張子で区別しているため、本番環境ではwebpackはAOT(app.bootstrap.aot.ts)を使用しますが、開発モードではJITをwebpack-dev-serverapp.bootstrap.ts)で使用します。

最後に、npm run compile:aot FIRSTを実行します。 AOTファイルがディスクに出力されたら、webpackまたはwebpack-dev-serverを使用してwebpackビルドを実行します。

実際の例については、私のリポジトリ Angular2 Webpack2 DotNET Starter を参照してください。 .NET Core 1.0と統合されていますが、.NETを使用していない場合でも、Webpack 2とAngular 2がどのように構成されているかを確認できます。

8
TetraDev

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

config/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コンパイルを行いました。このgitで、AOT/JITコンパイルのサンプルアプリを本番モードと開発モードのangular2遅延ロードでコンパイルすることができます。

angular2-webpack2-aot

1
MiraGe