閱讀這篇文章前,先回顧一下昨天的學習,回答看看:
- 如何建立測試 TypeScript 的開發環境(線上/本機)?
- 如果型別錯誤,TypeScript 是否會報錯和編譯成 JavaScript 檔案呢?
如果有點不清楚答案的話,可以先看看 Day02 的文章喔!
昨天簡單了介紹如何建立運行 TS 程式碼的線上和本機環境,今天要更近一步介紹 TS 如何自由地設定編譯成我們想要的 JS 檔案。
讓我們回到昨天介紹的線上測試介面playground,仔細的查看,會發現灰色的選單欄位,這裡可以自由的選擇 TS 要編譯到哪種版本的 JS、使用範例程式碼(Examples)和勾選不同的編譯設定(Options)。
基礎設定包括:
target
: 輸出的JavaScript版本(可選 ES3、 ES5 、 ES2015 、 ES2016 、 ES2017 、 ES2018 、 ESNext 和 JSON)JSX
: 是否使用JSX語法Lang
: 切換支援 TS 和 JS 語法關於上面提到的JS標準語法規範ECMAScript的版本發展,在這邊補充說明:ES3是1999年推出的第三版,ES5(目前大部分主流瀏覽器都支援的版本)則是2009年推出的第五版,而後2015年推出 ES6(又名 ES2015),之後規定每一年釋出新的版本,因此,2016年推出 ES2016,2017年推出 ES2017,以此類推,今年2019年已經到了 ES10版本,而未釋出的未來版本則為ESNext。
至於下方更細的設定(checkbox部分),等等會和 tsconfig.json 的 compilerOptions 內容一起討論。
在本機環境中,所有有關 TS 的編譯設定都會寫在 tsconfig.json 檔案中。那麼tsconfig.json 檔案究竟是如何產生的呢?
還記得昨天我們創建了 hello.ts 檔案,並把它編譯成 hello.js 嗎?同樣進到專案資料夾,此時,執行下面的命令
tsc --init
這時候,專案資料夾下會產生一個新的 tsconfig.json 檔案,可以看到預設的編譯設定(註解先忽略)。
{
"compilerOptions": {
"target": "es5", //指定編譯生成的JS版本
"module": "commonjs", //指定生成哪種模組
"strict": true, //採用嚴格模式
"esModuleInterop": true, //兼容模組導入的方式
}
}
其實,tsconfig.json 檔案可以完全不要有任何編譯設定,但是檔案不可以是空白,至少需要有一個空的JSON物件即可。
{}
這時候,TS會使用預設編譯設定,編譯專案資料夾下所有含.ts和.tsx的檔案。
再回到tsc --init 初始化產生的 tsconfig.json 檔案,裡面包含了"compilerOptions"
屬性設定。事實上,我們所有的編譯設定都會寫在 compilerOptions 裡,這個部分後面會再近一步討論。
而除了compilerOptions屬性之外,也有其他屬性可使用,像是"files"
屬性指定要編譯的 TS 檔案、"include"
屬性設定編譯時包含哪些檔案或資料夾以及"exclude"
屬性設定編譯時排除哪些檔案或資料夾。
}
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
},
"files":[
"hello.ts"
]
}
若沒有寫 files 屬性,TypeScript 預設會編譯根目錄以及子目錄下的 .ts 或是 .tsx 檔案。但如上方程式碼,若指定 files,則只會編譯指定的 hello.ts 檔案。files可以使用絕對路徑或相對路徑語法表示。
}
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
},
"include":[
"src/**/*.ts"
],
"exclude":[
"node_modules"
]
}
"include"和"exclude"屬性使用 glob-like 檔案匹配模式,最常見的萬用字元包括:
*
-表示匹配0至多個字元(不包含分隔符號)?
-匹配一個相符字元(不包含分隔符號)**/
-表示匹配所有子資料夾
從上面的程式碼,我們可以知道編譯時只要是src資料夾下的.ts副檔名都會進行編譯,而 node_modules 資料夾下的檔案都不進行編譯。
線上工具globtester可以方便測試 glob-like 語法。
補充:files v.s. include v.s. exclude
- files 使用相對路徑或是絕對路徑表達 ; include 使用 glob 匹配模式
- files 和 include 都不一定要填,若不填,預設找當下目錄跟子目錄的 TS 檔案 (含.ts、.d.ts、.tsx 副檔名)
- 若同時寫 include 和 files 兩個屬性,則相符的檔案或資料夾中的檔案都會被編譯
- 優先權:files > exclude > include。include 指定的檔案可以使用 exclude 進行過濾,但是files 指定檔案不能被 exclude 排除。如果 files 以及 exclude 指定重複的檔案或路徑,files 具有優先權
接下來,來說明compilerOptions屬性的部分。
這篇文章僅整理 官網 playground 見到的編譯選項以及 tsconfig.json 中最常見的配置選項(要左右滑才能看到完整的表格),其他詳細設定選項可參考官網。
選項 | 型別 | 預設值 | 說明 |
---|---|---|---|
基礎設定選項 | - | - | - |
target | string | "ES3" | 指定輸出的JS版本,可選ES3(預設)、 ES5 、 ES6/ ES2015 、 ES2016 、 ES2017 或 ESNext |
module | string | 若target設為"ES3"或"ES5",則預設為"CommonJS";其他預設為"ES6" | 可選 None、 CommonJS、AMD、System、UMD、ES6、ES2015 或 ESNext |
lib | string[] | 無 | 編譯需要引入的特定函式庫檔案 |
noLib | boolean | false | 不包含預設的函式庫檔案(lib.d.ts) |
allowJs | boolean | false | 允許JS檔案(.js或.jsx)編譯 |
checkJs | boolean | false | 在.js檔案中回報錯誤。和allowJs搭配使用 |
jsx | string | "preserve" | 支援.tsx檔名的特定JSX檔案,可選preserve(預設)、react-native 或 react |
declaration | boolean | false | 生成相對應的裝飾檔案(.d.ts) |
outFile | string | 無 | 輸出全部整合到此檔案,例如:"./dist/app.js" |
outDir | string | 無 | 重新設定輸入資料夾,例如"./dist" |
removeComments | boolean | false | 移除註解 |
noEmit | boolean | false | 不產生輸出檔案 |
noEmitOnError | boolean | false | 當有錯誤時不產生輸出檔案 |
downlevelIteration | boolean | false | 當target的JS版本為ES3或ES5時,會將for..of, spread 和 destructuring ES6新語法降級 |
檢查模式選項 | - | - | - |
strict | boolean | false | 啟用所有嚴格類型檢查模式,相當於noImplicitAny、noImplicitThis、alwaysStrict、strictBindCallApply、strictNullChecks、strictFunctionTypes 和 strictPropertyInitialization的設定為true |
alwaysStrict | boolean | false | 以嚴格模式解析,輸出每個檔案都加上"use strict" |
noImplicitAny | boolean | false | 隱含推論型別為any時報錯 |
noImplicitThis | boolean | false | 當this表達式的值為any型別時報錯 |
skipLibCheck | boolean | false | 不檢查所有的裝飾檔案(.d.ts) |
allowUnreachableCode | boolean | false | 允許有未執行的程式碼,不報錯 |
allowUnusedLabels | boolean | false | 允許有未使用的標籤,不報錯 |
noUnusedLocals | boolean | false | 當有未使用的local變數時報錯 |
noUnusedParameters | boolean | false | 當有未使用的函式參數時報錯 |
module解析選項 | - | - | - |
experimentalDecorators | boolean | false | 允許使用實驗階段的decorators |
allowSyntheticDefaultImports | boolean | 只有在module為"system"或esModuleInterop為true時才使用 | |
esModuleInterop | boolean | false | 兼容 CommonJS module 引入,符合 ES6 module 規範 |
關於esModuleInterop和allowSyntheticDefaultImports設定的細節說明可參考stackoverflow,這邊暫不多做探討。
在最上層設定 compileOnSave 屬性,可已讓IDE編輯器在儲存檔案的時候根據tsconfig.json重新產生編譯檔案
{
"compileOnSave": true,
"compilerOptions": {
...
}
}
在使用 compileOnSave 屬性時,會需要 Visual Studio 2015以上、TypeScript1.8.4以上並安裝 atom-typescript套件。
tsc
則會從該目錄資料夾開始向父層尋找tsconfig.json檔案
tsc hello.ts
則tsconfig.json檔案會被忽略,直接編譯 hello.ts
今天我們介紹了如何透過tsconfig.json檔案自由地設定哪些檔案要編譯,哪些檔案要排除,以及如何透過設定將 TS 檔案編譯成想要的 JS 檔案(哪個 JS 版本、是否採取嚴格模式、是否允許實驗階段的語法等等)。
其實,編譯設定選項非常多,這次先大致了解設定檔的基本輪廓,裡面還有很多眉眉角角,牽扯到 TS 整個編譯器的編譯流程,或許之後進到專案開發時再來細細研究。
如有錯誤的地方,還請留言告知,我會盡快修改調整,感謝:)