iT邦幫忙

2024 iThome 鐵人賽

DAY 3
2
JavaScript

TypeScript 初學者也能看的學習指南系列 第 3

TypeScript 初學者也能看的學習指南 03 - tsconfig.json 的配置

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240913/20149362ibhH1185uY.png

回顧

前一天【環境建立】時提到,執行 tsc --init 會自動生成 tsconfig.json,也介紹了各個默認配置選項的涵義。今天就不對默認配置做太多說明,來分享幾個實用、常見的配置選項吧

// 默認配置
{
  "compilerOptions": {
    "target": "es2016", // 指定編譯後的 JS 版本
    "module": "commonjs", // 指定編譯後的 JS 要使用哪種模組系統
    "strict": true, // 是否啟用所有嚴格的型別檢查選項
    "esModuleInterop": true, // 是否允許 TypeScript 導入符合 ES6 模組規範的模組
    "skipLibCheck": true, // 是否跳過對 `.d.ts` (聲明檔案)的型別檢查, d:declaration
    "forceConsistentCasingInFileNames": true // 大小寫是否敏感
  }
}

🔗 Day2 環境建立傳送門:https://ithelp.ithome.com.tw/articles/10349532

tsconfig.json 的其他配置選項

tsconfig.json 的配置選項非常多,通常是用到再去找就好
但身邊有朋朋提出疑問:「對配置選項沒有概念,有時候根本不知道哪些地方有提供選項做設定」
覺得這真是個好問題耶~ 官方其實有作分類,分得很細資訊量挺大的XD
所以這邊將分類整合一下:

  1. 環境相關的基本配置
  2. 型別檢查(Type Checking)
  3. 模組(Modules)
  4. 編譯與輸出(Emit)
  5. 編譯範圍
  6. 實驗性選項和延伸模組
  7. 專案參考選項

這邊抽幾個配置來介紹~

環境相關的基本配置

  • target官方說明):指定編譯後的 JS 版本,例如:es5, es6, es2016, ESNext
    如果改變 target 的值,編譯器也會自動調整 lib 的預設值,例如 target 為 es2016; lib 的預設值會被調整為 es2016。target 和 lib 做混合設置也是可以,但官方建議為了方便維護,只設置 target 並讓編譯器自動管理 lib 就好

P.S. ESNext 則表示使用目前最新、尚未被 ECMAScript 正式納入標準的版本

  • lib官方說明):指定編譯時需要引入哪些特定函式庫檔案,例如:ES6DOMDOM.Iterable

DOM: 基本定義和 DOM API (基本定義包括 window, document)
DOM.Iterabl:算是 DOM 的擴展,加入對可迭代的 DOM 集合(NodeList、HTMLCollection 等)的支持,像是能使用 for 迴圈去操作

  • jsx官方說明):指定要如何處理 jsx 的語法,用於 React 開發。可以設定為 preservereactreact-jsxreact-native

preserve:JSX 代碼不會被處理,保留原樣

型別檢查

  • strict官方說明):是否啟用所有嚴格的型別檢查選項
    預設是自動啟用,可以根據專案需求再單獨關閉或註解特定選項的檢查

  • noImplicitAny官方說明):不允許隱含的 any 型別,提醒開發者是否有未明確型別的地方

模組相關

  • baseUrl官方說明):導入模組時的起始路徑
    一般 baseUrl 會設置為 ././src4.1 版本後當你有設置 paths ,這選項就不是必須的了
project
  ├—— src
    ├—— components
      ├—— Header.vue
    ├—— utils
      ├—— helpers.ts
  tsconfig.json

以這個資料夾結構為例,假設 baseUrl: "./",那在 Header.vue 中這樣引入 helpers.ts

import { helpersFunc } from 'utils/helpers';

若沒設置 baseUrl,則要這樣引入

import { helperFunction } from '../../utils/helpers';
  • module官方說明):指定編譯後的 JS 要使用哪種模組系統(module system)
    可以填入 none、commonjs、amd、umd、es2020、ESNext 等

  • rootDir官方說明):告訴 TypeScript 編譯器要從哪個根路徑去編譯(定義編譯的源頭)
    如果你發現你的 src 或是不該被編譯的資料夾出現在 dist 中,就要注意有可能是此選項沒設定好
    預設是 ./,通常設定為 ./src
    rootDir 不會影響到 includeexcludefiles 的設定,他們有各自負責的工作
    rootDir 主要用於設定編譯輸出的目錄結構,而不是控制哪些文件應被包括或排除在編譯中

P.S. rootDirs:與 rootDir 不同的是,rootDirs 允許多個目錄作為編譯的源頭

  • paths官方說明):設置路徑別名,類似 webpack 的 alias
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"]
    },
  }
}
  • resolveJsonModule官方說明):是否能在 TypeScript 中導入 JSON 文件,需要讀取 JSON 文件的時候很實用
    設定 true,代表可以像處理模組一樣處理 JSON 文件
{
  "resolveJsonModule": true,
}

來看看範例
假設有一個 data.json

{
  "name": "Hannah",
  "type": "Human"
}

importJSON.ts 引入 data.json

import data from './JSON/data.json'; // ✅ Pass,不會報錯

console.log(data.name);  // Hannah
console.log(data.type);  // Human

編譯與輸出

  • sourceMap官方說明):編譯時是否輸出 .map 文件,通常是 .js.map.jsx.map,便於在開發工具中進行測試、查看

sourceMap: true 時,編譯後會在 dist 資料夾裡看到相對應的 .js.map
https://ithelp.ithome.com.tw/upload/images/20240912/20149362JzRNwo6nRt.png

你會在編譯出的 .js 檔案裡看到這段自動生成的註解 //# sourceMappingURL=test.js.map
當然 .js 前的檔名會隨著檔案名稱做變化
https://ithelp.ithome.com.tw/upload/images/20240912/20149362scpfdcJrFf.png

  • outDir官方說明):指定編譯後輸出的資料夾,一般是 ./dist

  • removeComments官方說明):是否在編譯時移除代碼中的註釋
    true 代表將從編譯後的 JavaScript 中移除所有註解,提升載入速度。如果在開發過中希望保留註解方便除錯,可以設定為 false 或直接註解此設定

編譯範圍

以下這些選項是寫在 Root Fields,跟 compilerOptions 在同一層

  • include官方說明):指定哪些文件「要」被編譯,可設定多個並用逗號隔開
    通常會跟 rootDir 是一樣的,你也可以額外指定其他檔案
{
  "include": ["src/**/*"] // src 目錄下的所有檔案(包括子目錄)
}
  • files官方說明):明確指定要進行編譯的檔案,TS 只會編譯這裡列出的檔案。當今天專案很小時,甚至小到只有幾支檔案時,用 files 就很合適
{
  "compilerOptions": {},
  "files": ["core.ts", "types.ts"]
}

files 和 include 就像手足,他們個性上有相似的地方,但本質上卻不同
編譯器爸爸接受他們同時存在,但沒辦法同時聽兩個人的意見,心只容得下一人

files 用於明確指定要編譯的檔案, include 用於指定特定檔案的規則

如果只定義了 files,則只有 files 內的檔案會被編譯。
如果只定義了 include,則所有符合 include 規則的檔案都會被編譯。
如果同時定義了 files 和 include,只有 files 中列出的檔案會被編譯,include 的不會。

  • exclude官方說明):指定哪些文件「不要」被編譯,也就是「排除」。預設是 node_modules, outDir的值, bower_components, jspm_packages
{
  "exclude": ["node_modules", "dist"]
}
  • extends官方說明):是否繼承一個現有的 tsconfig.json 配置,值會是字串,裡面填上檔案路徑
    • extends 的值會指向另一個 tsconfig.json 的路徑。當前檔案的設定會把被繼承的檔案加以覆蓋和合併
    • 如果當前的 tsconfig.json 檔案與被繼承檔案有「相同設定」,則當前設定會「覆蓋」繼承的設定,若有「不同設定」則會「合併」
    • 唯一不會繼承的是 references (下方有介紹)

文字描述不好懂的話,可以看圖
https://ithelp.ithome.com.tw/upload/images/20240913/20149362kACACbfvJa.png

專案參考

  • references官方說明):references 是在TypeScript 3.0 新增的,如果專案裡有很多個 tsconfig.json 檔案,例如 tsconfig.base.json, tsconfig.node.json,可以透過 references 指定要引用的專案。這個配置特別適用於大型專案或前後端都放在同個專案下時,可以被組織成多個相互依賴的子專案(例如:共享庫)
project
  ├—— src
  tsconfig.json
  tsconfig.node.json

tsconfig.json 中加上下面這段
references 的結構為陣列包物件,也是寫在 Root Fields,跟 compilerOptions 在同一層

{
  "references": [
    { "path": "./tsconfig.node.json" }
  ]
}

tsconfig.node.json
reference 裡所有參考的子專案中的 composite 務必要設為 true,因為 composite 啟用了 TypeScript 的增量編譯特性,這對在管理和編譯相互依賴的多個專案時是必需的

{
  "compilerOptions": {
    "composite": true,
  }
}

每天講的內容有推到 github 上喔

Reference


上一篇
TypeScript 初學者也能看的學習指南 02 - 起手式:環境建立
下一篇
TypeScript 初學者也能看的學習指南 04 - 型別系統: 型別註釋 & 型別推斷
系列文
TypeScript 初學者也能看的學習指南30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
hannnahTW
iT邦新手 1 級 ‧ 2024-09-13 02:25:52

發現一不小心寫太長 /images/emoticon/emoticon06.gif
但設定檔真的好多內容喔

我要留言

立即登入留言