tsconfig 備忘清單
前言
使用 ts 已多年,但是貌似對於 tsconfig 總是記憶不清,每次都是 cv 歷史項目,所以寫了這篇備忘錄,希望能幫助到大家。
本文總結整理自 Matt Pocock 的一篇文章 3,加以個人理解,並做了一些修改。
配置清單
{
"compilerOptions": {
/* 基礎選項: */
"esModuleInterop": true,
"skipLibCheck": true,
"target": "es2022",
"allowJs": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"isolatedModules": true,
"noUnusedLocals": true,
/* 嚴格模式 */
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
/* 使用 tsc 編譯: */
"module": "NodeNext",
"outDir": "dist",
"sourceMap": true,
/* 需要構建成庫: */
"declaration": true,
/* 需要在 monorepo 中構建成庫: */
"composite": true,
"declarationMap": true,
/* 如果不適用 tsc 編譯: */
"module": "preserve",
"noEmit": true,
/* 如果需要再瀏覽器中運行你的代碼: */
"lib": ["es2022", "dom", "dom.iterable"],
/* 如果你不需要再瀏覽器中運行你的代碼,比如 node: */
"lib": ["es2022"]
}
}
完整的配置說明
基礎配置
{
"compilerOptions": {
"esModuleInterop": true,
"skipLibCheck": true,
"target": "es2022",
"allowJs": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"isolatedModules": true,
"noUnusedLocals": true
}
}
esModuleInterop
:解決 ES Module 和 CommonJS 之間的兼容性問題
比如我們在 ts 中引入 import React from 'react'
, 我們會看到如下報錯
核心是因爲 esm
有 default
這個概念,而 cjs
沒有。任何導出的變量在 cjs
看來都是 module.exports
這個對象上的屬性,esm
的 default
導出也只是 cjs
上的 module.exports.default
屬性而已,而且目前已有的大量的第三方庫大多都是用 UMD
/ cjs
寫的(或者說,使用的是他們編譯之後的產物,而編譯之後的產物一般都爲 cjs
),但現在前端代碼基本上都是用 esm
來寫,所以 esm
與 cjs
需要一套規則來兼容。
詳細解釋可參見:_esModuleInterop 到底做了什麼?_1
-
skipLibCheck
:默認情況下,TypeScript 會對加載的類型聲明文件進行檢查,包括內置的lib.d.ts
和各種@type/*
,可以使用 skipLibCheck 跳過對這些類型聲明文件的檢查,這也能進一步加快編譯速度。 -
target
:指定 ECMAScript 目標版本,可選值:es3、es5、es2015、es2016、es2017、es2018、es2019、es2020、es2021、esnext。如果沒有特殊需要,推薦將 target 設置爲 "es2018",一個對常用語法支持較爲全面的版本。需要注意的是,更改 target 配置也會同時影響你的 lib 配置默認值 -
allowJs
和resolveJsonModule
:允許導入 js 和 json -
moduleResolution
: 指定模塊的解析規則,其實就是 node 如何去查找模塊的規則,可選值:node、classic、none。詳細解釋:_moduleResolution 總結_2 -
isolatedModules
:確保每一個文件都被視爲獨立模塊(可被獨立編譯) -
noUnusedLocals
:當設置爲 true,編譯器會報告文件中未使用的局部變量
嚴格模式
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true
}
}
-
strict
: 開啓嚴格模式,具體來說啓動了以下選項: -
noImplicitAny
: 不允許隱式的 any 類型 -
noImplicitThis
: 不允許對 this 表達式的隱式 any 類型。 -
alwaysStrict
: 以嚴格模式(strict mode)解析併爲每個源文件生成 "use strict"。 -
strictBindCallApply
: 更嚴格地檢查 bind、call 和 apply 的參數是否與原函數匹配。 -
strictNullChecks
: 在嚴格空檢查模式下工作,null 和 undefined 值不包含在任何類型中,只允許對他們執行任何操作。 -
strictFunctionTypes: 禁止函數參數雙向協變檢查
-
strictPropertyInitialization: 確保類的每個實例屬性都被明確賦值。
-
noUncheckedIndexedAccess :啓用後,可對索引簽名進行更加嚴格的檢查,使得訪問如對象或數組等帶索引簽名類型的元素時,返回的類型會自動包含 undefined。這讓開發人員更像在嚴格 null 檢查的環境中工作時一樣意識到可能未定義的值。
const array: number[] = [];
const value: number | undefined = array[0]; // noUncheckedIndexedAccess -> value有類型number | undefined
noImplicitOverride
: 當一個子類的方法重寫了基類的方法時,需要用override
關鍵字顯式地標記這個行爲。這確保了當基類的方法被重命名或移除的時候,派生類也相應地更新,防止意外的覆蓋或者運行時錯誤。
class Base {
greet() {}
}
class Derived extends Base {
greet() {} // Error! 方法應該有override關鍵字來標記重寫
override greet() {} // Correct
}
使用 tsc 編譯
{
"compilerOptions": {
"module": "NodeNext",
"outDir": "dist"
}
}
-
module
:指定生成哪種模塊系統代碼,可選值:None、CommonJS、AMD、System、UMD、ES6、ES2015、ESNext。 -
outDir
:指定輸出目錄
爲庫構建
{
"compilerOptions": {
"declaration": true
}
}
declaration
:生成相應的.d.ts
文件,對於 JavaScript 庫來說非常有用,你懂的
對於構建 monorepo 的類庫 (大型複雜項目同樣適用)
{
"compilerOptions": {
"declaration": true,
"composite": true,
"sourceMap": true,
"declarationMap": true
}
}
composite
:在Project References
的被引用子項目 tsconfig.json 中必須爲啓用狀態,它通過一系列額外的配置項,確保你的子項目能被Project References
引用,而在子項目中必須啓用declaration
,必須通過files
或includes
聲明子項目內需要包含的文件等。
這是 TypeScript3.0 新增的配置,核心是提供的Project Reference
能力,當然,這個不僅僅適用於構建 monorepo
的類庫,對於構建單個項目的類庫也同樣適用。
-
sourceMap
:啓用這個選項後,編譯過程會生成 .js.map 文件,這些文件是原始源文件(.ts)和生成的 JavaScript 文件(.js)之間的映射信息。有了 source map,你可以在調試時看到原始的 TypeScript 源碼而不是編譯後的 JavaScript 代碼,這極大地簡化了調試過程 -
declarationMap
: 當這個選項和 declaration 一起啓用時,編譯器不僅會爲 .ts 文件生成 .d.ts 聲明文件,還會創建 .d.ts.map 文件。這些 map 文件包含了. ts 源文件和. d.ts 聲明文件之間的映射信息,允許在使用類型定義文件時進行源碼映射。這使得在使用 IDE 或調試器時,開發者可以直接從使用庫的代碼跳轉到相應的類型定義中,即便這些定義來自第三方庫。
不適用 tsc 編譯
{
"compilerOptions": {
"module": "preserve",
"noEmit": true
}
}
-
module
: 指定生成哪種模塊系統代碼, 設置爲 "preserve
",這告訴 TypeScript 編譯器在處理模塊語法時不要轉換 ES6 模塊語句(如import
和export)
-
noEmit
: 不生成輸出, 只用ts
來做類型檢查,這也是現在的很多 CI 環境中常用的方式。實際的js
代碼由 Babel 去編譯生成
在 DOM 中運行
{
"compilerOptions": {
"lib": ["es2022", "dom", "dom.iterable"]
}
}
-
lib 選項通常用於模擬特定的運行環境,告訴 TypeScript 編譯器那些 api 是內置的,可以直接使用的
-
es2022:這個庫包含了 ECMAScript 2022(或者說是 ES12)標準規定的所有特性的類型聲明
-
dom: 這個庫提供了所有與 Web 瀏覽器的文檔對象模型(DOM)相關的類型聲明
-
dom.iterable:這個庫提供了關於 DOM 中可迭代對象(如 NodeList 或 HTMLCollection)的類型聲明
如果不是在 DOM 中運行,那麼可以將 lib 選項改爲 ["es2022"]
即可
常用配置
其他常用配置這裏就不說了,包括 include
、exclude
、files
、baseUrl
、rootDir
等
關於上述基本配置,可以從 tsconfig.guide4 中 copy 出來
參考文章
-
Nealyang/PersonalBlog https://github.com/Nealyang/PersonalBlog/issues/136
-
esModuleInterop 到底做了什麼? https://zhuanlan.zhihu.com/p/148081795
-
moduleResolution 總結 https://zhuanlan.zhihu.com/p/621795173
-
tsconfig-cheat-sheet https://www.totaltypescript.com/tsconfig-cheat-sheet
-
tsconfig.guide https://tsconfig.guide/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/6MEnHHlsaztp-K5l63xmHA