在Angular中有兩種編譯模式:
*.js 檔案後,會在用戶端的瀏覽器編譯 Angular 的 JS 程式碼,接著才會渲染畫面。*.js 檔案,就可以直接被執行,然後渲染畫面。下表為這兩種佈署方式的簡單比較表:
| Characteristic | JiT | AoT |
|---|---|---|
| Compilation target | Browser | Server |
| Compilation context | Runtime | Build |
| Bundle size | Huge (~1.2 MB) | Smaller (~400 KB) |
| Execution Performance | - | Better |
| Startup time | - | Shorter |
AoT的要點是將編譯從運行時移動到構建過程。因此我們不需要讓用戶載入完整的編譯器功能,也不需要在用戶端才去做編譯的動作,所以從對照表可以看出,這個動作可以讓效能以及檔案大小都變得更好。
另外,預先編譯可以在編譯期就發現一些模版的錯誤,而不需要等到實際在客戶端執行才發現。使用AOT,編譯器僅僅使用一組庫在構建期間運行一次;使用JIT,編譯器在每個用戶的每次運行期間都要用不同的庫運行一次。
Angular5大大的簡化了AOT流程,我們只需在生成文件時加上--aot
ng build --aot
ng serve --aot
如果我們使用--prod預設也會是aot輸出。
如果使用AOT預編譯,在撰寫angular的metadata要注意下面幾點:
var myFunction = function [name]([param1[, param2[, ..., paramN]]]) {
statements
};
(param1, param2, …, paramN) => { statements }
像下面這種設定方法在AOT是不被支援的
@Component({
...
providers: [{provide: server, useFactory: () => new Server()}]
})
需改成這樣:
export function serverFactory() {
return new Server();
}
@Component({
...
providers: [{provide: server, useFactory: serverFactory}]
})
因為常數是在編譯時就編譯進JS裡,如下面的寫法會造成AOT在編譯時遺失template常數的值:
const template = '<div>{{hero.name}}</div>';
@Component({
selector: 'app-hero',
template: template
})
export class HeroComponent {
@Input() hero: Hero;
}
我們可以改用下面這種寫法
@Component({
selector: 'app-hero',
template: '<div>{{hero.name}}</div>'
})
export class HeroComponent {
@Input() hero: Hero;
}
或將常數放至一個運算表達式內:
const template = '<div>{{hero.name}}</div>';
@Component({
selector: 'app-hero',
template: template + '<div>{{hero.title}}</div>'
})
export class HeroComponent {
@Input() hero: Hero;
}
在metadata中只支援下面的angular decorators
| DECORATOR | MODULE |
|---|---|
| Attribute | @angular/core |
| Component | @angular/core |
| ContentChild | @angular/core |
| ContentChildren | @angular/core |
| Directive | @angular/core |
| Host | @angular/core |
| HostBinding | @angular/core |
| HostListener | @angular/core |
| Inject | @angular/core |
| Injectable | @angular/core |
| Input | @angular/core |
| NgModule | @angular/core |
| Optional | @angular/core |
| Output | @angular/core |
| Pipe | @angular/core |
| Self | @angular/core |
| SkipSelf | @angular/core |
| ViewChild | @angular/core |
如果表達式使用不受支持的語法,則collector將錯誤的項目寫入.metadata.json文件。如果編譯器需要這段元數據來生成應用程序代碼,則編譯器稍後將報告該錯誤。
若希望能立即顯示錯誤,則可以將tsconfig的strictMetadataEmit設為true
"angularCompilerOptions": {
...
"strictMetadataEmit" : true
}
沒想到我的文章也在參考之中。
現在回去看覺得慘不忍睹 XD
Angular CLI 預設成 AOT 之後,平常就沒啥感覺了,去年要編個 AOT 都一堆麻煩
我有拜讀你去年的系列文喔!
[[功能介紹-1] Angular架構]([功能介紹-1] Angular架構)這篇你的文章也有在參考之中!
AOT現在真的方便多了...參考文章裡的方法都好複雜阿!