TypeScript 3.0中有一个名为Project References的新功能。它建议*.ts
模块之间更好的交互。不幸的是,尽管这看起来写得非常清楚和直接,但我只能从官方文档中得到所有信息。
任何人都可以帮助我确切地了解它,解决了什么问题,如何做到这一点以及如何从中受益?我有一个结构类似的项目,因此它可能(也可能不会)对此很有帮助。预先谢谢你!
UPD:项目结构大致为:
project/
lib/
index.ts # defines the original code
test/
index.spec.ts # requires lib/index.ts
package.json
tsconfig.json
答案 0 :(得分:12)
由于该问题受到越来越多的反对,我对此进行了深入研究并设法理解了该功能。希望这个答案会有所帮助。
最初的项目结构与此类似:
/
lib/
index.ts # defines the original code
test/
index.spec.ts # requires lib/index.ts
tsconfig.json
这里只有一个 tsconfig.json
文件,它表示/
(根)文件夹仅包含一个 TypeScript项目,项目本身包括 /lib
和/test
文件夹。
这又意味着编译项目时,输出将包含/test/index.spec.{js|d.ts}
个文件。虽然那不是我想要的,所以我将"include"
数组添加到/tsconfig.json
文件中:
{
"compilerOptions": {
// ...
},
"include": [
"./lib"
]
}
...以排除除/lib
之外的所有内容。
这有所帮助,但不幸的是,TypeScript编译器有时会忽略/test
文件夹中的所有文件。
利用项目引用后,project structure具有changed to this:
/
lib/
index.ts # defines the original code
tsconfig.json
test/
index.spec.ts # requires lib/index.ts
tsconfig.json
tsconfig-base.json
现在有两个 tsconfig.json
个文件:/lib/tsconfig.json
和/test/tsconfig.json
。这意味着/
(根)文件夹现在包含一个非TypeScript项目,其本身具有两个TypeScript“子项目”。
换句话说,我们在项目中添加了模块化。
两个/{lib|test}/tsconfig.json
文件都有一些共同的逻辑(假设它们都是"strict": true
)。为了指定没有重复,我们将逻辑放在/tsconfig-base.json
文件中:
{
"compilerOptions": {
"strict": true
}
}
...并制作两个/{lib|test}/tsconfig.json
文件以继承为基础:
{
"extends": "../tsconfig-base.json"
}
现在,/lib
和/test
基本上是两个具有相同配置的独立TypeScript项目。
最后要做的是指定两者之间的关系。这分两个步骤完成:
从/lib
项目中引用/test
项目(因为 tests 取决于 lib ,而不是相反):
// in /test/tsconfig.json
{
"extends": "../tsconfig-base.json",
"references": [
{ "path": "../lib" }
]
}
允许引用/lib
项目:
// in /lib/tsconfig.json
{
"extends": "../tsconfig-base.json",
"compilerOptions": {
"composite": true
}
}
此外,现在不需要"include"
中的/tsconfig-base.json
数组。
通过这些更改,tsc --build lib
命令(在根级别)仅编译/lib
项目,而不会破坏/test
,也不会丢失任何编译错误。
答案 1 :(得分:2)
用于您开发的打字稿库,供其他打字稿应用程序使用。因此,举例来说,如果您制作了lodash
之类的实用程序库,但正在与您的依赖应用程序一起积极地开发它,则tsconfig.json`中的references
可让您引用源代码,并且在util来源发生变化时(IE:tsc在util ts lib中检测到源代码发生了变化)自动重建您的依赖应用程序
就我而言,我将references
与npm link
和git submodules
结合使用,并且效果比ts 2.x
天更好。
答案 2 :(得分:-8)
**** UPDATE ****(2018年8月3日)
在信用到期的地方提供信用。
下面的内容是由Microsoft的Daniel Rosenwasser引用的“ Announcing TypeScript 3.0”
为库或应用程序执行几个不同的构建步骤是很普遍的。也许您的代码库有一个src
和一个test
目录。也许您的前端代码位于一个名为client
的文件夹中,而Node.js后端代码位于一个名为server
的文件夹中,并且每个代码都从一个shared
文件夹导入。也许您使用所谓的“ monorepo”,并且有许多项目以非平凡的方式相互依赖。
项目参考旨在使这些方案的工作更加轻松。
项目引用允许TypeScript项目依赖于其他TypeScript项目-具体而言,允许tsconfig.json
文件引用其他tsconfig.json
文件。指定这些依赖性使您更容易将代码拆分为较小的项目,因为它为TypeScript(及其周围的工具)提供了一种理解构建顺序和输出结构的方式。这意味着诸如更快的构建可以逐步运行,并支持跨项目的透明导航,编辑和重构之类的事情。
是什么样子?
作为一个简单的例子,带有项目引用的tsconfig.json
如下所示:
// ./src/bar/tsconfig.json
{
"compilerOptions": {
// Needed for project references.
"composite": true,
"declaration": true,
// Other options...
"outDir": "../../lib/bar",
"strict": true, "module": "esnext", "moduleResolution": "node",
},
"references": [
{ "path": "../foo" }
]
}
此处需要注意两个新字段:composite
和references
。
references
仅指定其他tsconfig.json
文件(或包含它们的文件夹)。当前,每个引用都是一个带有path
字段的对象,并让TypeScript知道构建当前项目需要首先构建该引用项目。
composite
字段也许同样重要。 composite
字段确保启用了某些选项,以便可以为依赖于此项目的任何项目引用和逐步构建此项目。能够智能地进行增量重建很重要,因为构建速度是您可能首先分解项目的原因之一。例如,如果项目front-end
依赖于shared
,而shared
依赖于core
,那么我们围绕项目引用的API可用于检测core
中的变化,但仅在shared
产生的类型(即.d.ts文件)已更改的情况下重建core
。这意味着更改core
并不会完全迫使我们重建世界。因此,设置composite
也会强制设置declaration
标志。
TypeScript的构建模式
TypeScript 3.0将提供一组用于项目引用的API,以便其他工具可以提供这种快速的增量行为。 tsc
现在带有新的--build
标志。
tsc --build
(或其昵称,tsc -b
)采用一组项目,并构建它们及其依赖项。
控制输出结构
从逻辑上讲,能够将您的输入源映射到其输出,这是项目引用的一个微妙但非常有用的好处。
如果您曾经尝试在应用程序的客户端和服务器之间共享TypeScript代码,则可能会遇到控制输出结构的问题。
例如,如果client/index.ts
和server/index.ts
都引用shared/index.ts
用于以下项目:
src
├── client
│ ├── index.ts
│ └── tsconfig.json
├── server
│ ├── index.ts
│ └── tsconfig.json
└── shared
└── index.ts
...然后尝试构建client
和server
,我们最终会得到...
lib
├── client
│ ├── client
│ │ └── index.js
│ └── shared
│ └── index.js
└── server
├── server
│ └── index.js
└── shared
└── index.js
而不是
lib
├── client
│ └── index.js
├── shared
│ └── index.js
└── server
└── index.js
请注意,我们最终在shared
和client
中都复制了server
。我们不必要地花了两次时间来构建shared
,并在lib/client/client
和lib/server/server
中引入了不希望的嵌套级别。
理想情况下,TypeScript应该理解这些文件不需要在同一编译中构建,而是可以跳转到.d.ts
文件中以获取类型信息。
为tsconfig.json
创建一个shared
并使用项目引用可以做到这一点。它向TypeScript发出信号
shared
应该独立构建,并且../shared
导入时,我们应该在其输出目录中查找.d.ts
文件。这避免了触发双重生成,也避免了意外吸收shared
的所有内容。