tsconfig.json配置解读

131 阅读9分钟

什么是 tsconfig.json

当你开始使用 TypeScript 开发项目时,tsconfig.json 文件是一个至关重要的配置文件。它定义了 TypeScript 编译器的行为以及项目的编译选项。通过这个文件,开发者可以指定哪些文件需要被编译、编译输出的目录、编译选项等。

tsconfig.json 的基本结构

一个典型的 tsconfig.json 文件通常包含以下几个部分:

  • compilerOptions:用于指定 TypeScript 编译器的选项。
  • files:明确列出要编译的文件。
  • exclude:指定不需要编译的文件或目录。
  • include:指定要编译的文件或目录。

filesexcludeinclude

优先级: files > exclude > include

glob通配符

  • * 匹配0或多个字符(不包括目录分隔符)
  • ? 匹配一个任意字符(不包括目录分隔符)
  • **/ 递归匹配任意子目录

files 编译的文件列表

需要明确列出要编译的文件,可以是相对或绝对文件路径的列表。 仅可以文件,不可为文件夹。 不可使用通配符。

  • filesinclude如果都没有指定,编译器默认包含当前目录和子目录下所有的TypeScript文件(.ts.d.ts 和 .tsx),排除在"exclude"里指定的文件。(如果allowJs设置为ture, 也会包含所有的.js.jsx)。
  • 使用 "outDir"指定的目录下的文件永远会被编译器排除,除非你明确地使用"files"将其包含进来(这时就算用exclude指定也没用)。
{
  // 通常情况下不配置files文件
  "files": [ 
      "src/index.ts", 
      "src/utils.ts", 
      "src/components/App.tsx" 
  ]
}

include 编译的路径列表

可以是相对或绝对文件路径的列表。 与files的区别在于,这里的路径可以是文件夹,也可以是文件。 支持使用通配符。

{
  "include": [
    "src/**/*"
    "./**/*.d.ts",
    "./**/*.ts",
    "./**/*.tsx"
  ],
}

exclude 要排除的、不编译的文件

可以是相对或绝对文件路径的列表。 可以是文件夹,也可以是文件。 支持使用通配符。

  • "exclude"默认情况下会排除node_modulesbower_componentsjspm_packages<outDir>目录。
  • 使用"include"引入的文件可以使用"exclude"属性过滤。
{
  "exclude": [
    "node_modules", // 排除 node_modules 目录
    "dist", // 构建后的文件
    "build", // 构建后的文件
    "**/*.spec.ts"   // 排除所有测试文件
  ]
}

compilerOptions 编译选项

下文为常用配置,所有配置均参考TSConfig

{
  "compilerOptions": {
    /* 类型检查 */
    "strict": true, // 用于指定是否启动所有类型检查,打开此功能相当于启用所有严格模式系列选项,默认为false
    "noImplicitAny": true, // 如果我们没有为一些值设置明确的类型,编译器会默认认为这个值为any,如果noImplicitAny的值为true的话。则没有明确的类型会报错。默认值为false
    "strictNullChecks": true, // strictNullChecks为true时,null和undefined值不能赋给非这两种类型的值,别的类型也不能赋给他们,除了any类型。还有个例外就是undefined可以赋值给void类型
    "strictFunctionTypes": true, // 是否严格检查函数参数
    "strictBindCallApply": true, // 设为true后会对bind、call和apply绑定的方法的参数的检测是严格检测的
    "strictPropertyInitialization": true, // 设为true后会检查类的非undefined属性是否已经在构造函数里初始化,如果要开启这项,需要同时开启strictNullChecks,默认为false
    "noImplicitThis": true, // 当this表达式的值为any类型的时候,生成一个错误
    "alwaysStrict": true, // alwaysStrict的值为true或false,指定始终以严格模式检查每个模块,并且在编译之后的js文件中加入"use strict"字符串,用来告诉浏览器该js为严格模式
    "noUnusedLocals": true, // 检查变量是否没有使用,默认值为false
    "noUnusedParameters": true, // 检查函数体中参数是否没有使用,默认为false
    "noImplicitReturns": true, // 用于检查函数是否有返回值,设为true后,如果函数没有返回值则会提示,默认为false
    "noFallthroughCasesInSwitch": true, // 用于检查switch中是否有case没有使用break跳出switch,默认为false 
    
     /* 模块 */
     "module": "nodenext", // 用来指定要使用的模块标准: 'none', 'commonjs', 'amd', 'system', 'umd', 'node16', 'nodenext', es2015', or 'ESNext'
     "moduleResolution": "nodenext", // 用于选择模块解析策略,有'node'、'node16'、'nodenext','classic'
     "resolveJsonModule": true, // 解析JSON模块
     "rootDir": "./", // 用来指定编译文件的根目录,编译器会在根目录查找入口文件,如果编译器发现以rootDir的值作为根目录查找入口文件并不会把所有文件加载进去的话会报错,但是不会停止编译
     "rootDirs": [], // rootDirs可以指定一个路径列表,在构建时编译器会将这个路径列表中的路径的内容都放到一个文件夹中
     "typeRoots": [], // typeRoots用来指定声明文件或文件夹的路径列表,默认情况下,所有可见的“`@types`”包都包含在你的编译中。如果指定了此项,则只有在这里列出的声明文件才会被加载
     "types": [], // types用来指定需要包含的模块,只有在这里列出的模块的声明文件才会被加载进来
     "baseUrl": "./", // baseUrl用于设置解析非相对模块名称的基本目录,相对模块不会受baseUrl的影响
     "paths": {}, // 用于设置模块名称到基于baseUrl的路径映射
    
     /* 触发 */
     "outDir": "./dist",// 指定输出文件夹
     "outFile": "./dist/main.js",// 用于指定将输出文件合并为一个文件,它的值为一个文件路径名。但是要注意,只有设置module的值为amd和system模块时才支持这个配置
     "declaration": true, // 指定是否在编译的时候生成相应的".d.ts"声明文件。如果设为true,编译每个ts文件之后会生成一个js文件和一个声明文件。但是declaration和allowJs不能同时设为true
     "removeComments": true,// 指定是否将编译后的文件中的注释删掉,设为true的话即删掉注释,默认为false
     "importHelpers": true, // importHelpers的值为true或false,指定是否引入tslib里的辅助工具函数,默认为false
     "downlevelIteration": true, // 当target为'ES5' or 'ES3'时,为迭代器Symbol.iterator提供完全支持
     
     /* 触发 Source Map Options */
     "sourceRoot": "", // 指定调试器应定位 TypeScript 文件的位置,而不是相对源位置。这个值会被写进.map文件里
     "mapRoot": "", // 指定调试器应该定位映射文件而不是生成的位置的位置,指定map文件的根路径,该选项会影响.map文件中的sources属性
     "sourceMap": true, // 用来指定编译时是否生成.map文件,与inlineSourceMap互斥。
     "inlineSourceMap": true, // 指定是否将map文件的内容和js文件编译在同一个js文件中,如果设为true,则map的内容会以//# sourceMappingURL=然后拼接base64字符串的形式插入在js文件底部
     "inlineSources": true, // 用于指定是否进一步将.ts文件的内容也包含到输入文件中
     "newLine": "LF", // 指定在触发文件时要使用的行尾序列:‘CRLF’(dos)或 ‘LF’(unix)。
    
     /* JS支持 */
     "allowJs": true, // 是否允许编译js文件,默认false
     "checkJs": false, // 是否检查和报告js文件中的错误,默认false
    
     /* 语言环境 */
     "target": "ES2018", // target用于指定编译之后的版本目标。 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'。
     "lib": ["es6", "dom"], // 用于指定编译过程中需要引入的库文件的列表
     "jsx": "react-jsx", // 控制 TypeScript 编译器如何处理 JSX 语法。 详解看下文解释。
    
     /* 互操作约束 */
     "allowSyntheticDefaultImports": true, // 允许合成默认导入
     "esModuleInterop": true, // 通过为导入内容创建命名空间,实现CommonJS和ES模块之间的互操作性
     "isolatedDeclarations": true, // 要求在导出时进行足够的注释,以便其他工具可以轻松生成声明文件。
     "forceConsistentCasingInFileNames": true, // 强制文件名大小写一致

     /* 完整性 */
     "skipLibCheck": true, // 跳过声明文件的类型检查。这可以节省编译时间
  }
}

部分属性解释

  • jsx: 控制 TypeScript 编译器如何处理 JSX 语法。
    • preserve(默认): 将 JSX 保留在生成的文件中,不对其进行任何转换。适用于将 TypeScript 代码传递给其他工具(例如 Babel), 这些工具将处理 JSX。
    • react: 将 JSX 转换为React.createElement调用。适用于使用 React 的项目。
    • react-jsx(从 TypeScript 4.1 开始支持): 将 JSX 转换为jsx函数调用,而不是React.createElement。适用于 React 17 及以上版本,支持新的 JSX 转换机制,不再需要导入React。
    • react-jsxdev (从 TypeScript 4.1 开始支持): 类似于 react-jsx,但会为开发环境生成额外的调试信息。适用于开发阶段,帮助调试React组件。

typeRoots和types

默认情况下,所有的"@types"包会在编译过程中被包含进来。例:node_modules/@types./node_modules/@types/../node_modules/@types/../../node_modules/@types/等等。

  • typeRoots :如果指定了typeRoots,只有typeRoots下面的包才会被包含进来。
{
   "compilerOptions": {
       "typeRoots" : ["./typings"]
       // 这个配置文件会包含所有`./typings`下面的包,而不包含`./node_modules/@types`里面的包。  
   }
}
  • types:如果指定了types,只有被列出来的包才会被包含进来。
{
   "compilerOptions": {
        "types" : ["node", "lodash"]
        // 这个`tsconfig.json`文件将仅会包含`./node_modules/@types/node`、`./node_modules/@types/lodash`。
        // `node_modules/@types/*`里面的其它包不会被引入进来。
   }
}

指定"types": []来禁用自动引入@types包。

注意,自动引入只在你使用了全局的声明(相反于模块)时是有用的。 如果你使用 import "foo"语句,TypeScript仍然会查找node_modulesnode_modules/@types文件夹来获取foo包。

module 和 moduleResolution

  • module: 指定要使用的模块标准,它决定了如何将模块导入和导出到 JavaScript 中。
    • commonjs: 生成 CommonJS 模块,这在 Node.js 中非常常见。
    • amd: 生成 AMD 模块,适用于 RequireJS 等库。
    • umd: 生成 UMD 模块,这种模块可以在 AMD、CommonJS 和全局环境中运行。
    • esnext: 生成 ES 模块,适用于支持 ES6 模块的环境。
    • node16nodenext:支持 CommonJS 和 ECMAScript 模块。
      • .mts/.mjs/.d.mts 文件始终是 ES 模块。
      • .cts/.cjs/.d.cts 文件始终是 CommonJS 模块。
      • 如果最近的祖级 package.json 文件包含 "type": "module",则 .ts/.tsx/.js/.jsx/.d.ts 文件是 ES 模块,否则是 CommonJS 模块。
  • moduleResolution: 指定模块解析策略,它决定了 TypeScript 在查找导入的模块时所采用的策略。
    • nodenext: 专为支持 Node.js 的 ESM(ECMAScript Modules)和 CommonJS 模块而设计,适合现代 Node.js 应用。
    • esnext: 与 nodenext 类似,主要针对 ES 模块。

extends

extends可以通过指定一个其他的tsconfig.json文件路径,来继承这个配置文件里的配置,继承来的文件的配置会覆盖当前文件定义的配置。

总结

tsconfig.json 是每个 TypeScript 项目中不可或缺的配置文件。它为 TypeScript 编译器提供了必要的信息,以便正确编译项目的代码。通过合理配置 tsconfig.json,开发者可以提高项目的可维护性、可读性以及团队协作的效率。因此,深入理解和掌握 tsconfig.json 的配置选项是使用 TypeScript 开发的关键。

参考文献

TSConfig