TL;DR:
该功能允许将项目的各个部分定义为单独的 TypeScript 模块。除其他外,这允许以不同方式配置这些模块、单独构建它们等。
之前
最初,project structure 在简化后类似于:
/
src/
entity.ts # exports an entity
test/
entity.spec.ts # imports an entity
tsconfig.json
一个实体是defined in src/entity.ts module,然后是used in test/entity.spec.ts file。
请注意,这里只有一个tsconfig.json 文件,位于根文件夹中。这基本上说这个文件夹包含一个大的实体 TypeScript 项目。这个项目包括几个文件,组织在文件夹中;其中一些文件用于测试其他文件。
然而,这种结构带来了一个问题:编译项目(即tsc)的过程也会编译测试文件,从而在输出中创建dist/test/entity.spec.{js|d.ts} 文件。这不应该发生,因此 tsconfig.json 文件稍作更改以仅包含那些供外部使用的文件/文件夹:
{
"compilerOptions": {
// compiler options
},
"include": [
"./src"
]
}
这解决了问题,但在我的情况下,它也导致在开发过程中 TypeScript 编译器偶尔会忽略 /test 文件夹中的所有文件。此外,这种独特的方法可能并不适合所有人。
之后
utilizing the feature之后,项目结构变成了这样:
/
src/
entity.ts # exports an entity
tsconfig.json
test/
entity.spec.ts # imports an entity
tsconfig.json
tsconfig-base.json
让我们来看看变化:
- 将
/tsconfig.json 重命名为 /tsconfig-base.json 本身就是一件非常重要的事情:根文件夹不再是 TypeScript 项目,因为 tsc 需要存在 tsconfig.json 文件。
- 另一方面,添加
src/tsconfig.json 和 test/tsconfig.json 文件会将 src 和 test 变成两个独立的 TypeScript 项目,彼此独立。
/{src|test}/tsconfig.json 文件的内容是相似的,因为不需要更改配置,即“严格性”、输出文件夹以及其他此类参数应保留。为了使它们相似而无需复制粘贴任何东西,all the configurations are put in an arbitrary file,可从两个地方访问;在这种情况下,为此选择了根文件夹中的 tsconfig-base.json:
// the contents of /tsconfig-base.json
{
"compilerOptions": {
// compiler options, common to both projects
}
}
This file is being "inherited" then by /{src|test}/tsconfig.json 文件,如果需要,还可以添加任何其他选项:
// the contents of /{src|test}/tsconfig.json
{
"extends": "../tsconfig-base.json",
"compilerOptions": {
// additional compiler options, specific to a project
}
}
请注意,此模式与定义不完整实现的 abstract class 有何相似之处,然后通过两个单独的“具体”类对其进行扩展。
现在,/src 和 /test 文件夹基本上包含两个具有相似配置的独立 TypeScript 项目。最后要做的是指定两者之间的关系。由于test 依赖于src,test 必须以某种方式“知道”src。这是通过两个非常明显的步骤完成的:
-
allow src to be "referenced" 从外部声明为“复合”:
// in /src/tsconfig.json
{
"extends": "../tsconfig-base.json",
"compilerOptions": {
// compiler options
"composite": true
}
}
-
reference src from test:
// in /test/tsconfig.json
{
"extends": "../tsconfig-base.json",
"references": [
{ "path": "../src" }
]
}
/tsconfig-base.jsonis not needed now 中的"include" 数组,因为代码排除是通过“绘制新边框”完成的。
更新:自 TypeScript 3.7
以来,以下部分似乎已过时
现在,test 项目需要 *.d.ts 文件才能存在 src 项目。这意味着在运行测试之前,src 应该已经单独构建。这是由using the new mode of tsc 完成的,由--build 选项触发:
tsc --build src
此命令构建src 项目并将输出放入指定的输出文件夹(在本例中为/dist),既不会破坏test,也不会丢失任何编译错误。