tsconfig.json
在 TypeScript 1.5 版本之前缺少一种内置的方法能够管理 TypeScript 工程的配置。在 TypeScript 1.5 版本中,提供了使用 tsconfig.json
配置文件来管理 TypeScript 工程的功能,从而弥补了这个不足。
tsconfig.json
配置文件能够管理如下种类的工程配置:
-
编译文件列表。
-
编译选项。
-
tsconfig.json
配置文件间的继承关系(TypeScript 2.1)。 -
工程间的引用关系(TypeScript 3.0)。
本节中将介绍如何为 TypeScript 工程添加 tsconfig.json
配置文件,并使用该配置文件来管理工程中的编译文件列表和声明文件列表。在本节的最后将介绍 tsconfig.json
配置文件的继承,它允许我们重用配置文件,同时也遵循了 DRY(Don’t repeat yourself)原则。
使用配置文件
tsconfig.json
配置文件是一个 JSON
格式的文件。若一个目录中存在 tsconfig.json
文件,那么该目录将被编译器视作 TypeScript 工程的根目录。
假设当前工程目录结构如下:
C:\app
|-- src
| `-- index.ts
`-- tsconfig.json
此例中,C:\app
目录下包含了一个 tsconfig.json
文件,因此 C:\app
成了一个 TypeScript 工程,并且 C:\app
目录将被视为工程的根目录。
tsconfig.json
文件的内容如下:
{
"compilerOptions": {
"target": "ES5"
}
}
在编写好 tsconfig.json
配置文件之后,有以下两种方式来使用它:
-
运行
tsc
命令时,让编译器自动搜索tsconfig.json
配置文件。 -
运行
tsc
命令时,使用--project
或-p
编译选项指定使用的tsconfig.json
配置文件。
需要注意的是,如果运行 tsc
命令时指定了输入文件,那么编译器将忽略 tsconfig.json
配置文件,既不会自动搜索配置文件,也不会使用指定的配置文件。示例如下:
tsc index.ts -p tsconfig.json
此例中,在运行 tsc
命令时指定了输入文件 index.ts
,因此编译器将不使用指定的 tsconfig.json
配置文件。
自动搜索配置文件
在运行 tsc
命令时,若没有使用 --project
或 -p
编译选项,那么编译器将在 tsc
命令的运行目录下查找是否存在文件名为 tsconfig.json
的配置文件。若存在 tsconfig.json
配置文件,则使用该配置文件来编译工程;若不存在,则继续在父级目录下查找 tsconfig.json
配置文件,直到搜索到系统根目录为止;如果最终也未能找到一个可用的 tsconfig.json
配置文件,那么就会停止编译工程。
假设当前工程目录结构如下:
C:\app
|-- src
| `-- index.ts
`-- tsconfig.json
当在 C:\app\src
目录下运行 tsc
命令时,编译器搜索 tsconfig.json
配置文件的流程如下:
-
搜索
C:\app\src\tsconfig.json
。 -
搜索
C:\app\tsconfig.json
。 -
搜索
C:\tsconfig.json
。 -
退出
tsc
编译命令,不进行编译。
一旦编译器找到了匹配的 tsconfig.json
配置文件,就会终止查找过程并使用找到的配置文件。此例中,在第 2 步能够找到匹配的 tsconfig.json
配置文件,于是使用该配置文件来编译工程,并终止后续的查找。
指定配置文件
在运行 tsc
命令时,可以使用 --project
编译选项(短名字为 -p
)来指定使用的配置文件。
--project
编译选项的参数是一个路径,它的值可以为:
-
指向某个具体的配置文件。在这种情况下,配置文件的文件名不限,例如可以使用名为
app.config.json
的配置文件。 -
指向一个包含了
tsconfig.json
配置文件的目录。在这种情况下,该目录中必须包含一个名为tsconfig.json
的配置文件。
假设当前工程目录结构如下:
C:\app
|-- src
| `-- index.ts
|-- tsconfig.json
`-- tsconfig.release.json
在 C:\app
目录下运行 tsc
命令并使用 -p
编译选项来指定使用 tsconfig.release.json
配置文件编译该工程。示例如下:
tsc -p tsconfig.release.json
在 C:\app
目录下运行 tsc
命令并使用 -p
编译选项来指定一个包含了 tsconfig.json
配置文件的目录。示例如下:
tsc -p .
此例中,-p
编译选项的参数值为一个点符号 .
,它表示当前目录,也就是运行 tsc
命令时所在的目录。因此,编译器会查找并使用 C:\app\tsconfig.json
配置文件。
编译选项列表
在 tsconfig.json
配置文件中使用顶层的 compilerOptions
属性能够设置编译选项。对于同一个编译选项而言,不论是在命令行上指定还是在 tsconfig.json
配置文件中指定,它们都具有相同的效果并且使用相同的名称。示例如下:
{
"compilerOptions": {
"strict": true,
"target": "ES5"
}
}
注意,不是所有的编译选项都能够在 tsconfig.json
配置文件中指定。例如,前文介绍的 --help
和 --version
编译选项不支持在 tsconfig.json
配置文件中使用。
TypeScript 提供了一个 --init
编译选项,在命令行上运行 tsc
命令并使用 --init
编译选项会初始化一个 tsconfig.json
配置文件。在生成的 tsconfig.json
配置文件中会自动添加一些常用的编译选项并将它们分类。
假设当前工程目录结构如下:
C:\app
`-- index.ts
在 C:\app
目录下运行 tsc
命令并使用 --init
编译选项。示例如下:
tsc --init
tsc
命令的运行结果是在 C:\app
目录下新生成了一个 tsconfig.json
配置文件。该文件的内容如下:
{
"compilerOptions": {
/* 基础选项 */
"incremental": true,
"target": "es5",
"module": "commonjs",
"lib": [],
"allowJs": true,
"checkJs": true,
"jsx": "preserve",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outFile": "./",
"outDir": "./",
"rootDir": "./",
"composite": true,
"tsBuildInfoFile": "./",
"removeComments": true,
"noEmit": true,
"importHelpers": true,
"downlevelIteration": true,
"isolatedModules": true,
/* 严格类型检查选项 */
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
/* 额外检查选项 */
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
/* 模块解析选项 */
"moduleResolution": "node",
"baseUrl": "./",
"paths": {},
"rootDirs": [],
"typeRoots": [],
"types": [],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"preserveSymlinks": true,
"allowUmdGlobalAccess": true,
/* SourceMap 选项 */
"sourceRoot": "",
"mapRoot": "",
"inlineSourceMap": true,
"inlineSources": true,
/* 实验性选项 */
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
/* 高级选项 */
"forceConsistentCasingInFileNames": true
}
}
编译文件列表
tsconfig.json
配置文件的另一个主要用途是配置待编译的文件列表。
--listFiles 编译选项
TypeScript 提供了一个 --listFiles
编译选项,如果启用了该编译选项,那么在编译工程时,编译器将打印出参与本次编译的文件列表。该编译选项既可以在命令行上使用,也可以在 tsconfig.json
配置文件中使用。
假设当前工程目录结构如下:
C:\app
`-- src
|---a.ts
`-- b.ts
在命令行上使用 --listFiles
编译选项,示例如下:
tsc --listFiles
在 tsconfig.json
配置文件中使用 --listFiles
编译选项,示例如下:
{
"compilerOptions": {
"listFiles": true,
"strict": true,
"target": "ES5"
}
}
在使用上例中的 tsconfig.json
配置文件编译工程时,编译器将输出编译文件列表。示例如下:
...\typescript\lib\lib.d.ts
...\typescript\lib\lib.es5.d.ts
...\typescript\lib\lib.dom.d.ts
...\typescript\lib\lib.webworker.importscripts.d.ts
...\typescript\lib\lib.scripthost.d.ts
C:\app\src\a.ts
C:\app\src\b.ts
通过以上运行结果能够看到,编译文件列表除了包含工程内的源文件外还包含了 TypeScript 内置的一些声明文件。
默认编译文件列表
如果工程中含有一个 tsconfig.json
配置文件,那么在默认情况下 tsconfig.json
配置文件所在目录及其子目录下的所有 .ts
、.d.ts
、.tsx
文件都会被添加到编译文件列表。
假设当前工程目录结构如下:
C:\app
|-- a.ts
|-- src
| |-- b.ts
| `-- c.ts
`-- tsconfig.json
tsconfig.json
配置文件内容如下:
{
"compilerOptions": {
"listFiles": true
}
}
在 C:\app
目录下运行 tsc
编译命令,示例如下:
tsc
tsc
命令的运行结果如下:
<此处省略了内置的声明文件列表>
C:\app\a.ts
C:\app\src\b.ts
C:\app\src\c.ts
通过以上运行结果能够看到,C:\app
目录与其子目录 C:\app\src
下的所有 TypeScript 源文件都参与了本次编译。
files 属性
在 tsconfig.json
配置文件中,使用顶层的 files
属性能够定义编译文件列表。files
属性的值是由待编译文件路径所构成的数组。
假设当前工程目录结构如下:
C:\app
|-- a.ts
|-- src
| |-- b.ts
| `-- c.ts
`-- tsconfig.json
tsconfig.json
配置文件内容如下:
{
"compilerOptions": {
"listFiles": true
},
"files": ["src/b.ts", "src/c.ts"]
}
在 C:\app
目录下运行 tsc
命令,示例如下:
tsc
tsc
命令的运行结果如下:
<此处省略了内置的声明文件列表>
C:\app\src\b.ts
C:\app\src\c.ts
通过以上运行结果能够看到,只有 files
属性中指定的 C:\app\src\b.ts
和 C:\app\src\c.ts
文件参与了本次编译,而 C:\app\a.ts
文件则没有参与编译。
在使用 files
属性设置编译文件列表时必须逐一地列出每一个文件,该属性不支持进行模糊的文件匹配。因此,files
属性适用于待编译文件数量较少的情况。当待编译文件数量较多时,使用 include
和 exclude
属性是更好的选择。
include 属性
在 tsconfig.json
配置文件中,使用顶层的 include
属性能够定义编译文件列表。include
属性的功能包含了 files
属性的功能,它既支持逐一地列出每一个待编译的文件,也支持使用通配符来模糊匹配待编译的文件。
include
属性支持使用三种通配符来匹配文件,具体请参考8.1.2节。
假设当前工程目录结构如下:
C:\app
|-- bar
| `-- c.ts
|-- foo
| |-- a.spec.ts
| |-- a.ts
| |-- b.spec.ts
| `-- b.ts
`-- tsconfig.json
如果 tsconfig.json
配置文件的内容如下:
{
"include": ["foo/*.spec.ts"]
}
那么只有 C:\app\foo\a.spec.ts
和 C:\app\foo\b.spec.ts
文件会被添加到编译文件列表。
如果 tsconfig.json
配置文件的内容如下:
{
"include": ["foo/?.ts"]
}
那么只有 C:\app\foo\a.ts
和 C:\app\foo\b.ts
文件会被添加到编译文件列表。
如果 tsconfig.json
配置文件的内容如下:
{
"include": ["bar/**/*.ts"]
}
那么只有 C:\app\bar\c.ts
文件会被添加到编译文件列表。
exclude属性
在 tsconfig.json
配置文件中,exclude
属性需要与 include
属性一起使用,它的作用是从 include
属性匹配到的文件列表中去除指定的文件。exclude
属性也支持和 include
属性相同的通配符。
假设当前工程目录结构如下:
C:\app
|-- bar
| `-- c.ts
|-- foo
| |-- a.spec.ts
| |-- a.ts
| |-- b.spec.ts
| `-- b.ts
`-- tsconfig.json
tsconfig.json
配置文件的内容如下:
{
"compilerOptions": {
"listFiles": true
},
"include": ["**/*"],
"exclude": ["**/*.spec.ts"]
}
在 C:\app
目录下运行 tsc
命令,示例如下:
tsc
tsc
命令的运行结果如下:
<此处省略了内置的声明文件列表>
C:\app\bar\c.ts
C:\app\foo\a.ts
C:\app\foo\b.ts
此例中,include
属性将 C:\app
目录下所有的 .ts
文件添加到编译文件列表,然后 exclude
属性则将所有的 .spec.ts
文件从编译文件列表中移除。
声明文件列表
在 TypeScript 工程中 node_modules/@types
目录是一个特殊的目录,TypeScript 将其视为第三方声明文件的根目录,因为在安装 DefinitelyTyped
提供的声明文件时,它会被安装到 node_modules/@types
目录下。在默认情况下,编译器会将安装在 node_modules/@types
目录下的所有声明文件添加到编译文件列表。该默认行为可以使用 --typeRoots
和 --types
编译选项设置。
--typeRoots 编译选项
--typeRoots
编译选项用来设置声明文件的根目录。当配置了 --typeRoots
编译选项时,只有该选项指定的目录下的声明文件会被添加到编译文件列表,而 node_modules/@types
目录下的声明文件将不再被默认添加到编译文件列表。
假设当前工程目录结构如下:
C:\app
|-- node_modules
| `-- @types
| `-- jquery
| | |-- ...
| | |-- index.d.ts
| | `-- package.json
| `-- ...
|-- typings
| `-- utils
| `-- index.d.ts
|-- index.ts
|-- package.json
|-- package-lock.json
`-- tsconfig.json
tsconfig.json
配置文件的内容如下:
{
"compilerOptions": {
"listFiles": true,
"typeRoots": ["./typings"]
}
}
注意,typeRoots
属性中的路径是相对于当前 tsconfig.json
配置文件的路径来进行解析的。
在 C:\app
目录下运行 tsc
命令,示例如下:
tsc
tsc
命令的运行结果如下:
<此处省略了内置的声明文件列表>
C:\app\index.ts
C:\app\typings\utils\index.d.ts
通过该运行结果能够看到,只有 typeRoots
属性定义的 C:\app\typings
目录下的声明文件被添加到了编译文件列表,而 C:\app\node_modules\@types
目录下的声明文件则没有被添加到编译文件列表。
如果想要同时使用 C:\app\typings
和 C:\app\node_modules\@types
目录下的声明文件,则需要将两者同时添加到 typeRoots
属性中。示例如下:
{
"compilerOptions": {
"listFiles": true,
"typeRoots": [
"./node_modules/@types",
"./typings"
]
}
}
在 C:\app
目录下运行 tsc
命令的运行结果如下:
<此处省略了内置的声明文件列表>
C:\app\index.ts
C:\app\typings\utils\index.d.ts
C:\app\node_modules\@types\jquery\index.d.ts
--types 编译选项
--types
编译选项也能够用来指定使用的声明文件。--typeRoots
编译选项配置的是含有声明文件的目录,而 --types
编译选项则配置的是具体的声明文件。
假设当前工程目录结构如下:
C:\app
|-- node_modules
| `-- @types
| |-- jquery
| | |-- index.d.ts
| | `-- package.json
| `-- lodash
| |-- index.d.ts
| `-- package.json
|-- index.ts
|-- package.json
|-- package-lock.json
`-- tsconfig.json
tsconfig.json
配置文件的内容如下:
{
"compilerOptions": {
"listFiles": true,
"types": ["jquery"]
}
}
在 C:\app
目录下运行 tsc
命令,示例如下:
tsc --listFiles
tsc
命令的运行结果如下:
<此处省略了内置的声明文件列表>
C:\app\index.ts
C:\app\node_modules\@types\jquery\index.d.ts
通过以上运行结果能够看到,只有 types
属性中定义的 jQuery
声明文件被添加到了编译文件列表,而 C:\app\node_modules\@types\lodash\index.d.ts
声明文件则没有被添加到编译文件列表。
继承配置文件
一个 tsconfig.json
配置文件可以继承另一个 tsconfig.json
配置文件中的配置。当一个项目中包含了多个 TypeScript 工程时,我们可以将工程共同的配置提取到 tsconfig.base.json
配置文件中,其他的 tsconfig.json
配置文件继承 tsconfig.base.json
配置文件中的配置。这种方式避免了重复配置同一属性并且能够增强可维护性,当需要修改某一共通属性时,仅需要修改一处即可。
在 tsconfig.json
配置文件中,使用顶层的 extends
属性来设置要继承的 tsconfig.json
配置文件。在 extends
属性中指定的路径既可以是相对路径,也可以是绝对路径,但路径解析规则有所不同。
--showConfig 编译选项
在介绍配置文件的继承之前,先介绍一下 --showConfig
编译选项。在使用该编译选项后,编译器将显示出编译工程时使用的所有配置信息。当我们在调试工程配置的时候,该编译选项是非常有帮助的。
但需要注意的是,若启用了 --showConfig
编译选项,那么编译器将不会真正编译一个工程,而只是显示工程的配置。
假设当前工程目录结构如下:
C:\app
|-- src
| `-- index.ts
`-- tsconfig.json
tsconfig.json
配置文件的内容如下:
{
"compilerOptions": {
"listFiles": true,
"target": "ES6"
}
}
在 C:\app
目录下运行 tsc
命令,示例如下:
tsc
tsc
命令的运行结果如下:
{
"compilerOptions": {
"target": "es6"
},
"files": [
"./src/index.ts"
]
}
该结果显示了在编译工程时最终使用的配置信息,它不但包含了 tsconfig.json
配置文件中的配置信息,还包含了待编译的文件列表。
注意,--showConfig
编译选项只能在命令行上使用,在 tsconfig.json
配置文件中不能使用该编译选项。
使用相对路径
若 extends
属性中指定的路径是以 ./
或 ../
作为起始的,那么编译器在解析相对路径时将参照当前 tsconfig.json
配置文件所在的目录。
假设当前工程目录结构如下:
C:\app
|-- src
| `-- index.ts
|-- tsconfig.app.json
|-- tsconfig.base.json
`-- tsconfig.spec.json
在 tsconfig.base.json
配置文件中包含了共同的配置,而 tsconfig.app.json
配置文件和 tsconfig.spec.json
配置文件继承了 tsconfig.base.json
配置文件中的配置。
tsconfig.base.json
文件的内容如下:
{
"compilerOptions": {
"target": "ES6"
}
}
tsconfig.app.json
文件的内容如下:
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"strict": true
},
"files": ["./src/index.ts"]
}
tsconfig.spec.json
文件的内容如下:
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"strict": false
},
"files": ["./src/index.spec.ts"]
}
在 C:\app
目录下运行 tsc
命令,并使用 tsconfig.app.json
配置文件来编译该工程。示例如下:
tsc --showConfig -p tsconfig.app.json
tsc
命令的运行结果如下:
{
"compilerOptions": {
"target": "es6",
"strict": true
},
"files": [
"./src/index.ts"
]
}
在 C:\app
目录下运行 tsc
命令,并使用 tsconfig.spec.json
配置文件来编译该工程。示例如下:
tsc --showConfig -p tsconfig.spec.json
tsc
命令的运行结果如下:
{
"compilerOptions": {
"target": "es6",
"strict": false
},
"files": [
"./src/index.spec.ts"
]
}
通过以上运行结果能够看到,tsconfig.app.json
配置文件和 tsconfig.spec.json
配置文件都继承了 tsconfig.base.json
配置文件中的 target
编译选项。
使用非相对路径
若 extends
属性指定的路径不是以 ./
或 ../
作为起始的,那么编译器将在 node_modules
目录下查找指定的配置文件。
编译器首先在 tsconfig.json
配置文件所在目录的 node_modules
子目录下查找,若该目录下包含了指定的配置文件,则使用该配置文件;否则,继续在父级目录下的 node_modules
子目录下查找,直到搜索到系统根目录为止。若最终未能找到指定的配置文件,则产生编译错误。
假设有如下目录结构的工程:
C:\app
|-- node_modules
| `-- tsconfig
| `-- tsconfig.standard.json
|-- index.ts
`-- tsconfig.json
tsconfig.json
配置文件的内容如下:
{
"extends": "tsconfig/tsconfig.standard.json"
}
此例中,编译器查找 tsconfig/tsconfig.standard.json
文件的步骤如下:
-
查找
C:\app\node_modules\tsconfig\tsconfig.standard.json
文件。 -
查找
C:\node_modules\tsconfig\tsconfig.standard.json
文件。 -
报错,文件未找到。
当编译器找到了匹配的配置文件时就会终止查找过程。此例中,在第 1 步找到了匹配的 tsconfig.standard.json
配置文件,于是使用该配置文件来编译工程并终止后续的查找。