软件包配置
许多 monorepos 可以在根目录中声明一个 turbo.json
,并在所有包中声明一个 任务描述。但是,有时,monorepo 可能包含需要以不同方式配置其任务的包。
¥Many monorepos can declare a turbo.json
in the root directory with a
task description that applies to all packages. But, sometimes, a monorepo can contain packages that need to configure their tasks differently.
为了实现这一点,Turborepo 允许你在任何包中使用 turbo.json
扩展根配置。这种灵活性使得更多样化的应用和软件包能够在工作区中共存,并允许软件包所有者维护专门的任务和配置,而不会影响 monorepo 的其他应用和软件包。
¥To accommodate this, Turborepo enables you to extend the root configuration with a turbo.json
in any package. This flexibility enables a more diverse set of apps and packages to co-exist in a Workspace, and allows package owners to maintain specialized tasks and configuration without affecting other apps and packages of the monorepo.
工作原理
¥How it works
要覆盖根 turbo.json
中定义的任何任务的配置,请在 monorepo 的任何软件包中添加一个带有顶层 extends
键的 turbo.json
文件:
¥To override the configuration for any task defined in the root turbo.json
, add
a turbo.json
file in any package of your monorepo with a top-level extends
key:


目前,extends
键的唯一有效值是 ["//"]
。//
是一个用于标识 monorepo 根目录的特殊名称。
¥For now, the only valid value for the extends
key is ["//"]
. //
is a
special name used to identify the root directory of the monorepo.
包中的配置可以覆盖任何 任务配置。任何未包含的键都将从扩展的 turbo.json
继承。
¥Configuration in a package can override any of the configurations for a
task. Any keys that are not included are inherited
from the extended turbo.json
.
示例
¥Examples
在一个应用中使用不同的框架工作区
¥Different frameworks in one Workspace
假设你的 monorepo 包含多个 Next.js 应用和一个 SvelteKit 应用。这两个框架都在各自的 package.json
中使用 build
脚本创建构建输出。你可以像这样配置 Turborepo,使其在根目录下使用单个 turbo.json
任务来运行这些任务:
¥Let's say your monorepo has multiple Next.js apps, and one SvelteKit
app. Both frameworks create their build output with a build
script in their
respective package.json
. You could configure Turborepo to run these tasks
with a single turbo.json
at the root like this:


请注意,即使 Next.js 应用不会生成 .svelte-kit
目录,.next/**
和 .svelte-kit/**
都需要指定为 outputs
,反之亦然。
¥Notice that both .next/**
and .svelte-kit/**
need to be specified as
outputs
, even though Next.js apps do not generate a .svelte-kit
directory, and
vice versa.
使用包配置,你可以在 apps/my-svelte-kit-app/turbo.json
中的 SvelteKit 包中添加自定义配置:
¥With Package Configurations, you can instead add custom
configuration in the SvelteKit package in apps/my-svelte-kit-app/turbo.json
:


并从根配置中移除 SvelteKit 特定的 outputs
:
¥and remove the SvelteKit-specific outputs
from the root configuration:


这不仅使每个配置更易于阅读,还使配置更接近其使用位置。
¥This not only makes each configuration easier to read, it puts the configuration closer to where it is used.
专门的任务
¥Specialized tasks
再举一个例子,假设一个软件包 dependsOn
中的 build
任务调用了一个 compile
任务。你可以将其声明为 dependsOn: ["compile"]
。这意味着你的根 turbo.json
必须有一个空的 compile
任务条目:
¥In another example, say that the build
task in one package dependsOn
a
compile
task. You could universally declare it as dependsOn: ["compile"]
.
This means that your root turbo.json
has to have an empty compile
task
entry:


使用包配置,你可以将该 compile
任务移动到 apps/my-custom-app/turbo.json
,
¥With Package Configurations, you can move that compile
task into the
apps/my-custom-app/turbo.json
,


并将其从根目录中移除:
¥and remove it from the root:


现在,my-app
的所有者可以完全拥有其 build
任务的所有权,但可以继续继承根目录中定义的任何其他任务。
¥Now, the owners of my-app
, can have full ownership over their build
task,
but continue to inherit any other tasks defined at the root.
与特定于软件包的任务的比较
¥Comparison to package-specific tasks
乍一看,包配置听起来很像根 turbo.json
中的 package#task
语法。它们的功能相似,但有一个显著的区别:当你在根 turbo.json
中声明特定于包的任务时,它将完全覆盖基线任务配置。使用软件包配置,任务配置将被合并。
¥At first glance, Package Configurations may sound a lot like the
package#task
syntax in the root turbo.json
. The features are
similar, but have one significant difference: when you declare a package-specific task
in the root turbo.json
, it completely overwrites the baseline task
configuration. With a Package Configuration, the task configuration is merged
instead.
再次考虑包含多个 Next.js 应用和一个 Sveltekit 应用的 monorepo 示例。使用特定于软件包的任务,你可以像这样配置你的根 turbo.json
:
¥Consider the example of the monorepo with multiple Next.js apps and a Sveltekit
app again. With a package-specific task, you might configure your root
turbo.json
like this:


在此示例中,对于 Sveltekit 应用,my-sveltekit-app#build
完全覆盖了 build
,因此 outputLogs
和 inputs
也需要复制。
¥In this example, my-sveltekit-app#build
completely overwrites build
for the
Sveltekit app, so outputLogs
and inputs
also need to be duplicated.
使用包配置,outputLogs
和 inputs
是继承的,因此你无需复制它们。你只需在 my-sveltekit-app
配置中覆盖 outputs
。
¥With Package Configurations, outputLogs
and inputs
are inherited, so
you don't need to duplicate them. You only need to override outputs
in
my-sveltekit-app
config.
虽然没有计划移除特定于包的任务配置,但我们预计在大多数情况下可以使用包配置。
¥Although there are no plans to remove package-specific task configurations, we expect that Package Configurations can be used for most use cases instead.
Experimental 边界标签
¥Boundaries Tags Experimental
软件包配置也用于声明边界标签。为此,请在你的 turbo.json
中添加一个 tags
字段:
¥Package Configurations are also used to declare Tags for Boundaries. To do so, add a tags
field to your turbo.json
:


从这里,你可以定义标签可以包含哪些依赖或被依赖的规则。查看 边界文档 了解更多详细信息。
¥From there, you can define rules for which dependencies or dependents a tag can have. Check out the Boundaries documentation for more details.
限制
¥Limitations
虽然总体思路与根 turbo.json
相同,但软件包配置附带一组防护措施,可以防止软件包造成潜在的混乱情况。
¥Although the general idea is the same as the root turbo.json
, Package
Configurations come with a set of guardrails that can prevent packages from creating
potentially confusing situations.
软件包配置不能使用 workspace#task
语法 作为任务条目
¥Package Configurations cannot use the workspace#task
syntax as task entries
package
是根据配置的位置推断出来的,并且无法更改其他包的配置。例如,在 my-nextjs-app
的包配置中:
¥The package
is inferred based on the location of the configuration, and it is
not possible to change configuration for another package. For example, in a
Package Configuration for my-nextjs-app
:


请注意,build
任务仍然可以依赖于特定于包的任务:
¥Note that the build
task can still depend on a package-specific task:


软件包配置只能覆盖 tasks
键中的值
¥Package Configurations can only override values in the tasks
key
无法在包配置中像 globalEnv
或 globalDependencies
那样覆盖 全局配置。需要在包配置中更改的配置并非真正全局的,应该进行不同的配置。
¥It is not possible to override global configuration like globalEnv
or globalDependencies
in a Package Configuration. Configuration that would need to be altered in a Package Configuration is not truly global and should be configured differently.
Root turbo.json 无法使用 extends
键
¥Root turbo.json cannot use the extends
key
为避免在包上创建循环依赖,根 turbo.json
不能从任何包扩展。extends
键将被忽略。
¥To avoid creating circular dependencies on packages, the root turbo.json
cannot extend from anything. The extends
key will be ignored.
故障排除
¥Troubleshooting
在大型单体仓库中,有时可能很难理解 Turborepo 如何解释你的配置。为了提供帮助,我们在 试运行 输出中添加了 resolvedTaskDefinition
。例如,如果你运行 turbo run build --dry-run
,输出将包含在运行 build
任务之前考虑的所有 turbo.json
配置的组合。
¥In large monorepos, it can sometimes be difficult to understand how Turborepo is
interpreting your configuration. To help, we've added a resolvedTaskDefinition
to the Dry Run output. If you run turbo run build --dry-run
, for example, the
output will include the combination of all turbo.json
configurations that were
considered before running the build
task.