Angular 2 事先編譯 Ahead-of-Time (AoT)
- 2017-01-09
- Liu, An-Chi 劉安齊
前言
Angular 2 雖然是一套強大框架,但最後輸出仍然為 html
、js
、css
檔案,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-loader
或 awesome-typescript-loader
。 這個套件會和 AotPlugin 一起完成 AoT 編譯。