[技術支援-7] TypeScript設定

TypeScript配置

TypeScript是Angular應用開發中使用的主語言。瀏覽器不能直接執行TypeScript,得先用tsc編譯器轉譯(transpile)成JavaScript,而且編譯器需要進行一些配置。而配置的檔案名稱就是tsconfig.json

這邊是官方關於此配置文件的詳細說明:tsconfig.json

tsconfig.json

下面為一個tsconfig.json的範例

關於設定檔裡的noImplicitAny意思是是否不允許typescript編譯時隱性將沒有設定類型的變數設定為any。如果設定為true的話,如果typescript裡面有沒有設定類型的變數則會產生錯誤訊息。當這個值設定為true時,記得要將suppressImplicitAnyIndexErrors也設定為true,不然會發生隱式報錯。

lib.d.ts 文件

TypeScript有一個特殊的聲明文件lib.d.ts。包含了JavaScript運行庫和DOM的各種常用Javascript環境聲明。
基於–target,TypeScript添加額外的環境聲明,例如如果目標為es6時將添加Promise。

[技術支援-6] NPM設定

安裝NPM環境

Angular應用程序以及Angular本身都依賴於很多第三方包(包括Angular自己)提供的特性和功能。這些包由Node包管理器( npm )負責安裝和維護。
因此Node.js和npm是做Angular開發的基礎。
這邊是Node.js下載連結:Downloads NPM

如果在電腦中需要同時運行多個不同版本的npm,可以使用nvm來管理他們:nvm

package.json設定

這邊有詳細的說明文檔:Specifics of npm’s package.json handling
下面是一個預設CLI設定檔的範例

這邊說明幾個比較重要的設定值:

  • script: 是一個script commands的列表,這些script commands會在生命週期中的不同時間運行。其內容的key是生命週期事件,value是要執行的命令。可獲得的生命周期列表:請見此
  • dependencies: 要運行這個應用程式必要一定要安裝的package
  • devDependencies: 只有在開發時需要用到的功能則寫在這邊,當別人要導入我們所開發的專案時,不用一定要下載完整的devDependencies內容。

在dependencies需載入的Angular Packages

  • @angular/animations:網頁切換動畫效果
  • @angular/common: services, pipes, and directives等都在這邊
  • @angular/compiler:Angular的模板編譯器,在JIT
  • @angular/core: 基本angular框架所需的功能如metadata decorators, Component, Directive, dependency injection,以及元件的lifecycle hooks都在裡面
  • @angular/forms:template-driven和reactive forms的表單驗證功能都在這
  • @angular/http:Angular的舊版即將被棄用的HTTP客戶端
  • @angular/platform-browser:一切DOM和瀏覽器相關的在這,AOT編譯方法也在這
  • @angular/platform-browser-dynamic:JIT編譯器在這
  • @angular/router:路由器功能
  • @angular/upgrade:從angularJS升級所需使用的
  • core-js: Polyfill packages
  • zone.js: 一個為 Zone規範提供的填充庫
  • rxjs: 新版的Angular主要使用的HTTP方法模組
  • bootstrap: bootstrap是一個可以簡單做出UI的視覺框架
  • angular-in-memory-web-api: 一個Angular的支持庫,它能模擬一個遠端服務器的Web API,而不需要依賴一個真實的服務器或發起真實的HTTP調用。對演示、文檔範例和開發的早期階段(那時候我們可能還沒有服務器呢)非常有用。

devDependencies需載入的Packages

列在文件中devDependencies區的包會幫助我們開發該應用程序。我們不用把它們部署到產品環境的應用程序中——雖然這樣做也沒什麼壞處。
另外在devDependencies也需要列出所有在Angular裡列為peerDependencies的package

[技術支援-5] 佈署方式JIT及AOT介紹

Ahead-of-Time (AOT)編譯

在Angular 2 中有兩種編譯模式:

  • JIT(Just-in-Time):Angular預設是使用 Just-in-Time (JIT) 即時編譯,等瀏覽器下載完 *.js 檔案後,會在用戶端的瀏覽器編譯 Angular 的 JS 程式碼,接著才會渲染畫面。
  • AOT(Ahead-of-Time):在程式發佈之前就透過 Angular Compiler 進行編譯,所以瀏覽器下載完的 *.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,編譯器在每個用戶的每次運行期間都要用不同的庫運行一次。

AOT編譯的優點

  • 更快:瀏覽器直接載入可運行的程式碼,可以立即使用,而不用等待編譯完成。
  • 減少HTTP異部請求:編譯器把外部HTML模板和CSS樣式表內聯到了該應用的JavaScript中。消除了用來下載那些源文件的Ajax請求。
  • 檔案更小:客戶端不用載入完整的Angular編譯器
  • 提早檢測模板錯誤:編譯時會跳出模板綁定錯誤警告,提早發現錯誤
  • 更安全:AOT編譯遠在HTML模版和組件被服務到客戶端之前,將它們編譯到JavaScript文件。沒有模版可以閱讀,沒有高風險客戶端HTML或JavaScript可利用,所以注入攻擊的機會較少。

使用AOT編譯

Angular5大大的簡化了AOT流程,我們只需在生成文件時加上--aot

如果我們使用--prod預設也會是aot輸出。

用AOT編譯的程式編寫限制

如果使用AOT預編譯,在撰寫angular的metadata要注意下面幾點:

不支援function expression

不支援Arrow functions

像下面這種設定方法在AOT是不被支援的

需改成這樣:

在元數據內單獨使用常數

因為常數是在編譯時就編譯進JS裡,如下面的寫法會造成AOT在編譯時遺失template常數的值:

我們可以改用下面這種寫法

或將常數放至一個運算表達式內:

裝飾和數據綁定的類成員必須公開

在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文件。如果編譯器需要這段元數據來生成應用程序代碼,則編譯器稍後將報告該錯誤。
若希望能立即顯示錯誤,則可以將tsconfigstrictMetadataEmit設為true

參考資料