如何在 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.jsontest/tsconfig.json 文件会将 srctest 变成两个独立的 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 依赖于srctest 必须以某种方式“知道”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,也不会丢失任何编译错误。

【讨论】:

感谢您抽出宝贵时间撰写此 Dmitry,感谢您的洞察力。 我希望官方文档能像这个答案一样清晰。谢谢! 你能在测试目录中显示实际代码吗? path 在这里和我们 import myFunction from "path" 一样重要。感觉这个答案缺少关键部分。 仍然没有导入的例子。到 gitlab 的链接是不够的。 @ChrisFremgen 我不完全确定,到底缺少什么。是exportimport 语句的用法吗?如果是,则未更改;选择加入 Project References 不会更改该语法。我认为这很明显,只是做了一个链接,而不是复制代码。如果您仍然觉得代码应该直接出现在答案中,请告诉我【参考方案2】:

它适用于您开发的 TypeScript 库,供其他 TypeScript 应用程序使用。因此,例如,如果您制作了一些像 lodash 这样的实用程序库,但正在与您的依赖应用程序一起积极开发它,那么 tsconfig.json 中的 references 可以让您引用源代码,并拥有您的依赖应用程序当 util 源发生变化时自动重建(即:tsc 检测到 util ts lib 中的源代码变化)

就我而言,我将referencesnpm 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 最佳入门实践

微软TypeScript 3.0重磅发布!

Vue 3.0前的 TypeScript 最佳入门实践

ThinkJS 3.0 如何实现对 TypeScript 的支持

vue-cli 3.0 安装和创建项目流程