在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現在真的方便多了...參考文章裡的方法都好複雜阿!