配置任务
Turborepo 将始终按照你的 turbo.json
配置文件 和 Package Graph 中描述的顺序运行任务,并在可能的情况下并行处理工作,以确保一切尽可能快地运行。这比一次运行一个任务更快,也是 Turborepo 如此快速的原因之一。
例如,yarn workspaces run lint && yarn workspaces run test && yarn workspaces run build
看起来会像这样


但是,要使用 Turborepo 更快地完成相同的工作,你可以使用 turbo run lint test build


开始使用
根目录下的 turbo.json
文件是你注册 Turborepo 将要运行的任务的地方。一旦你定义了你的任务,你就可以使用 turbo run
运行一个或多个任务。
- 如果你是全新开始,我们建议 使用
create-turbo
创建一个新的仓库 并编辑turbo.json
文件来尝试本指南中的代码片段。 - 如果你在现有仓库中采用 Turborepo,请在仓库的根目录中创建一个
turbo.json
文件。你将使用它来学习本指南中的其余配置选项。
定义任务
tasks
对象中的每个键都是一个可以通过 turbo run
执行的任务。Turborepo 将在你的包中搜索 与其 package.json
中与任务同名的脚本。
要定义一个任务,请使用 turbo.json
中的 tasks
对象。例如,一个没有依赖项和输出的名为 build
的基本任务可能看起来像这样
如果你此时运行 turbo run build
,Turborepo 将并行运行你的包中的所有 build
脚本,并且不会缓存任何文件输出。这很快会导致错误。 你缺少一些重要的部分,以使其按你期望的方式工作。
以正确的顺序运行任务
dependsOn
键 用于指定在另一个任务开始运行之前必须完成的任务。例如,在大多数情况下,你希望你的库的 build
脚本在你的应用程序的 build
脚本运行之前完成。为此,你将使用以下 turbo.json
你现在有了你期望的构建顺序,在 dependents 之前构建 dependencies。
但是要小心。 此时,你尚未标记构建输出以进行缓存。为此,请跳转到 指定输出 部分。
依赖于带有 ^
符号的依赖项中的任务
^
微语法告诉 Turborepo 从依赖关系图的底部开始运行任务。如果你的应用程序依赖于一个名为 ui
的库,并且该库有一个 build
任务,则 ui
中的 build
脚本将首先运行。一旦它成功完成,你的应用程序中的 build
任务将运行。
这是一个重要的模式,因为它确保你的应用程序的 build
任务将拥有编译所需的所有必要依赖项。当你的依赖关系图增长到具有多个任务依赖级别的更复杂结构时,此概念也适用。
依赖于同一包中的任务
有时,你可能需要确保同一包中的两个任务以特定的顺序运行。例如,你可能需要在你的库中运行 build
任务,然后再在同一库中运行 test
任务。为此,请在 dependsOn
键中将脚本指定为纯字符串(不带 ^
)。
依赖于特定包中的特定任务
你还可以指定要依赖的特定包中的单个任务。在下面的示例中,utils
中的 build
任务必须在任何 lint
任务之前运行。
你还可以更具体地说明依赖任务,将其限制在某个特定的包中
通过此配置,你的 web
包中的 lint
任务只能在 utils
包中的 build
任务完成后运行。
无依赖项
某些任务可能没有任何依赖项。例如,用于在 Markdown 文件中查找错别字的任务可能不需要关心其他任务的状态。在这种情况下,你可以省略 dependsOn
键或提供一个空数组。
指定 outputs
Turborepo 缓存你的任务的输出,这样你就永远不会做两次相同的工作。我们将在 缓存指南 中深入讨论这一点,但让我们首先确保你的任务配置正确。
outputs
键告诉 Turborepo 在任务成功完成后应该缓存的 文件和目录。如果未定义此键,Turborepo 将不会缓存任何文件。在后续运行中命中缓存将不会恢复任何文件输出。
以下是一些常用工具的输出示例
Glob 相对于包,因此 dist/**
将分别处理每个包输出的 dist
。有关为 outputs
键构建 glob 模式的更多信息,请参阅 glob 规范。
指定 inputs
inputs
键用于指定你想要包含在任务的哈希值中的文件,以便进行 缓存。默认情况下,Turborepo 将包括包中 Git 跟踪的所有文件。但是,你可以使用 inputs
键更具体地说明要包含在哈希值中的文件。
例如,用于查找 Markdown 文件中错别字的任务可以这样定义
现在,只有 Markdown 文件中的更改才会导致 spell-check
任务错过缓存。
此功能选择退出 Turborepo 的所有默认 inputs
行为,包括跟踪源代码控制跟踪的更改。这意味着你的 .gitignore
文件将不再被遵守,你需要确保你不会用你的 globs 捕获这些文件。
要恢复默认行为,请使用 $TURBO_DEFAULT$
微语法。
使用 $TURBO_DEFAULT$
恢复默认值
默认的 inputs
行为 通常是你希望用于任务的行为。但是,你可以通过微调你的 inputs
以忽略已知不会影响任务输出的文件的更改,来提高某些任务的缓存命中率。
因此,你可以使用 $TURBO_DEFAULT$
微语法来微调默认的 inputs
行为
在此任务定义中,Turborepo 将对 build
任务使用默认的 inputs
行为,但将忽略对 README.md
文件的更改。如果 README.md
文件被更改,任务仍然会命中缓存。
注册根任务
你还可以使用 turbo
在 Workspace 根目录的 package.json
中运行脚本。例如,除了每个包中的 lint
任务之外,你可能还希望为 Workspace 根目录中的文件运行 lint:root
任务
现在已注册根任务,turbo run lint:root
现在将运行该任务。你还可以运行 turbo run lint lint:root
来运行所有你的 lint 任务。
何时使用根任务
- Workspace 根目录的 Lint 和格式化:你的 Workspace 根目录中可能有一些你想要进行 lint 和格式化的代码。例如,你可能想在你的根目录中运行 ESLint 或 Prettier。
- 增量迁移:当你在迁移到 Turborepo 时,你可能有一个中间步骤,其中你有一些尚未移动到包的脚本。在这种情况下,你可以创建一个根任务来开始迁移,并将任务分散到以后的包中。
- 没有包范围的脚本:你可能有一些在特定包的上下文中没有意义的脚本。这些脚本可以注册为根任务,这样你仍然可以使用
turbo
运行它们,以实现缓存、并行化和工作流目的。
高级用例
使用包配置
包配置 是直接放置在包中的 turbo.json
文件。这允许包为其自己的任务定义特定的行为,而不会影响仓库的其余部分。
在拥有许多团队的大型 monorepo 中,这使团队能够更好地控制自己的任务。要了解更多信息,请访问 包配置文档
执行副作用
某些任务应该始终运行,无论如何,例如缓存构建后的部署脚本。对于这些任务,请在你的任务定义中添加 "cache": false
。
可以并行运行的依赖任务
尽管依赖于其他包,但某些任务可以并行运行。符合此描述的任务示例是 linters,因为 linter 不需要等待依赖项中的输出成功运行。
因此,你可能会想这样定义你的 check-types
任务
这会并行运行你的任务 - 但不考虑依赖项中的源代码更改。这意味着你可以
- 对你的
ui
包的接口进行破坏性更改。 - 运行
turbo check-types
,在依赖于ui
的应用程序包中命中缓存。
这是不正确的,因为应用程序包将显示成功的缓存命中,尽管它没有更新以使用新接口。在你的编辑器中手动检查你的应用程序包中的 TypeScript 错误很可能会显示错误。
因此,你对你的 check-types
任务定义进行了一个小的更改
如果你再次测试在你的 ui
包中进行破坏性更改,你会注意到缓存行为现在是正确的。但是,任务不再并行运行。
为了满足这两个要求(正确性和并行性),你可以将 Transit Nodes 引入到你的任务图中
这些 Transit Nodes 使用一个不执行任何操作的任务(因为它与任何 package.json
中的脚本都不匹配)在你的包依赖项之间创建关系。因此,你的任务可以并行运行 并且 能够感知到对其内部依赖项的更改。
在此示例中,我们使用了名称 transit
- 但你可以将任务命名为 Workspace 中尚未存在的任何脚本。
下一步
在 配置 turbo.json
文档 中有更多选项可用,你将在接下来的指南中进行探索。现在,你可以开始运行一些任务,看看基本原理是如何工作的。