Turborepo

缓存

Turborepo 使用缓存来加速构建,确保你不会重复做相同的工作。当你的任务可缓存时,Turborepo 将使用第一次运行任务时的指纹从缓存中恢复任务结果。

12 tasks are being ran in 3 packages, resulting in a ">>> FULL TURBO" cache hit. The total time it takes to restore these tasks from cache is 80 milliseconds.

Turborepo 的缓存功能在本地工作时可以显著节省时间 - 当启用远程缓存时,它会更加强大,可以在你的整个团队和 CI 之间共享缓存。

在本页中,你将学习到

须知

Turborepo 假设你的任务是确定性的。如果一个任务在 Turborepo 已知的输入集的情况下能够产生不同的输出,则缓存可能无法按预期工作。

命中你的第一个 Turborepo 缓存

你可以通过三个步骤尝试 Turborepo 的缓存行为

创建一个新的 Turborepo 项目

使用 npx create-turbo@latest 并按照提示创建一个新的 Turborepo。

终端
npx create-turbo@latest

首次运行构建

如果你全局安装了 turbo,请在你的存储库中运行 turbo build

或者,你可以使用你的包管理器运行 package.json 中的 build 脚本。

终端
npm run build

这将导致缓存未命中,因为你以前从未使用此存储库中的输入集运行过 turbo。这些输入被转换为哈希值,以便在本地文件系统缓存或远程缓存中进行检查。

命中缓存

再次运行 turbo build。你将看到如下消息

A terminal window showing two tasks that have been ran through turbo. They successfully complete in 116 milliseconds.

由于输入的指纹已存在于缓存中,因此没有理由再次从零开始重建你的应用程序。你可以从缓存中恢复上一次构建的结果,从而节省资源和时间。

远程缓存

Turborepo 将任务结果存储在你机器上的 .turbo/cache 目录中。但是,你可以通过与你的队友和 CI 共享此缓存来使你的整个组织运行得更快。

要了解有关远程缓存及其好处的更多信息,请访问远程缓存页面

启用远程缓存

首先,使用你的远程缓存提供商进行身份验证

终端
npx turbo login

然后,将你机器上的存储库链接到远程缓存

终端
npx turbo link

现在,当你运行任务时,Turborepo 会自动将任务的输出发送到远程缓存。如果你在另一台也已通过身份验证连接到你的远程缓存的机器上运行同一任务,则它将在第一次运行该任务时命中缓存。

有关如何将你的 CI 机器连接到远程缓存的信息,请访问构建 CI 指南

默认情况下,Turborepo 使用Vercel 远程缓存,无需任何配置。如果你想使用其他远程缓存,请访问远程缓存 API 文档

缓存的内容是什么?

Turborepo 缓存两种类型的输出:任务输出和日志。

任务输出

Turborepo 缓存在 turbo.jsonoutputs中定义的任务文件输出。当命中缓存时,Turborepo 将从缓存中恢复文件。

outputs 键是可选的,请参阅API 参考,了解 Turborepo 在这种情况下如何运行。

提供文件输出

如果你没有为任务声明文件输出,Turborepo 将不会缓存它们。这对于某些任务(如 linters)可能没问题 - 但许多任务会生成你希望缓存的文件。

如果你在命中缓存时遇到文件不可用的错误,请确保你已为你的任务定义了输出。

日志

Turborepo 始终捕获你任务的终端输出,并在第一次运行任务时将这些日志恢复到你的终端。

你可以使用--output-logs 标志outputLogs 配置选项来配置重播日志的详细程度。

任务输入

输入由 Turborepo 进行哈希处理,从而为任务运行创建一个“指纹”。当“指纹”匹配时,运行任务将命中缓存。

在底层,Turborepo 创建两个哈希值:全局哈希和任务哈希。如果任何一个哈希值发生更改,则该任务将不会命中缓存。

全局哈希输入

输入示例
从根 turbo.json 解析的任务定义
和包 turbo.json
更改根 turbo.json包配置中的outputs
影响工作区根目录的 Lockfile 更改更新根 package.json 中的依赖项将导致所有任务都未命中缓存
globalDependencies 文件内容./.env 列在 globalDependencies 中时,更改它将导致所有任务都未命中缓存
列在globalEnv中的变量的值GITHUB_TOKEN 列在 globalEnv 中时,更改它的值
影响任务运行时的标志值使用行为更改标志,如 --cache-dir--framework-inference--env-mode
任意传递的参数turbo build -- --arg=value 将与 turbo buildturbo build -- --arg=diff 相比未命中缓存

包哈希输入

输入示例
包配置更改更改包的 turbo.json
影响包的 Lockfile 更改更新包的 package.json 中的依赖项
包的 package.json 更改更新包的 package.json 中的 name 字段
源代码控制中的文件更改src/index.ts 中编写新代码

故障排除

使用空运行

Turborepo 有一个--dry 标志,可用于查看如果你运行任务而不实际运行会发生什么情况。当你不知道自己正在运行哪些任务时,这对于调试缓存问题很有用。

有关更多详细信息,请访问--dry API 参考

使用运行摘要

Turborepo 有一个--summarize 标志,可用于获取所有任务输入、输出等的概述。比较两个摘要将显示为什么两个任务的哈希值不同。这对于以下情况很有用:

  • 调试输入:在 Turborepo 中,任务有很多输入。如果任务在你期望命中缓存时未命中,你可以使用运行摘要来检查你未曾预料到的哪些输入不同。
  • 调试输出:如果缓存命中没有恢复你期望的文件,运行摘要可以帮助你了解正在从缓存中恢复哪些输出。

摘要查看器

虽然没有 Turborepo 原生的运行摘要 UI 查看器,但我们鼓励你使用社区构建的https://turbo.nullvoxpopuli.com,如果你想将你的运行摘要作为 Web 视图查看。

关闭缓存

有时,你可能不想将任务的输出写入缓存。可以使用"cache": false为任务永久设置,或者使用--no-cache 标志为整个运行设置。

覆盖缓存

如果你想强制 turbo 重新执行已缓存的任务,请使用--force 标志。请注意,这会禁用读取缓存,而不是写入

缓存任务比执行任务慢

在某些情况下,缓存最终会比不缓存慢。这些情况很少见,但以下是一些示例:

  • 执行速度极快的任务:如果任务的执行速度快于到远程缓存的网络往返,则应考虑不缓存该任务。
  • 输出资产巨大的任务:可能会创建过于庞大的工件,导致上传或下载它所花费的时间超过重新生成它所花费的时间,例如完整的 Docker 容器。在这些情况下,应考虑不缓存该任务。
  • 具有自身缓存的脚本:某些任务具有自己的内部缓存行为。在这些情况下,配置可能会变得很复杂,以使 Turborepo 的缓存和应用程序缓存协同工作。

虽然这些情况很少见,但请务必测试你的项目的行为,以确定在特定位置禁用缓存是否能带来性能优势。

下一步

既然你已经了解了 Turborepo 的缓存如何使你的存储库更快,接下来让我们看看如何在你的 Turborepo 中开发应用程序和库。

小时

节省的总计算量
开始使用
远程缓存 →

本页内容