记录一下 tsconfig 的配置及作用。
根模块
json
{
"compilerOptions": {}, // 编译选项
"files": [], // 指定需要包含的文件包含的文件
"extends": "", // 指定继承的另一个配置文件
"include": ["src/**/*", "tests/**/*"], // 值为一个文件地址数组,支持通配符,指定包含的需要编译的文件
"exclude":[], // 同include,指定不需要编译的文件
// 指定子包,需要与composite配合使用。适用于大型项目,拆分子包
"references": [
{ "path": "./packages/shared" },
{ "path": "./packages/frontend" },
{ "path": "./packages/backend" }
],
"typeAcquisition": {}, // 类型获取配置项
"watchOptions": {}, // 配置 --watch 模式下的监听行为
}
编译选项
编译选项分为以下几类
- Modules 模块配置
- Type Checking 类型检查
- Emit 输出相关配置
- JavaScript Support js支持
- Editor Support 编辑器支持
- Interop Constraints 模块互操作配置项
- Backwards Compatibility 向后兼容性
- Language and Environment 语言和环境
- Compiler Diagnostics 编译器诊断信息
- Projects 项目
- Output Formatting 编译输出格式化选项
- Completeness 完整性
json
{
"compilerOptions": {
// === Emit - 输出设置 ===
"declaration": true, // 生成类型声明文件
"declarationDir": "./types", // 声明文件输出目录
"declarationMap": true, // 为声明文件生成 source map
"downlevelIteration": true, // 支持低版本迭代器语法
"emitBOM": false, // 输出文件添加 UTF-8 BOM
"emitDeclarationOnly": false, // 仅输出声明文件不生成 JS
"importHelpers": true, // 使用 tslib 中的辅助函数
"inlineSourceMap": false, // 内联 source map
"inlineSources": true, // source map 中包含源码
"mapRoot": "", // 设置 source map 中的 sources 路径前缀
"newLine": "lf", // 设置输出文件换行符
"noEmit": false, // 不输出任何文件
"noEmitHelpers": false, // 不输出 helper 函数
"noEmitOnError": true, // 有错误时不输出
"outDir": "./dist", // 输出目录
"outFile": undefined, // 打包输出为单一文件
"preserveConstEnums": false, // 保留 const enum(不内联)
"removeComments": true, // 删除注释
"sourceMap": true, // 生成 .map 文件
"sourceRoot": "", // source map 中的源路径前缀
"stripInternal": true, // 移除 @internal 标记内容
// === Type Checking - 类型检查 ===
"allowUnreachableCode": false, // 允许不可达代码
"allowUnusedLabels": false, // 允许未使用的标签
"alwaysStrict": true, // 启用严格模式
"exactOptionalPropertyTypes": true, // 可选属性严格匹配 undefined
"noFallthroughCasesInSwitch": true, // 禁止 switch 穿透
"noImplicitAny": true, // 禁止隐式 any
"noImplicitOverride": true, // 重写方法需显式 override
"noImplicitReturns": true, // 所有路径需有返回值
"noImplicitThis": true, // 禁止隐式 this
"noPropertyAccessFromIndexSignature": true, // 禁止从索引签名访问属性
"noUncheckedIndexedAccess": true, // 索引访问添加 undefined
"noUnusedLocals": true, // 未使用的变量报错
"noUnusedParameters": true, // 未使用的参数报错
"strict": true, // 启用所有严格模式
"strictBindCallApply": true, // bind/call/apply 严格检查
"strictBuiltinIteratorReturn": true, // 内置迭代器返回类型检查
"strictFunctionTypes": true, // 函数类型双向协变检查
"strictNullChecks": true, // 严格 null 检查
"strictPropertyInitialization": true, // 类属性必须初始化
"useUnknownInCatchVariables": true, // catch 默认类型为 unknown
// === Modules - 模块配置 ===
"allowArbitraryExtensions": false, // 允许任意扩展名
"allowImportingTsExtensions": true, // 允许导入 .ts 等扩展
"allowUmdGlobalAccess": false, // 允许访问全局 UMD 模块
"baseUrl": "./", // 模块解析基础路径
"customConditions": [], // 自定义条件导入字段
"module": "esnext", // 模块类型
"moduleResolution": "node", // 模块解析策略
"moduleSuffixes": [".ts", ".tsx", ".d.ts", ".js"], // 模块扩展名
"noResolve": false, // 禁止模块解析
"noUncheckedSideEffectImports": false, // 检查副作用导入
"paths": {}, // 路径映射
"resolveJsonModule": true, // 支持导入 JSON
"resolvePackageJsonExports": true, // 解析 package.json 的 exports
"resolvePackageJsonImports": true, // 解析 package.json 的 imports
"rewriteRelativeImportExtensions": "js", // 重写导入扩展名
"rootDir": "./src", // 根目录
"rootDirs": ["./src", "./shared"], // 虚拟根目录合并
"typeRoots": ["./types"], // 类型声明路径
"types": ["node"], // 包含的类型
// === JavaScript Support - JS 支持 ===
"allowJs": true, // 允许 JS 编译
"checkJs": false, // 检查 JS 类型
"maxNodeModuleJsDepth": 2, // node_modules 查找深度
// === Editor Support - 编辑器支持 ===
"disableSizeLimit": false, // 关闭文件大小限制警告
"plugins": [], // 配置插件
// === Interop Constraints - 模块互操作性 ===
"allowSyntheticDefaultImports": true, // 允许默认导入非默认模块
"erasableSyntaxOnly": false, // 仅删除语法层面可安全移除的内容
"esModuleInterop": true, // 启用 ES 模块互操作
"forceConsistentCasingInFileNames": true, // 文件名大小写一致
"isolatedDeclarations": false, // 独立声明文件生成
"isolatedModules": false, // 每个文件视作模块
"preserveSymlinks": false, // 保留符号链接
"verbatimModuleSyntax": true, // 保留原始导入导出语法
// === Backwards Compatibility - 向后兼容性 ===
"charset": "utf8", // 文件编码
"importsNotUsedAsValues": "remove", // 类型导入使用处理方式
"keyofStringsOnly": false, // keyof 是否只允许字符串
"noImplicitUseStrict": false, // 不添加 'use strict'
"noStrictGenericChecks": false, // 关闭泛型严格检查
"out": "", // 旧版 outFile
"preserveValueImports": true, // 保留值导入
"suppressExcessPropertyErrors": false, // 忽略对象字面量多余属性错误
"suppressImplicitAnyIndexErrors": false, // 允许索引隐式 any
// === Language and Environment - 语言与环境 ===
"emitDecoratorMetadata": false, // 装饰器元数据
"experimentalDecorators": true, // 启用装饰器
"jsx": "react-jsx", // JSX 转换类型
"jsxFactory": "React.createElement", // JSX 工厂函数
"jsxFragmentFactory": "React.Fragment", // JSX Fragment 工厂
"jsxImportSource": "react", // JSX 导入源
"lib": ["ES2021", "DOM"], // 引入标准库
"libReplacement": {}, // 替换标准库(实验性)
"moduleDetection": "force", // 模块检测方式
"noLib": false, // 不包含默认库
"reactNamespace": "React", // React 命名空间
"target": "ES2021", // 编译目标
"useDefineForClassFields": true, // 使用 define 定义类字段
// === Compiler Diagnostics - 编译诊断 ===
"diagnostics": false, // 输出诊断信息
"explainFiles": false, // 显示文件包含关系
"extendedDiagnostics": false, // 扩展诊断
"generateCpuProfile": false, // 生成 CPU profile
"generateTrace": "", // 生成 trace 文件
"listEmittedFiles": false, // 列出生成文件
"listFiles": false, // 列出所有参与编译文件
"noCheck": false, // 禁用所有类型检查
"traceResolution": false, // 显示模块解析过程
// === Projects - 多项目配置 ===
"composite": false, // 启用项目引用
"disableReferencedProjectLoad": false, // 不自动加载引用项目
"disableSolutionSearching": false, // 禁用自动查找解决方案
"disableSourceOfProjectReferenceRedirect": false, // 禁用引用项目重定向
"incremental": true, // 启用增量编译
"tsBuildInfoFile": "./.tsbuildinfo", // 增量信息存储路径
// === Output Formatting - 输出格式化 ===
"noErrorTruncation": false, // 不截断错误信息
"preserveWatchOutput": false, // 保留 watch 输出
"pretty": true, // 美化终端输出
// === Completeness - 完整性 ===
"skipDefaultLibCheck": true, // 跳过默认库检查
"skipLibCheck": true // 跳过所有声明文件检查
},
// 命令行参数(适用于增量编译)
"assumeChangesOnlyAffectDirectDependencies": true, // 增量编译时只更新直接依赖
// 监听选项
"watchOptions": {
"watchFile": "useFsEvents", // 文件监听策略
"watchDirectory": "useFsEvents", // 目录监听策略
"fallbackPolling": "dynamicPriority", // 设置监听失败时的回退轮询策略
"synchronousWatchDirectory": false, // 是否使用同步监听(更兼容但更慢)
"excludeDirectories": ["node_modules"], // 排除监听的目录
"excludeFiles": [] // 排除监听的文件
},
// 类型获取(主要用于 JS 项目自动引入类型)
"typeAcquisition": {
"enable": true, // 启用自动类型获取(从 @types 安装)
"include": ["lodash"], // 强制包含的类型定义
"exclude": ["jquery"], // 排除的类型定义
"disableFilenameBasedTypeAcquisition": false // 是否禁用基于文件名的自动类型猜测
},
// 项目引用(Project References)
"references": [
{ "path": "./packages/core" }, // 引用核心模块
{ "path": "./packages/utils" } // 引用工具模块
]
}
vue3 中的tsconfig
json
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "temp",
"sourceMap": false,
"target": "es2016",
"newLine": "LF",
"useDefineForClassFields": false,
"module": "esnext",
"moduleResolution": "bundler",
"allowJs": false,
"strict": true,
"noUnusedLocals": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"isolatedModules": true,
"skipLibCheck": true,
"esModuleInterop": true,
"removeComments": false,
"jsx": "preserve",
"lib": ["es2016", "dom"],
"types": ["vitest/globals", "puppeteer", "node"],
"rootDir": ".",
"paths": {
"@vue/compat": ["packages/vue-compat/src"],
"@vue/*": ["packages/*/src"],
"vue": ["packages/vue/src"]
},
"isolatedDeclarations": true,
"composite": true
},
"include": [
"packages/global.d.ts",
"packages/*/src",
"packages/*/__tests__",
"packages/vue/jsx-runtime",
"packages/runtime-dom/types/jsx.d.ts",
"scripts/*",
"rollup.*.js"
],
"exclude": ["packages-private/sfc-playground/src/vue-dev-proxy*"]
}
在这个配置中,最顶层只有三个元素。分别是 compilerOptions、include、exclude。
其中 include 和exclude比较简单,定义了哪些文件需要编译,哪些文件不需要编译。
compilerOptions
为了快速理解这个配置的作用,可以先对这些配置进行一个分类并加上注释。
json
{
"compilerOptions": {
// Modules - 模块配置
"baseUrl": ".", // 置项目的"根路径",配合 paths 使用
"module": "esnext", // 设置 编译输出时 使用哪种模块系统
"moduleResolution": "bundler", // 设置 编译时 怎么找模块路径
"resolveJsonModule": true, // 支持导入 JSON
"types": ["vitest/globals", "puppeteer", "node"], // 包含的类型
"rootDir": ".", // 虚拟根目录合并
"paths": { // 配置路径别名(让 @vue/compat 能找到实际路径)
"@vue/compat": ["packages/vue-compat/src"],
"@vue/*": ["packages/*/src"],
"vue": ["packages/vue/src"]
},
// Emit - 输出配置
"outDir": "temp", // 输出目录
"sourceMap": false, // 生成 .map 文件
"newLine": "LF", // 设置输出文件换行符
"removeComments": false, // 删除注释
// Language and Environment - 语言与环境
"target": "es2016", // 编译目标
"useDefineForClassFields": false, // 使用 define 定义类字段
"experimentalDecorators": true, // 启用装饰器
"jsx": "preserve", // JSX 转换类型
"lib": ["es2016", "dom"], // 引入标准库
// JavaScript Support - JS 支持
"allowJs": false, // 允许 JS 编译
// Type Checking - 类型检查
"strict": true, // 启用严格模式
"noUnusedLocals": true, // 未使用的变量报错
// Interop Constraints - 模块互操作性配置
"isolatedModules": true, // 每个文件视作模块
"esModuleInterop": true, // 启用 ES 模块互操作,允许默认导入commonjs 模块
"isolatedDeclarations": true, // 独立声明文件生成
// Completeness - 完整性
"skipLibCheck": true, // 跳过所有声明文件检查
// Projects - 项目配置
"composite": true // 标识独立项目,可以被引入
}
}
模块互操作
模块互操作是指 esm 和 cjs 两种模块系统互相操作,这个配置主要解决的也是这个问题,这样在代码中就可以使用 import 语法来引入 cjs 模块。
模块配置
模块配置主要有三个作用。
- 模块代码的输出形式(import 或 require)
- 如何寻找和解析模块
- 控制模块路径、后缀、别名、扩展等
以上通过注释和解释可以大概了解这个项目的打包编译逻辑。