[翻译]Nx 心智模型 (Mental Model)

Nx 是一个开源的功能强大的构建系统,用于提高开发人员生产力、优化 CI 性能和维护代码质量的工具和技术。

一、心智模型 (Mental Model)

Nx 是一个基于 VS Code 的构建工具。具有强大的核心且由元数据驱动,可以通过插件进行扩展能力。Nx 使用一些概念来 有效高效 的驱动, 你的第一存储库。本指南涵盖了项目图 (graphs),甘特图(task graphs)、受影响的命令(affected commands),计算(computation hashing)和缓存(caching)的心理模型。

二、项目图 (The project graph)

项目图 用于反映 存储库中的源代码 以及 未在存储库中编写 的所有外部依赖项,例如: WebpackReactAngular 等。

image.png

对于 Nx,项目中的节点 (Node)是在 project.json 文件中定义的。你可以 手动 定义节点之间的依赖关系,但不必经常这样做。Nx 分析文件的源代码、已安装的依赖、TypeScript 文件以及其他为你这些依赖的内容。 Nx 还缓存项目图,因此它只重新分析你已更改的文件。

项目图更新

每次分析完成之后,Nx 都会提供更新的图表。

三、元数据驱动

Nx 中的所有内容都带有 元数据 已实现工具化。默认值验证自动完成 工作等都在架构中定义,而不是代码中。此元数据由 Nx 本身、VSCodeWebStorm 集成、GitHub 集成以及 第三方 工具使用。

image.png

通过 Nx 使用元数据,这些工具能够实现更加丰富的体验。

四、任务图

Nx 使用 项目图 来创建 任务图。每当运行任何内容时,Nx 都会从 项目图 创建一个 任务图,然后执行该图中的 任务

扫描二维码关注公众号,回复: 15597193 查看本文章

例如,nx test lib 创建一个具有 单个节点 的任务图:

The task graph.png 任务是对目标的调用。如果调用 同一目标 两次,则会创建两个任务。

Nx 使用 项目图,但任务图和项目图不是同构的,这意味着它们没有直接连接。在上面的例子中,app1 依赖 app2lib,但是运行 nx run-many -t test -p app1 app2 lib,创建的任务图将如下所示:

项目图-任务图.png

尽管应用程序依赖于 lib 测试,但测试 app1 并不依赖于测试 lib。这意味着这两个任务可以并行运行。

让我们看看 测试目标 依赖于它的依赖项。

{
  "test": {
    "executor": "@nx/jest:jest",
    "outputs": ["{workspaceRoot}/coverage/apps/app1"],
    "dependsOn": ["^test"],
    "options": {
      "jestConfig": "apps/app1/jest.config.js",
      "passWithNoTests": true
    }
  }
}

这样,运行相同的测试命令将创建以下 任务图

项目图-任务图-next.png

这对于构建来说通常更有意义,在哪里构建 app1,你想 lib 首先构建。您还可以定义同一项目的目标之间的类似关系,包括依赖于构建的测试目标。

任务图 可以包含不同的目标,并且这些 目标 可以并行运行。例如,当 Nx 正在构建时 app2,它可以 app1 同时进行测试。

image.png

Nx 还以正确的 顺序运行 任务图中的任务。Nx 并行执行任务可加快整体执行时间。

五、受影响的命令

当运行 nx test app1 时,Nx 运行 app1:test 任务及其依赖的所有任务。

当运行时,在告诉 Nx 对两个任务和 nx run-many -t test -p app1 lib 执行相同的操作。 app1:test lib:test

当运行时 nx run-many -t test --allNx 对所有项目执行此操作。

随着工作空间的增长,重新测试所有项目变得太慢。为了解决这个问题,Nx 实施了代码更改分析,以获得需要重新测试的最小项目集。它是如何工作的?

当运行 nx affected -t test 时,Nx 会查看项目 PR 中更改的文件,它将查看更改的性质(您在这些文件中到底更新了什么),并使用它来计算工作区中可以更改的项目列表。受此变化影响。然后它 run-many 使用该列表运行命令。

例如,如果我的 PR 发生变化 lib ,然后我运行 nx affected -t testNx 会发现 app1app2 依赖 lib,因此它将调用 nx run-many -t test -p app1 app2 lib

做作的

Nx 分析变化的性质。例如,如果更改 package.jsonNext.js 的版本,Nx 知道不会 app2 受其影响,因此只会重新测试 app1

六、计算哈希和缓存

Nx 以正确的顺序运行任务图中的任务。在运行任务之前,Nx 计算其计算哈希。只要计算哈希相同,运行任务的输出就相同。

Nx 是如何做到的?

默认情况下,say 的计算哈希nx test app1包括:

  • app1 和的所有源文件 lib
  • 相关全局配置。
  • 外部依赖项的版本。
  • 用户配置的运行时值。
  • CLI 命令标志。

计算散列

此行为是可定制的。例如,lint 检查可能仅依赖于项目的源代码和全局配置。构建可以依赖于已编译库的 dts 文件而不是其源。

Nx 计算出任务的哈希值后,它会检查之前是否运行过这个精确的计算。首先,它在本地进行检查,然后如果丢失,如果配置了远程缓存,则进行远程检查。

如果 Nx 找到计算,Nx 会检索它并重播它。Nx 将正确的文件放入正确的文件夹中并打印终端输出。因此,从用户的角度来看,命令运行相同,只是速度快得多。

cache.svg

如果 Nx 找不到此计算,Nx 会运行该任务,完成后,它会获取输出和终端输出并将其存储在本地(如果远程配置)。所有这一切都是透明发生的,因此您不必担心。

尽管从概念上讲这相当简单,但 Nx 对此进行了优化,以使这种体验对您有利。例如  ,Nx

  • 捕获 stdoutstderr 以确保重放的输出看起来相同,包括在 Windows 上。
  • 通过记住哪些文件在哪里重播来最小化 IO
  • 仅在处理大型任务图时显示相关输出。
  • 提供对缓存未命中进行故障排除的功能。以及许多其他优化。

随着工作区的增长,任务图看起来更像这样:

grow-graphq.png

所有这些优化对于使 Nx 可用于任何重要的工作空间至关重要。仅发生最少量的工作。其余部分要么保持原样,要么从缓存中恢复。

七、分布式任务执行

Nx 支持跨多台机器运行命令。您可以手动设置或使用 Nx Cloud 阅读两种方法的比较。

当使用 分布式任务 执行时,Nx 能够在许多代理上而不是在本地 运行 任何 任务图

例如,nx affected --build 不会在本地运行构建(对于大型工作区,这可能需要几个小时)。相反,它会将任务图发送到 Nx Cloud。然后,Nx 云代理将选取它们可以运行的任务并执行它们。

请注意,这是透明发生的。如果代理构建 app1,它将获取输出(如果它还没有 lib )。

当代理完成任务时,您调用的主要作业 nx affected --build 将开始接收创建的文件和终端输出。

完成后 nx affected --build,机器将拥有构建文件和所有终端输出,就像在本地运行一样。

image.png

八、总结

  • Nx 能够 分析源代码 以创建 项目图
  • Nx 可以使用 项目图 和有关项目目标的信息来创建 任务图
  • Nx 能够执行代码更改分析,为项目的 PR 创建最小的 任务图
  • Nx 支持计算缓存,永远不会执行相同的计算两次。该 计算缓存可插拔 的并且可以是分布式的。

猜你喜欢

转载自juejin.im/post/7254474251725537335