精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

會寫 TypeScript 但你真的會 TS 編譯配置嗎?

開發 前端
TypeScript 是一種基于 JavaScript 的強類型編程語言,它使得在前端項目開發過程中更加嚴謹且流暢,一定程度上保證了大型前端項目程序的健壯性。

最近遇到了挺多涉及到前端“編譯”方面的工作,其中關于 TypeScript 的編譯會涉及到關于 tsconfig.json 文件的配置,由于配置項繁雜,遂逐一解析并驗證,減少大家的一些疑惑,并提升工作效率!

隨著 TypeScript 的流行,越來越多的項目通過使用 TypeScript 來實現編寫代碼時候的類型提示和約束,從開發過程中減少 BUG 出現的概率,以此提升程序的健壯性和團隊的研發效率。

為什么會單獨寫一篇文章來講述 tsconfig.json 文件的配置吶?原因是筆者在做 TS 項目的時候,由于對其中的配置項不熟悉,搞來搞去,搞好久,煩死了!所以決定好好梳理下。

越來越多的項目用上了 TypeScript,因此如何按需配置 tsconfig 也應該是前端工程師需要掌握的技能之一。

本文內容結構如下,朋友們按需食用:

 

一、前置知識 

在熟悉掌握 tsconfig.json 文件配置前,先給首次接觸 TS 的同學預備一下“前置知識”。

1.1 TypeScript 是什么?

TypeScript 官網:https://www.typescriptlang.org

TypeScript 是一種基于 JavaScript 的強類型編程語言,它使得在前端項目開發過程中更加嚴謹且流暢,一定程度上保證了大型前端項目程序的健壯性。

  • TypeScript 是由微軟開發的一款開源的編程語言;
  • TypeScript 是 JavaScript 的超集,遵循最新的 ESM 規范,TypeScript 擴展了 JavaScript 的語法;
  • TypeScript 更像后端 JAVA、C# 這樣的面向對象語言,可以讓 JS 開發大型企業級項目。

但是 TypeScript 并不可以直接運行,而是需要轉換成 JavaScript 代碼才可以在 Node.js 或瀏覽器環境下執行,因此我們需要通過“編譯器”將 TS 代碼轉換為 JS 代碼。

1.2 什么是 tsc ?

tsc 的全稱是 TypeScript Compiler,也就是將 TypeScript 轉碼為 JavaScript 代碼的編譯器。

tsc 的全局安裝方式:

  1. npm install typescript -g 

當我們編譯一份 index.ts 文件時,會使用下面的命令:

  1. tsc ./index.ts 

這樣就可以得到一份編譯成為 JavaScript 代碼的 ./index.js 文件。

tsc 實際就是將 TS 轉為 JS 的編譯(器)腳手架工具,如果是一個 TS 的前端工程項目,那么就可以通過項目中的 tsconfig.json 文件來自定義配置 TS 編譯相關規則。

項目中的 tsconfig.json 文件,我們一般會通過如下快捷命令生成:

  1. tsc --init 

執行完后,會在項目根目錄生成一個簡單的初始化 tsconfig.json 配置描述文件,如果沒有特別的要求,該初始化配置就足以支持你愉快地使用 TS 開發啦!

更多相關 TS 編譯配置和使用說明可以通過 tsc -h 查看。

1.3 tsconfig.json 文件

tsconfig.json[1] 文件是用于描述將 TypeScript 轉為 JavaScript 代碼的配置文件。

IDE(代碼編輯器)將會根據 tsconfig.json 文件來對當前項目中支持不同程度的類型約束,同時也是對 TSC 編譯 TypeScript 代碼過程做一些預定義、約束入口和編譯輸出目錄等配置。

因此對于一個支持 TypeScript 編程語言的工程來說,tsconfig.json 文件就是編碼的基礎。

二、tsconfig.json 配置詳解 

有了上面的前置知識作為基石,相信大家會對 tsconfig.json 文件的配置項也會更加容易理解。

  • tsconfig 的詳細配置:https://www.typescriptlang.org/tsconfig
  • tsconfig 的協議描述網址:http://json.schemastore.org/tsconfig

tsconfig 協議

 

筆者將從常見的配置項單獨解釋,然后在最后會將一些不常用的配置統一解釋,朋友們可以將這篇文章收藏一下,可當作一份 tsconfig 配置的中文查詢對照表 👀。

2.1 files

files 字段用于指明需要 tsc 編譯的一個或多個 ts 文件,例如:

  1.   "files": ["index.ts""global.d.ts"], 

當指定的文件或文件夾不存在時,會提示 ❌ 錯誤!

2.2 include

include 字段用于指明需要被 tsc 編譯的文件或文件夾列表,例如:

  1.   "include": [ 
  2.     "src"
  3.     "global.d.ts" 
  4.   ], 

2.3 exclude

exclude 字段用于排除不需要 tsc 編譯的文件或文件夾列表,例如:

  1.   "exclude": ["test.ts""src/test.ts"], 

注意: exclude 字段中的聲明只對 include 字段有排除效果,對 files 字段無影響,即與 include 字段中的值互斥。

如果 tsconfig.json 文件中 files 和 include 字段都不存在,則默認包含 tsconfig.json 文件所在目錄及子目錄的所有文件,且排除在 exclude 字段中聲明的文件或文件夾。

2.4 compileOnSave

compileOnSave 是聲明是否需要在保存時候自動觸發 tsc 編譯的字段,一般來說,我們的代碼編譯過程會通過 Rollup、Webpack 等打包構建工具,并且使用熱更新,因此無需配置該項,保持缺省即可。

  1.   "compileOnSave"false

2.5 extendsextends

字段用于指明繼承已有的 tsconfig 配置規則文件。

該字段可以說是非常有用了,因為我們的 tsconfig 配置其實各個項目之間大同小異,因此完全可以結合自己團隊的情況,抽離一個基礎且公共的 tsconfig 配置,并將其發包,然后作為 extends 字段的值來繼承配置。

tsconfig 推薦默認配置可以參考官方的包:@tsconfig/recommended[2]

@tsconfig/recommended 的配置如下:

  1.   "compilerOptions": { 
  2.     "target""ES2015"
  3.     "module""commonjs"
  4.     "strict"true
  5.     "esModuleInterop"true
  6.     "skipLibCheck"true
  7.     "forceConsistentCasingInFileNames"true 
  8.   }, 
  9.   "$schema""https://json.schemastore.org/tsconfig"
  10.   "display""Recommended" 

例如繼承一個發包后的 tsconfig 基礎配置,并通過顯示聲明編譯的目標代碼版本為 ES2016 來覆蓋覆蓋 @tsconfig/recommended 中對應配置項。

  1.   "extends""@tsconfig/recommended/tsconfig.json"
  2.   "compilerOptions": { 
  3.     "target""ES2016" 
  4.   } 

作為一些實踐經驗,社區也提供了一些常見環境(例如:Nuxt、Vite、Node 等)最佳實踐后的基礎配置,推薦參閱:https://github.com/tsconfig/bases/[3]

2.6 compilerOptions

compilerOptions 是一個描述 TypeScript 編譯器功能的“大”字段,其值類型是“對象”,因此包含了很多用于描述編譯器功能的子字段,其子字段的功能如下:

(1). target

target 字段指明經過 TSC 編譯后的 ECMAScript 代碼語法版本,根據 ECMAScript 語法標準,默認值為 ES3。

TypeScript 是 JavaScript 的超集,是對 JavaScript 語法和類型上的擴展,因此我們可以使用 ES5、ES6,甚至是最新的 ESNext[4] 語法來編寫 TS。例如當我們使用 ES2021 語法來編碼 TS 文件,同時配置如下:

  1.   "compilerOptions": { 
  2.     "target""ES5"
  3.   } 

則會將對應使用了最新 ECMAScript 語法的 TS 文件編譯為符合 ES5 語法規范的 *.js 文件。

延伸一下知識點,思考一下 tsc 是如何將高版本(ECMAScript 規范)代碼向低版本代碼轉換的?這個轉換的結果靠譜嗎?與 Babel 有何差異?

一圖看 ECMAScript 各版本功能差異

另外對于個版本差異有想簡單了解的👬,可以閱讀《1.5萬字概括ES6全部特性[5]》

通過一個實驗,在 src/index.ts 文件中使用了 Map、Async/Await、Promise、擴展運算符,并在 tsconfig.jon -> target 設置為 ES5:

驗證 target 降級處理

然后發現在右側的 dist/index.js 文件中,依然存在 new Map() 、Promise 語法,因此可以得出結論:tsc 的代碼降級編譯并不能完全處理兼容性。

通過官方文檔了解到:

這里提到了 lib 字段,意思是 target 不同的值會有對應默認的 lib 字段值,當然也支持開發者顯示指明 lib 字段的值,那么接下來看看 lib 是干嘛的吧!

(2). lib

lib 字段是用于為了在我們的代碼中顯示的指明需要支持的 ECMAScript 語法或環境對應的類型聲明文件。

例如我們的代碼會使用到瀏覽器中的一些對象 window、document,這些全局對象 API 對于 TypeScript Complier 來說是不能識別的:

lib 未顯示引入 DOM 會提示類型錯誤

因而需要在 lib 字段中如下配置:

  1.   "compilerOptions": { 
  2.     "target""ES5"
  3.     "lib": ["ES5""ES6""DOM"], 
  4.   } 

來顯式引入在 DOM 即瀏覽器環境下的一些默認類型定義,即可在代碼中使用,window、document 等瀏覽器環境中的對象,TS 在運行時以及編譯時就不會報類型錯誤。

引入類型定義后無錯誤提示

綜合 target 和 lib 字段的實際功能表現,我們可以得出結論:

TSC 的編譯結果只有部分特性做了 pollyfill 處理,ES6[6] 的一些特性仍然被保留,想要支持完全的降級到 ES5 還是需要額外引入 pollyfill(也就是我們在項目的入口文件處 import 'core-js'),但建議是將 target 字段值設置為 ES6,提升 TSC 的速度。

因此,筆者對于使用 TSC 編譯的觀點是:

不應該將 TSC 作為編譯項目的工具,應該將 TSC 作為類型檢查工具,代碼編譯的工作盡量交給 Rollup、Webpack 或 Babel 等打包工具!

另外推薦閱讀《為什么說用 babel 編譯 typescript 是更好的選擇》

(3). module

module 字段指明 tsc 編譯后的代碼應該符合何種“模塊化方案”,可以指定的枚舉值有:none, commonjs, amd, system, umd, es2015, es2020, 或 ESNext,默認值為 none。

在如今的前端開發趨勢來講,主要是使用 ESM、CommonJS、UMD、IIFE 四種模塊化方案,未來會趨向于 ESM,當然我們會根據項目的應用場景來決定使用何種模塊化方案,例如:NodeJS 使用 CommonJS,瀏覽器里可以使用 ESM,不過現在的打包工具,會自動處理 CommonJS 和 ESM 的差異,并包裝成符合指定模塊化規范的代碼,

在 tsconfig.json 可以設置 allowSyntheticDefaultImports 字段為 true,來允許合成默認導入。

(4). esModuleInterop

簡單來說,就是支持合成默認導入。

在前端項目開發時,使用 ESM 編寫代碼引入了 CJS 的模塊,由于 CJS 模塊沒有默認導出內容,因此需要通過我們的工具去自動化合成 CJS 的默認導出,以支持在 ESM 下流暢開發。

參閱文章《esModuleInterop 到底做了什么?[7]》,講得非常詳細也非常好。

當 esModuleInterop 字段設置為 true 時候,上述提到的 allowSyntheticDefaultImports 字段也會自動設置為 true。

(5). moduleResolution

moduleResolution 聲明如何處理模塊,枚舉值:classic、node,會根據 module 字段決定默認值。

推薦手動設置為 node,更符合現在大家的編碼認識一些,而且大部分的構建打包工具都是基于 Node。

舉個,遇到 import {a} from 'a-lib'; 這樣的模塊引入代碼應該如何去(解析)查找到對應的模塊文件。

(6). baseUrl & paths

baseUrl:設置基本目錄以解析非絕對模塊名稱(定義一個根目錄,以此進行絕對文件路徑解析)

paths:用于設置模塊名或路徑映射列表,這樣就可以簡寫項目中自定義模塊的文件路徑。

舉一個 :

  1.   "compilerOptions": { 
  2.     // 注意:baseUrl 必選,與 paths 成對出現,以 tsconfig.json 文件所在目錄開始 
  3.     "baseUrl"".",  
  4.     "paths": { 
  5.       // 映射列表 
  6.       "@/*": [ 
  7.         "src/*" 
  8.       ], 
  9.       "moduleA": [ 
  10.         "src/libs/moduleA" 
  11.       ] 
  12.     } 
  13.   } 
  14.  
  15. // 代碼里這么寫 
  16. import Toast from '@/components/Toast.ts' // 模塊實際位置: src/components/Toast.ts 
  17. import TestModule from 'moduleA/index.js' // 模塊實際位置: src/libs/moduleA/index.js 

⚠️ 注意: 如果需要自動生成(導出)類型定義文件,TSC 不會處理路徑別名,需要引入 typescript-transform-paths[8] 插件,以及 TTypescript[9] 來轉換路徑別名為相對路徑。

由于當前的 TypeScript 不支持 tsconfig.json 中的自定義轉換器,且無法使用 tsc 命令使用自定義轉換器編譯文件,所以引入了 TTypescript 作為包裝器

  1. // tsconfig.json 
  2.   "compilerOptions": { 
  3.     "baseUrl""./"
  4.     // 配置路徑別名映射 
  5.     "paths": { 
  6.       "@/*": ["src/*"
  7.     }, 
  8.     "plugins": [ 
  9.       // 轉換輸出 js 文件中的路徑 
  10.       { "transform""typescript-transform-paths" }, 
  11.  
  12.       // 轉換輸出 .d.ts 文件中的路徑 
  13.       { "transform""typescript-transform-paths""afterDeclarations"true } 
  14.     ] 
  15.   } 

plugins[10] 是用于擴展 TSC 編譯器功能的字段。

例如在 Rollup 打包環境下,可以如下配置:

  1. import typescript from '@rollup/plugin-typescript'
  2. import ttypescript from 'ttypescript'
  3.  
  4. export default [ 
  5.   { 
  6.     input: './src/index.ts'
  7.     output: { 
  8.       dir: 'dist'
  9.       format: 'cjs'
  10.       entryFileNames: 'index.js'
  11.     }, 
  12.     plugins: [ 
  13.       typescript({ 
  14.         typescript: ttypescript, 
  15.       }), 
  16.     ], 
  17.   }, 
  18. ]; 

如果是有自動導出類型定義文件的需求,才需要搞這一套插件~

(7). rootDir & outDir

rootDir:指定 TypeScript 識別讀取的根目錄,用于所有非聲明輸入文件的最長公共路徑

例如:'"rootDir": "./src",則 src 目錄下的 TS 文件不能引用 src 目錄以外的 ts 文件,一般我們會設置為 ./src 或 ./(即 tsconfig.json 所在目錄)

outDir:輸出目錄,即 tsc 編譯后的文件輸出的文件夾路徑(基于 tsconfig.json 文件的相對路徑)

例如:"outDir": "./dist",及將 TSC 編譯輸出的 JS 文件,統一輸出的 ./dist 目錄下。

(8). jsx

如果是有 jsx 語法需要支持的項目,可以設置值 preserve、react 等

  1.   "compilerOptions": { 
  2.     "jsx""preserve", // 一般 preserve 即可 
  3.   }, 

(9). importHelpers

importHelpers 決定是否啟用從 tslib 庫引入語法降級輔助函數,以避免重復冗余的輔助函數聲明。

個人建議是設置為 true 來啟用。

(10).experimentalDecorators

experimentalDecorators 用于聲明是否啟實驗性用裝飾器模式。

TypeScript 和 ES6 中引入了 Class 的概念,同時在 Decorators[11] 提出了裝飾器模式,通過引入裝飾器模式,能極大簡化書寫代碼。

當前對于 Decorator 的支持性不太好,如果是一些涉及到使用了裝飾器的需要,就需要開啟這個屬性。

(11). noEmit

noEmit 設置是否輸出 js 文件,一般是設置為 false,將打包等工作交給 Webpack 等工具。

三、tsconfig.json 全解析 

上面針對 tsconfig.json 中一些常見配置做了詳細解釋,將一些不常用的配置字段組合在一起,做一個 Checklist 如下:

  1.   "compilerOptions": { 
  2.     /* 基本選項 */ 
  3.     "target""es6", // 指定 ECMAScript 目標版本: 'ES3' (default), 'ES5''ES2015''ES2016''ES2017'or 'ESNEXT' 
  4.     "module""commonjs", // 指定使用模塊: 'commonjs''amd''system''umd' or 'es2015' 
  5.     "lib": [], // 指定要包含在編譯中的庫文件 
  6.     "allowJs"true, // 允許編譯 javascript 文件 
  7.     "checkJs"true, // 報告 javascript 文件中的錯誤 
  8.     "jsx""preserve", // 指定 jsx 代碼的生成: 'preserve''react-native'or 'react' 
  9.     "declaration"true, // 生成相應的 '.d.ts' 文件 
  10.     "declarationDir""./dist/types", // 生成的 '.d.ts' 文件保存文件夾 
  11.     "sourceMap"true, // 生成相應的 '.map' 文件 
  12.     "outFile""./", // 將輸出文件合并為一個文件 
  13.     "outDir""./dist", // 指定輸出目錄 
  14.     "rootDir""./", // 用來控制輸出目錄結構 --outDir. 
  15.     "removeComments"true, // 刪除編譯后的所有的注釋 
  16.     "noEmit"true, // 不生成輸出文件 
  17.     "importHelpers"true, // 從 tslib 導入輔助工具函數 
  18.     "isolatedModules"true, // 將每個文件做為單獨的模塊 (與 'ts.transpileModule' 類似). 
  19.  
  20.     /* 嚴格的類型檢查選項 */ 
  21.     "strict"true, // 啟用所有嚴格類型檢查選項 
  22.     "noImplicitAny"true, // 在表達式和聲明上有隱含的 any類型時報錯 
  23.     "strictNullChecks"true, // 啟用嚴格的 null 檢查 
  24.     "noImplicitThis"true, // 當 this 表達式值為 any 類型的時候,生成一個錯誤 
  25.     "alwaysStrict"true, // 以嚴格模式檢查每個模塊,并在每個文件里加入 'use strict' 
  26.  
  27.     /* 額外的檢查 */ 
  28.     "noUnusedLocals"true, // 有未使用的變量時,拋出錯誤 
  29.     "noUnusedParameters"true, // 有未使用的參數時,拋出錯誤 
  30.     "noImplicitReturns"true, // 并不是所有函數里的代碼都有返回值時,拋出錯誤 
  31.     "noFallthroughCasesInSwitch"true, // 報告switch語句的fallthrough錯誤。(即,不允許switch的case語句貫穿) 
  32.  
  33.     /* 模塊解析選項 */ 
  34.     "moduleResolution""node", // 選擇模塊解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6) 
  35.     "baseUrl""./", // 用于解析非相對模塊名稱的基礎目錄 
  36.     "paths": {}, // 模塊名到基于 baseUrl 的路徑映射的列表 
  37.     "rootDirs": [], // 根文件夾列表,其組合內容表示項目運行時的結構內容 
  38.     "typeRoots": [], // 包含類型聲明的文件列表 
  39.     "types": [], // 需要包含的類型聲明文件名列表 
  40.     "allowSyntheticDefaultImports"true, // 允許從沒有設置默認導出的模塊中默認導入。 
  41.     "esModuleInterop"true, // 支持合成模塊的默認導入 
  42.    
  43.     /* Source Map Options */ 
  44.     "sourceRoot""./", // 指定調試器應該找到 TypeScript 文件而不是源文件的位置 
  45.     "mapRoot""./", // 指定調試器應該找到映射文件而不是生成文件的位置 
  46.     "inlineSourceMap"true, // 生成單個 soucemaps 文件,而不是將 sourcemaps 生成不同的文件 
  47.     "inlineSources"true, // 將代碼與 sourcemaps 生成到一個文件中,要求同時設置了 --inlineSourceMap 或 --sourceMap 屬性 
  48.  
  49.     /* 其他選項 */ 
  50.     "experimentalDecorators"true, // 啟用裝飾器 
  51.     "emitDecoratorMetadata"true // 為裝飾器提供元數據的支持 
  52.   }, 
  53.   /* 指定編譯文件或排除指定編譯文件 */ 
  54.   "include": ["src/**/*"], 
  55.   "exclude": ["node_modules""**/*.spec.ts"], 
  56.   "files": ["index.ts""test.ts"], 
  57.   // 從另一個配置文件里繼承配置 
  58.   "extends""@tsconfig/recommended"
  59.   // 讓 IDE 在保存文件的時候根據 tsconfig.json 重新生成文件 
  60.   "compileOnSave"true // 支持這個特性需要Visual Studio 2015, TypeScript 1.8.4 以上并且安裝 atom-typescript 插件 

四、打包工具中的 TypeScript 

前文講到了為什么不推薦直接使用 TSC 作為項目的打包編譯工具,那么接下來就簡單看看在常見的幾款打包工具中針對 TypeScript 的編譯方案是如何設計的?

4.1 Rollup + TypeScript

在 Rollup 打包中,我們一般只需要添加 @rollup/plugin-typescript[12] 插件即可,該插件會默認讀取項目根目錄下的 tsconfig.json 配置文件。

Rollup 的配置就像這樣:

  1. // file: rollup.config.js 
  2. import typescript from '@rollup/plugin-typescript'
  3.  
  4. export default { 
  5.   input: 'src/index.ts'
  6.   output: { 
  7.     dir: 'output'
  8.     format: 'cjs' 
  9.   }, 
  10.   plugins: [typescript()] 
  11. }; 

結合其源碼:

默認使用 TSC 作為 TS 的編譯器

因為 typescript 聲明了是 peerDependencies,因此會采用項目中安裝的 typescript 版本,即是使用我們項目中的 TS 編譯器。

通過閱讀 @rollup/plugin-typescript 源碼,可以看到該插件會默認使我們自己項目中的 tsconfig.json 文件作為 TSC 編譯的配置,但會做一些配置預設覆蓋:

會調用 ts.parseJsonConfigFileContent() 方法,將 FORCED_COMPILER_OPTIONS 值 merge 到用戶的自定義配置中。

FORCED_COMPILER_OPTIONS

通過英文解釋看到,因為需要 TSC 編譯獲得 JS 產物,所以會將 noEmit 設置為 false,也就是 TSC 編譯會輸出文件,但為什么我們在輸出目錄卻沒有看到對應的 TSC 產物吶?

TSC 編譯結果存儲到內存中

但是如果開啟了 declaration,則會將 TSC 解析得到的 *.d.ts 文件輸出到指定目錄。

4.2 Webpack + TypeScript

在 Webpack 中的 TypeScript[13] 官方文檔中,指明了需要安裝:typescript 和 ts-loader 兩個模塊。

配置 Webpack 并支持 TypeScript 的配置如下:

  1. // file: webpack.config.js 
  2. const path = require('path'); 
  3.  
  4. module.exports = { 
  5.   entry: './src/index.ts'
  6.   module: { 
  7.     rules: [ 
  8.       { 
  9.         test: /\.tsx?$/, 
  10.         use: 'ts-loader'
  11.         exclude: /node_modules/, 
  12.       }, 
  13.     ], 
  14.   }, 
  15.   resolve: { 
  16.     extensions: ['.tsx''.ts''.js'], 
  17.   }, 
  18.   output: { 
  19.     filename: 'bundle.js'
  20.     path: path.resolve(__dirname, 'dist'), 
  21.   }, 
  22. }; 

可以看出 Webpack 主要是依賴 ts-loader 實現對 TypeScript 語法的編譯支持,再看看對 ts-loader 的介紹:

ts-loader

換句話說,ts-loader 實際調用了 TSC 來編譯 TS 文件,TSC 的配置依賴于你項目中的 tsconfig.json 文件。

如果使用了 Babel,則可以使用 @babel/preset-typescript[14] 來處理,但 Babel 不會做 TS 類型校驗,在打包工具 Rollup 和 Webpack 中都可以引入 Babel,那么接下來看看 Babel 是如何處理 TypeScript 的吧!

4.3 Babel + TypeScript

Babel 處理 TS 需要安裝 @babel/preset-typescript 模塊,然后在 babel 項目配置文件中聲明:

  1. // 配置說明:https://babeljs.io/docs/en/babel-preset-typescript 
  2.   "presets": ["@babel/preset-typescript"

但 Babel 中只會對 TS 代碼轉為 JS 代碼(通過 parse TS 文件為 AST,并直接移除類型信息,然后打印目標代碼),不會去做 TS 類型檢查,所以 Babel 編譯 TS 文件相較于 TSC 的速度更快!

同時,因為 Babel 會根據不同的兼容環境,按需引入 pollyfill,比 TSC 直接引入 core-js 更優雅,因此使用了 Babel 打包的體積也會更小。

TS 類型檢查工作可以交給代碼編輯器承擔,當然同時可以新增 TS 檢查的命令:

  1. // package.json 
  2.   "script": { 
  3.     "tsCheck""tsc --noEmit"
  4.   } 

可以把類型檢查放到特定的 npm scripts 生命周期之前,另外其實也可以將類型檢查放到 git commit 階段,用于做必要的 TS 類型檢查,保證項目的正確性。

4.4 ESbuild + TypeScript

通過 Vite 體會到了 ESbuild[15] 帶來的開發熱更新“極速”體驗,針對 TS 項目,ESbuild 和 Babel 是相同的編譯策略,即僅編譯,不校驗類型。

ESbuild 處理 TypeScript[16] 同樣可以帶來飛一般的感覺!

Vite 使用 esbuild 將 TypeScript 轉譯到 JavaScript,約是 tsc 速度的 20~30 倍,同時 HMR 更新反映到瀏覽器的時間小于 50ms。—— Vite Docs[17]

但在 ESbuild 中需要啟用 tsconfig 中的 isolatedModules 功能,然后在類型引入的時候需要替換,規則參考如下:

  1. // old 
  2. import { UserType } from './types'
  3.  
  4. // new 
  5. import type { UserType } from './types'

因為 ESbuild 是單獨編譯每個文件,無法判斷引入的是 Type(類型) 還是 值,所以需要開發者顯示地聲明是“Type”。

同時還需要啟用 esModuleInterop 功能,用于支持 ESM 模塊合成默認導入,以兼容 CJS 和 ESM 規范。

另外 ESbuild 不支持:emitDecoratorMetadat、const enum 類型和 *.d.ts 文件

此外,關注到兼容性處理這方面,Bable 和 ESbuild 是類似的,因此會存在兼容性問題:

兼容性

對于裝飾器處理不支持,因為 TS 是 JS 的超集,ESnext 的規范提案某些還不是穩定的,因此如果有這方面訴求的項目,可以借助 TSC 做預編譯,例如使用 Rollup 的 typescript 插件 或 Webpack 的 ts-loader 方式。

五、總結 

針對 TypeScript 項目的類型檢查和編譯流程算是完整過了一遍,相信已足以支撐大家在工作中自定義化配置 TS 前端項目!

另外,tsconfig.json 推薦配置策略如下:

  1. 借助 extends 字段,并結合項目應用場景,繼承官方推薦配置
  2. 針對項目特點,按需修改對應功能配置
  3. 建議啟用 importHelpers、esModuleInterop,取消 noEmit 輸出
  4. TS 項目的打包構建,推薦使用 Webpack、Rollup、Bable 等專業工具來保證正確性和構建優化

參考資料

[1]TSconfig.json 手冊: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html

[2]@tsconfig/recommended: https://www.npmjs.com/package/@tsconfig/recommended

[3]TSconfig 最佳實踐配置: https://github.com/tsconfig/bases/

[4]ES.Next 語法提案: https://github.com/tc39/proposals

[5]1.5萬字概括ES6全部特性: https://watesegmentfault.com/a/1190000020678240

[6]ES6 語法新特性: http://es6-features.org/#Constants

[7]esModuleInterop 到底做了什么?: https://zhuanlan.zhihu.com/p/148081795

[8]typescript-transform-paths: https://www.npmjs.com/package/typescript-transform-paths

[9]TTypescript: https://www.npmjs.com/package/ttypescript

[10]compilerOptions.plugins: https://www.typescriptlang.org/tsconfig#plugins

[11]Decorators: https://github.com/tc39/proposal-decorators

[12]@rollup/plugin-typescript: https://github.com/rollup/plugins/tree/master/packages/typescript/#readme

[13]Webpack 中的 TypeScript: https://webpack.docschina.org/guides/typescript/

[14]@babel/preset-typescript: https://babeljs.io/docs/en/babel-preset-typescript

[15]ESbuild: https://esbuild.github.io/

[16]ESbuild 處理 TypeScript: https://esbuild.github.io/content-types/#typescript

[17]Vite Docs: https://cn.vitejs.dev/guide/features.html#typescript

 

責任編輯:姜華 來源: DYBOY
相關推薦

2019-08-27 08:24:17

簡歷技能工作

2019-12-27 08:33:45

Java工具IDE

2022-03-25 09:39:50

LinuxLinux top

2017-11-07 12:35:53

比特幣區塊鏈虛擬貨幣

2022-04-07 16:03:36

JavaScriptTypeScript

2021-07-13 06:42:58

JavaEquals方法

2017-11-13 14:06:56

2019-01-22 15:37:01

GitHub代碼開發者

2016-06-01 15:42:58

Hadoop數據管理分布式

2023-03-01 09:39:05

2014-04-17 16:42:03

DevOps

2020-04-17 14:25:22

Kubernetes應用程序軟件開發

2022-07-26 00:00:22

HTAP系統數據庫

2025-08-06 08:53:35

2017-10-10 11:11:14

2024-04-23 08:31:57

pythonfalse

2021-11-09 09:48:13

Logging python模塊

2021-04-23 07:27:31

內存分配CPU

2022-08-15 10:42:50

千兆網絡千兆光纖

2021-01-15 07:44:21

SQL注入攻擊黑客
點贊
收藏

51CTO技術棧公眾號

日本麻豆一区二区三区视频| 精品午夜视频| 久久精品人人做人人综合| 97激碰免费视频| 欧亚乱熟女一区二区在线| av老司机在线观看| 久久久久久久综合日本| 国产精品一区二区久久| 欧美做爰爽爽爽爽爽爽| 黄瓜视频成人app免费| 欧美韩日一区二区三区四区| 国产精品美女av| 懂色av粉嫩av蜜臀av一区二区三区| 九七电影院97理论片久久tvb| 亚洲欧美国产高清| 国外成人免费视频| 成人黄色免费网| 91精品国产自产在线观看永久∴| 日韩精品一区二区三区swag | 日韩一级裸体免费视频| 视频免费1区二区三区| 国产理论电影在线| 久久精品亚洲乱码伦伦中文| 成人黄色大片在线免费观看| 日本系列第一页| 日韩精品1区| 欧美va亚洲va在线观看蝴蝶网| 免费黄色福利视频| av在线下载| 国产亚洲欧美日韩日本| 99超碰麻豆| 天天爽夜夜爽人人爽| 一区二区三区网站| 中文字幕日韩综合av| 成人精品在线观看视频| 国产精品对白久久久久粗| 91精品一区二区三区久久久久久 | 91手机视频在线| 酒色婷婷桃色成人免费av网| 成人av高清在线| 99精品99久久久久久宅男| 国产又粗又猛又爽又黄的| 美女精品网站| 茄子视频成人在线| 精品美女久久久久| 亚洲福利久久| 国自产精品手机在线观看视频| 欧美俄罗斯乱妇| 成人做爰66片免费看网站| 一级片视频免费| 奇米一区二区三区| 国产精品福利片| 中文字幕在线日本| 日韩精品一卡二卡三卡四卡无卡| 91精品国产高清久久久久久久久 | 成年人看片网站| 国产日韩欧美中文在线| 4438x亚洲最大成人网| 日本中文字幕影院| 高清一区二区中文字幕| 欧美人牲a欧美精品| 午夜啪啪小视频| 久久69av| 亚洲国产精品电影| 在线观看av中文字幕| 香蕉视频一区| 亚洲图片欧洲图片av| jizz18女人高潮| 999国产精品| 久久成人亚洲精品| 久久久www成人免费毛片| 精品二区视频| 日本精品久久中文字幕佐佐木| www.日韩一区| 精品一区二区三区视频在线观看 | 国产美女无遮挡永久免费| 激情五月激情综合网| 91视频网页| 四虎在线视频免费观看| 久久综合九色综合久久久精品综合 | 国产精品国产三级在线观看| 欧美电影精品一区二区| 欧美做受喷浆在线观看| 国产传媒欧美日韩成人精品大片| 中文字幕久热精品在线视频| 久久久久久久久毛片| 99国产精品99久久久久久粉嫩| 欧美在线视频网| 91尤物国产福利在线观看| 丁香五精品蜜臀久久久久99网站| 鲁丝一区鲁丝二区鲁丝三区| 日本中文字幕在线2020| 亚洲午夜羞羞片| 超碰av在线免费观看| 免费精品一区| 亚洲欧洲一区二区三区在线观看| 久久国产高清视频| 亚洲精品1234| 国产日韩欧美视频在线| 天天干,夜夜爽| 国产精品沙发午睡系列990531| www国产免费| 日韩成人av电影| 欧美不卡在线视频| 中文字幕免费在线看线人动作大片| 欧美黄污视频| 国产精品免费一区二区三区都可以| 国产麻豆免费视频| 国产日韩v精品一区二区| av无码久久久久久不卡网站| 成人a在线观看高清电影| 欧美变态tickle挠乳网站| 日本一区二区视频在线播放| 日韩视频在线一区二区三区 | silk一区二区三区精品视频| 亚洲午夜未满十八勿入免费观看全集 | 夜夜春成人影院| 欧美激情综合色| 国产精品色综合| 欧美激情一区在线| 久久国产成人精品国产成人亚洲| 欧美高清一级片| 中文字幕av一区二区三区谷原希美| 日本少妇激情舌吻| 国产乱国产乱300精品| 亚洲国产成人不卡| gay欧美网站| 精品亚洲一区二区三区| 精品无码av在线| 国产一区二区三区日韩| 亚洲国产午夜伦理片大全在线观看网站| 国产精品vvv| 日韩欧美www| 91香蕉视频在线播放| 免费av成人在线| 欧美一区激情视频在线观看| 超碰高清在线| 亚洲高清久久久久久| 美女的奶胸大爽爽大片| 精品一区二区三区免费毛片爱 | av中文字幕在线| 日本高清成人免费播放| 国内精品久久99人妻无码| 亚洲美女色禁图| 国产欧美日韩一区| 国产三线在线| 亚洲精品电影网在线观看| 久久久久久久久97| 国产成人av一区| 97碰在线视频| 丁香5月婷婷久久| 高清视频欧美一级| 天天操天天干天天插| 欧美日韩亚洲91| 少妇真人直播免费视频| 久久精品导航| 日本午夜精品一区二区三区| 日本电影欧美片| 中文字幕欧美日韩精品| 亚洲图片视频小说| 亚洲视频一区在线| 久久久久亚洲av片无码v| 欧美精品1区| 国产九区一区在线| 欧美aa免费在线| 亚洲欧洲第一视频| 中文在线免费看视频| 国产精品久久久久影院色老大| 日本肉体xxxx裸体xxx免费| 欧美丰满日韩| 97超级在线观看免费高清完整版电视剧| 国产又色又爽又黄刺激在线视频| 亚洲精品v欧美精品v日韩精品| 天天干天天干天天干天天| 国产亚洲制服色| 免费成年人高清视频| 亚洲视频久久| 欧美激情视频一区二区三区| 福利精品一区| 欧美激情一区二区三区成人 | 精品国产一区二区三区久久| 99久久婷婷国产一区二区三区| 一区二区三区四区不卡在线| 国产伦精品一区三区精东| 首页国产欧美久久| 无码人妻aⅴ一区二区三区日本| 美女视频亚洲色图| 国产精品亚洲网站| 宅男在线观看免费高清网站| 亚洲国产天堂久久综合| 日本妇乱大交xxxxx| 亚洲一区二区三区四区在线| 亚洲av综合一区二区| 精品一区二区在线播放| 丰满爆乳一区二区三区| 色欧美自拍视频| 国产视频一区二区三区四区| 韩国精品主播一区二区在线观看 | 日本黄网免费一区二区精品| 久久久久久久久久久久电影| 日本精品在线视频| 青青草原国产在线| 在线播放亚洲激情| 黄色小视频免费观看| 欧美日韩一区二区电影| 欧美不卡视频在线观看| 自拍偷拍亚洲激情| 天天躁夜夜躁狠狠是什么心态| 国产成人免费高清| 国产原创精品在线| 久久经典综合| 日韩伦理在线免费观看| 午夜精品一区二区三区国产| 蜜桃网站成人| jizz国产精品| 91香蕉电影院| 韩国精品视频在线观看| 91成品人片a无限观看| 性爱视频在线播放| 日韩中文字幕在线| a√资源在线| 亚洲免费高清视频| 天天躁日日躁狠狠躁喷水| 日韩一区二区在线观看| 中文字幕+乱码+中文| 日韩欧美亚洲成人| 国产网址在线观看| 夜夜夜精品看看| 国产盗摄x88av| 亚洲人成7777| 黄色精品视频在线观看| 欧美激情综合在线| 日本少妇xxxxx| 久久亚洲影视婷婷| 日本黄色动态图| 成人中文字幕在线| 少妇伦子伦精品无吗| 色香欲www7777综合网| 美女扒开尿口让男人操亚洲视频网站| 国产裸舞福利在线视频合集| 日韩精品中文字幕在线播放| 高清毛片aaaaaaaaa片| 欧美一级电影网站| 国产熟女精品视频| 欧美一区二区三区性视频| 在线播放国产一区| 欧美三级日韩在线| 亚洲天堂aaa| 欧美另类高清zo欧美| 亚洲一卡二卡在线观看| 欧美福利电影网| 国产农村妇女毛片精品久久| 91精品午夜视频| 精品人妻无码一区二区| 欧美v日韩v国产v| 欧美一级在线免费观看| 亚洲激情在线观看| 欧美挠脚心网站| 亚洲性生活视频在线观看| 国产小视频免费在线观看| 这里只有精品久久| 蜜桃av在线免费观看| 欧美成人精品xxx| 国精产品一区一区三区mba下载| 久久久久久97| 涩涩av在线| 国产精品极品尤物在线观看 | 亚洲人体偷拍| 黄色一级片播放| 久久一区二区三区四区五区| 91极品视频在线观看| 国产又黄又大久久| 91精品又粗又猛又爽| 91免费视频网| 你懂得在线观看| 亚洲午夜在线电影| 丁香社区五月天| 91精品欧美福利在线观看| www.国产精品视频| 亚洲乱码国产乱码精品精| 最新97超碰在线| 久久久女女女女999久久| 日韩国产激情| 91原创国产| 亚洲国产国产| 伊人天天久久大香线蕉av色| 欧美日韩午夜| 国产精品入口免费软件| 国产乱人伦偷精品视频不卡| 无码任你躁久久久久久老妇| 国产欧美精品一区二区色综合 | 婷婷视频在线| 国内精品久久久| 成人在线视频免费| 激情五月综合色婷婷一区二区| 成人影院天天5g天天爽无毒影院| 91精品国产毛片武则天| 免费视频一区| 国产乱淫av麻豆国产免费| 久久蜜桃一区二区| a级黄色片免费看| 欧美色男人天堂| 香蕉av一区二区三区| 久久亚洲欧美日韩精品专区| 免费观看一级欧美片| 91视频婷婷| 99久久婷婷国产综合精品电影√| 秋霞无码一区二区| 国产麻豆精品久久一二三| av电影在线不卡| 午夜国产精品影院在线观看| 国产老女人乱淫免费| 亚洲人成电影网站色www| 岛国毛片av在线| 亚洲va欧美va国产综合剧情| 国产a久久精品一区二区三区 | 三级成人在线| 国内精品视频免费| 欧美精品91| 久久久久久久高清| 欧美国产精品v| 天堂网免费视频| 国产视频欧美视频| 91高清视频在线观看| 99在线观看视频网站| 天天射综合网视频| 精品综合久久久久| 日本一区二区三级电影在线观看| 亚洲 欧美 日韩 综合| 精品88久久久久88久久久| a级在线观看| 3d动漫啪啪精品一区二区免费 | 国产视频在线视频| 91麻豆国产香蕉久久精品| 国产一级大片在线观看| 日韩欧美在线网站| 伊人电影在线观看| 51国产成人精品午夜福中文下载| 91视频精品| gogogo高清免费观看在线视频| 国产精品女同互慰在线看| av手机天堂网| 中国人与牲禽动交精品| 欧美日韩视频免费观看| 日日夜夜精品网站| 免费人成黄页网站在线一区二区| 99久久精品免费视频| 欧美色图在线观看| 最新av网站在线观看| 成人欧美一区二区三区在线 | 孩xxxx性bbbb欧美| 欧美人与动xxxxz0oz| 国产特级黄色大片| 99re成人精品视频| 日日噜噜噜噜人人爽亚洲精品| 国产丝袜一区视频在线观看| 久久精品女人天堂av免费观看 | 久久久久久久久久久久| 在线观看中文字幕不卡| 日本亚洲精品| 亚洲a成v人在线观看| 国产一区久久| 久久久久成人精品无码中文字幕| 欧美日韩在线看| 精品成人一区二区三区免费视频| 国产精品久久久久久久久久99 | 国产欧美一区二区三区沐欲| 亚洲图片欧美在线| 久久999免费视频| 麻豆成人入口| 久久九九国产视频| 日韩美女视频一区二区| 亚洲精品免费在线观看视频| 欧美日韩第一页| 日韩高清在线免费观看| 91香蕉视频污版| 一区二区三区鲁丝不卡| 偷拍自拍在线视频| 国产精品福利在线观看网址| 希岛爱理av一区二区三区| xfplay5566色资源网站| 色综合亚洲欧洲| 成码无人av片在线观看网站| 国产高清在线一区| 日韩精品福利网| 久草视频免费在线| 亚洲人成绝费网站色www| www.久久久久爱免| 日日橹狠狠爱欧美超碰| 亚洲国产精品黑人久久久| 亚洲精品18p| 国产精品久久中文| 国产一区清纯| 精品一区二区在线观看视频| 亚洲第一网中文字幕| 亚洲伦理一区二区| 欧美日韩在线一| 亚洲视频免费在线| 亚洲av成人精品毛片| 成人一区二区电影|