【问题标题】:How to use project references in TypeScript 3.0?如何在 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

【问题讨论】:

    标签: typescript module


    【解决方案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
    

    让我们来看看变化:

    1. /tsconfig.json 重命名为 /tsconfig-base.json 本身就是一件非常重要的事情:根文件夹不再是 TypeScript 项目,因为 tsc 需要存在 tsconfig.json 文件。
    2. 另一方面,添加 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@
    猜你喜欢
    • 2017-11-20
    • 2019-01-16
    • 2018-12-20
    • 2018-03-15
    • 2020-01-16
    • 2018-12-31
    • 2013-08-30
    • 2017-12-08
    • 1970-01-01
    相关资源
    最近更新 更多