Fastify 模块化项目实战 - 你真的懂 tsconfig.json 吗?
tsconfig.json:TypeScript 项目的核心配置文件
在使用 TypeScript 开发 JavaScript 项目时,几乎所有项目都会有一个非常重要的文件:
tsconfig.json
TypeScript 官方文档也说明:
这个文件用于定义编译目标、模块系统、类型检查规则、输入文件范围等行为。 (typescriptlang.org)
它决定了 TypeScript 编译器如何理解、检查和编译你的代码。如果说 TypeScript 编译器 tsc 是引擎,那么 tsconfig.json 就是控制引擎运行方式的配置中心。
一个最简单的例子:
{
"compilerOptions": {
"target": "ES2023"
}
}
当 TypeScript 编译器运行时:
tsc
它会自动读取当前目录的 tsconfig.json 并按照配置执行编译。
为什么需要 tsconfig.json ?
如果没有 tsconfig.json,TypeScript 仍然可以编译:
tsc index.ts
但在真实项目中会出现很多问题:
统一编译规则
不同开发者机器必须使用相同规则,例如:
target: ES2023
strict: true
module: ESNext
否则编译结果可能不同。
控制代码兼容性.
例如:
target: ES2017
意味着 TypeScript 不会输出 ES2023 的语法。
这样可以保证代码在旧环境中运行。 (typescriptdocs.com)
控制 TypeScript 类型检查
例如:
strict: true
开启严格类型检查。
控制项目结构
例如src → 编译 → dist:
{
"rootDir": "src",
"outDir": "dist"
}
由此可见, tsconfig.json 解决了编译规则统一、类型检查策略、项目结构管理三个核心问题。
tsconfig.json 的基本结构
一个典型的 tsconfig.json:
{
"compilerOptions": {},
"include": [],
"exclude": [],
"extends": ""
}
最核心的部分是 compilerOptions
compilerOptions 是什么?
compilerOptions 是 TypeScript 编译器选项集合,决定了:
- 编译输出
- 模块系统
- 语言版本
- 类型检查规则
- 项目结构
例如:
{
"compilerOptions": {
"target": "ES2023",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true
}
}
target
target: "ES2023"
控制编译后的 JavaScript 版本。例如 TypeScript → JavaScript:
如果:
target: ES5
箭头函数会被转换:
const fn = () => {}
变成:
var fn = function() {}
官方建议:
target 应设置为你支持的最低 JavaScript 版本。 (typescriptdocs.com).
常见值:
ES2017
ES2020
ES2022
ESNext
module
module: "ESNext"
控制模块系统。例如 import/export 最终编译为:
- ES Modules
- CommonJS
- AMD
常见值:
- CommonJS
- ESNext
- NodeNext
- ES2020
现代前端和 Node 项目通常使用 ESNext
moduleResolution
moduleResolution: "bundler"
控制模块查找规则。例如:
import foo from "./foo"
控制 TypeScript 如何找到 foo。官方定义:
- bundler
- node16
- nodenext
- classic
bundler 表示:
让 bundler(Vite / Webpack / esbuild)负责解析模块路径。 (typescriptlang.org)
特点:
- 不强制写
.js扩展名 - 支持 package.json exports
- 更适合前端项目
strict
strict: true
开启严格模式。这是 TypeScript 最重要的配置之一。它实际上包含多个规则:
- noImplicitAny
- strictNullChecks
- strictFunctionTypes
- strictBindCallApply
作用:
- 避免隐式 any
- 避免 null 错误
- 提高类型安全
官方建议:
始终开启 strict。 (TypeScript TV)
esModuleInterop
esModuleInterop: true
用于解决 CommonJS 和 ES Module 互操作问题。例如:
import express from "express"
而 express 实际是:
module.exports = express
没有这个配置就必须写:
import * as express from "express"
开启后 default import 也可以使用。
其他重要 compilerOptions
以下也是常见配置:
rootDir
rootDir: "src"
源码目录。
outDir
outDir: "dist"
编译输出目录。
sourceMap
sourceMap: true
生成 source map,方便调试。
skipLibCheck
skipLibCheck: true
跳过 node_modules 类型检查。大型项目非常常见。
resolveJsonModule
允许:
import config from "./config.json"
forceConsistentCasingInFileNames
避免:
- import User
- import user
在不同系统出现问题。
noEmit
noEmit: true
让 TypeScript 只做类型检查。实际编译由:
- Vite
- Webpack
- esbuild
完成。
paths
大型项目常使用:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
这样可以写:
import userService from "@/services/user"
而不是:
import userService from "../../../services/user"
include / exclude 是什么 ?
TypeScript 需要知道哪些文件需要编译
include
{
"include": ["src/**/*"]
}
表示 src 目录下所有 ts 文件
exclude
{
"exclude": ["node_modules", "dist"]
}
排除目录。
extends 是什么?
extends 用于继承配置文件。例如:
- tsconfig.base.json
- tsconfig.json
{
"extends": "./tsconfig.base.json"
}
这样可以:
- monorepo 共享配置
- library / app 复用配置
很多项目都会这样:
- tsconfig.base.json
- tsconfig.build.json
- tsconfig.test.json
常见的 tsconfig 示例
{
"compilerOptions": {
"target": "ES2023",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"rootDir": "src",
"outDir": "dist",
"skipLibCheck": true,
"sourceMap": true,
"resolveJsonModule": true
},
"include": [
"@types",
"src/**/*.ts"
]
}
那么, 最后的最后, 在哪里查看全部 tsconfig 选项呢? TypeScript 所有配置都在官方文档:
👉 https://www.typescriptlang.org/tsconfig
一个好的 tsconfig.json 能让:
- 项目类型更安全
- 编译行为更一致
- 工程结构更清晰
以上。
- ← Previous
Fastify 模块化项目实战(三)