前言

Angular 2 雖然是一套強大框架,但最後輸出仍然為 htmljscss 檔案,js 本身是即時編譯 (Just-in-Time, JiT),瀏覽器先讀取我們的檔案,然後瀏覽器邊看邊編譯,但這樣比起有先編譯過當然慢了多,如果事先編譯 (Ahead-of-Time, AoT) 的話,當我們用瀏覽器打開時,就不用編譯,於是體驗速度就快了許多,此外編譯過的程式碼也會比原始碼輕量。由於先編譯過,如果有 bug 的話也會很容易發現。

AoT

在 Angular 2 中有幾種方式可以建構 AoT 網頁:
1.使用開發環境
2.直接使用 ngc
3.@ngtools/webpack 套件

如果要建立 AoT 要做多設定,後面兩種屬於要自己重頭硬幹的方式,介紹起來真的很複雜,所以我簡單帶過,通常我們也不需要這樣做。附上一些文章供大家參考:
官方文件
Ahead-of-Time Compilation in Angular
Building an Angular 2 Application for Production

1.使用開發環境

這邊開發環境是指 Angular-Seed 這類的環境,或是別人已經打包好的 AoT 開發專案直接拿來使用。

Angular-Seed

Angular-Seed 是 Angular 第二受歡迎的開發環境

$ git clone --depth 1 https://github.com/mgechev/angular-seed.git
$ cd angular-seed

安裝套件

$ npm install

快一點安裝套件 (用 Yarn: https://yarnpkg.com)

$ yarn install # or yarn

AoT compilation 編譯檔案,檔案會產生在 dist/prod

$ npm run build.prod.aot

2.ngc

採用 Angular CLI 開發

首先要安裝套件

npm install @angular/compiler-cli @angular/platform-server --save

建立一個 tsconfig-aot.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": ["es2015", "dom"],
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
  },

"files": [
"app/app.module.ts",
"app/main.ts"
],

"angularCompilerOptions": {
"genDir": "aot",
"skipMetadataEmit" : true
}
}

編譯

node_modules/.bin/ngc -p tsconfig-aot.json

Bootstrap 也要調整

//app/main.ts

import { platformBrowser } from '@angular/platform-browser';
import { AppModuleNgFactory } from '../aot/app/app.module.ngfactory';
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

Rollup: 一種 treeshaking 的技巧,就是把多餘無用的 code 像搖樹般搖掉。
首先要安裝

npm install rollup rollup-plugin-node-resolve rollup-plugin-commonjs rollup-plugin-uglify --save-dev

然後增加一個 rollup-config.js 檔案

import rollup      from 'rollup'
import nodeResolve from 'rollup-plugin-node-resolve'
import commonjs    from 'rollup-plugin-commonjs';
import uglify      from 'rollup-plugin-uglify'

export default {
entry: 'app/main.js',
dest: 'dist/build.js', // output a single application bundle
sourceMap: false,
format: 'iife',
plugins: [
nodeResolve({jsnext: true, module: true}),
commonjs({
include: 'node_modules/rxjs/**',
}),
uglify()
]
}

執行 rollup

node_modules/.bin/rollup -c rollup-config.js

index.html 中用 SystemJS 的部分移除,改成:

<body>
  <my-app>Loading...</my-app>
</body>

<script src="dist/build.js"></script>

這樣就完成囉!

3.@ngtools/webpack

首先要裝這個套件

npm install -D @ngtools/webpack

設定成 development dependency

接著加入 Webpack configuration 檔案 webpack.config.js,並加入以下內容:

import {AotPlugin} from '@ngtools/webpack'

exports = { /* … */
module: {
rules: [
{
test: /.ts$/,
loader: '@ngtools/webpack',
}
]
},

plugins: [
new AotPlugin({
tsConfigPath: 'path/to/tsconfig.json',
entryModule: 'path/to/app.module#AppModule'
})
]
}

這邊 @ngtools/webpack 會取代 typescript 載入器像是 ts-loaderawesome-typescript-loader。 這個套件會和 AotPlugin 一起完成 AoT 編譯。