如何在 TypeScript 3.0 中使用项目引用?
Posted
技术标签:
【中文标题】如何在 TypeScript 3.0 中使用项目引用?【英文标题】:How to use project references in TypeScript 3.0? 【发布时间】:2019-01-08 22:28:36 【问题描述】: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
【问题讨论】:
【参考方案1】: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.json
is 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
,也不会丢失任何编译错误。
【讨论】:
感谢您抽出宝贵时间撰写此 Dmitry,感谢您的洞察力。 我希望官方文档能像这个答案一样清晰。谢谢! 你能在测试目录中显示实际代码吗?path
在这里和我们 import myFunction from "path"
一样重要。感觉这个答案缺少关键部分。
仍然没有导入的例子。到 gitlab 的链接是不够的。
@ChrisFremgen 我不完全确定,到底缺少什么。是export
和import
语句的用法吗?如果是,则未更改;选择加入 Project References 不会更改该语法。我认为这很明显,只是做了一个链接,而不是复制代码。如果您仍然觉得代码应该直接出现在答案中,请告诉我【参考方案2】:
它适用于您开发的 TypeScript 库,供其他 TypeScript 应用程序使用。因此,例如,如果您制作了一些像 lodash
这样的实用程序库,但正在与您的依赖应用程序一起积极开发它,那么 tsconfig.json 中的 references
可以让您引用源代码,并拥有您的依赖应用程序当 util 源发生变化时自动重建(即:tsc
检测到 util ts lib 中的源代码变化)
就我而言,我将references
与npm link
和git submodules
结合使用,效果比ts 2.x
时代要好得多。
【讨论】:
我添加了项目结构的粗略表示。如果我正确理解了您的答案,创建project/test/tsconfig.json
文件并在其references
中指定project/lib/index.ts
是有意义的,对吧?这看起来有点奇怪,如果我错了,请纠正我。
@DmitryParzhitsky 您可以查看我的开源 typescript 项目作为示例。在 npm 中搜索“xlib”和“phantomjscloud”。第一个是图书馆,第二个使用它。在本地,我通过npm link xlib
有 phantomjscloud 参考 xlib@以上是关于如何在 TypeScript 3.0 中使用项目引用?的主要内容,如果未能解决你的问题,请参考以下文章
使用 yarn 和 ts 3.0 管理 typescript 项目 monorepo
Vuejs301- Vue 3.0前的 TypeScript 最佳入门实践