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

Turborepo 的缓存可以在本地开发中节省大量时间——并且当启用 远程缓存 时,其威力将更加强大,它可以在你的整个团队和 CI 之间共享缓存。
在本页,你将了解
须知:
Turborepo 假定你的任务是确定性的。如果一个任务在 Turborepo 已知的输入集下能够产生不同的输出,那么缓存可能无法按预期工作。
实现第一次 Turborepo 缓存命中
你可以通过三个步骤来尝试 Turborepo 的缓存行为
首次运行构建
如果你已经全局安装了 turbo,请在你的仓库中运行 turbo build。
或者,你也可以使用你的包管理器运行 package.json 中的 build 脚本。
这将导致缓存未命中,因为你之前从未在此仓库中运行过具有此输入集的 turbo。这些输入将被转换为一个哈希值,用于在你的本地文件系统缓存或远程缓存中进行查找。
由于输入的指纹已在缓存中,因此无需从零开始重建你的应用程序。你可以从缓存中恢复上次构建的结果,从而节省资源和时间。
远程缓存
Turborepo 将任务的结果存储在你机器的 .turbo/cache 目录中。但是,通过与你的团队成员和 CI 共享此缓存,你可以使整个组织更快。
要了解有关远程缓存及其优势的更多信息,请访问远程缓存页面。
启用远程缓存
首先,使用你的远程缓存提供商进行身份验证
然后,将你机器上的仓库链接到远程缓存
现在,当你运行一个任务时,Turborepo 将自动将任务的输出发送到远程缓存。如果你在另一台也已通过身份验证到你的远程缓存的机器上运行相同的任务,那么在第一次运行时它将命中缓存。
有关如何将 CI 机器连接到远程缓存的信息,请访问构建 CI 指南。
默认情况下,Turborepo 使用Vercel 远程缓存,无需任何配置。如果你想使用不同的远程缓存,请访问远程缓存 API 文档。
什么会被缓存?
Turborepo 缓存两种类型的输出:任务输出和日志。
任务输出
Turborepo 缓存任务在 turbo.json 的outputs 键中定义的输出文件。当发生缓存命中时,Turborepo 将从缓存中恢复文件。
outputs 键是可选的,请参阅API 参考了解 Turborepo 在此情况下的行为。
提供文件输出
如果你没有为任务声明文件输出,Turborepo 将不会缓存它们。对于某些任务(如 linters)来说这可能没问题——但许多任务会产生你想要缓存的文件。
如果你在命中缓存时遇到文件不可用的错误,请确保你已为任务定义了输出。
日志
Turborepo 始终捕获任务的终端输出,并将这些日志从任务第一次运行时恢复到你的终端。
你可以使用--output-logs 标志或outputLogs 配置选项来配置重播日志的详细程度。
任务输入
Turborepo 会对输入进行哈希处理,生成任务运行的“指纹”。当“指纹”匹配时,运行该任务将命中缓存。
在底层,Turborepo 创建两个哈希值:全局哈希值和任务哈希值。如果其中任何一个哈希值发生更改,该任务将缓存未命中。
全局哈希输入
| 输入 | 示例 |
|---|---|
从根目录 turbo.json 解析的任务定义以及包的 turbo.json | 更改根目录 turbo.json 或包配置中的outputs |
| 影响工作区根目录的锁定文件更改 | 更新根目录 package.json 中的依赖项将导致所有任务缓存未命中 |
globalDependencies 文件的内容 | 更改 ./.env 文件(当它列在 globalDependencies 中时)将导致所有任务缓存未命中 |
列在 globalEnv 中的变量的值 | 更改 GITHUB_TOKEN 的值(当它列在 globalEnv 中时) |
| 影响任务运行时的标志值 | 使用改变行为的标志,例如 --cache-dir、--framework-inference 或 --env-mode |
| 任意传递参数 | turbo build -- --arg=value 将导致所有任务缓存未命中(与 turbo build 或 turbo build -- --arg=diff 相比)(包括未接收 --arg=value 的 build 的依赖项) |
包哈希输入
| 输入 | 示例 |
|---|---|
| 包配置更改 | 更改包的 turbo.json |
| 影响包的锁定文件更改 | 更新包的 package.json 中的依赖项 |
包的 package.json 更改 | 更新包的 package.json 中的 name 字段 |
| 源代码控制中的文件更改 | 在 src/index.ts 中写入新代码 |
故障排除
使用干运行
Turborepo 有一个--dry 标志,可用于在不实际运行任务的情况下查看运行任务会发生什么。当你确定不清楚正在运行哪些任务时,这对于调试缓存问题很有用。
有关更多详细信息,请访问--dry API 参考。
使用运行摘要
Turborepo 有一个--summarize 标志,可用于获取任务的所有输入、输出等的概述。比较两个摘要将显示为什么两个任务的哈希值不同。这可用于
- 调试输入:Turborepo 中的任务有许多输入。如果一个任务在你期望它命中缓存时却未命中,你可以使用运行摘要来检查哪些输入与你预期的不同。
- 调试输出:如果缓存命中未恢复你期望的文件,运行摘要可以帮助你了解哪些输出正在从缓存中恢复。
摘要查看器
虽然没有 Turborepo 原生的运行摘要 UI 查看器,但有几个社区构建的工具可用
- https://turbo.nullvoxpopuli.com - 运行摘要的基于 Web 的 UI 查看器
turborepo-summary- 从 Turborepo 运行摘要 JSON 输出生成人类可读的报告turborepo-summary-action- 包装turborepo-summary的 GitHub Action,将其附加到 GitHub Actions 作业摘要中
关闭缓存
有时,你可能不想将任务的输出写入缓存。这可以使用"cache": false永久设置为某个任务,或者使用 --cache <options> 标志为整个运行设置。
覆盖缓存
如果你想强制 turbo 重新执行一个已被缓存的任务,请使用--force 标志。请注意,这只会禁用读取缓存,而不是写入。
缓存一个任务比执行任务慢
有可能出现缓存比不缓存更慢的情况。这些情况很少见,但有几个例子包括
- 执行速度极快的任务:如果一个任务的执行速度比与远程缓存的网络往返时间还快,你应该考虑不缓存该任务。
- 输出资产巨大的任务:有可能创建一个巨大的工件,以至于上传或下载它的时间超过了重新生成它的时间,例如完整的 Docker 容器。在这种情况下,你应该考虑不缓存该任务。
- 有自己缓存的脚本:有些任务有自己的内部缓存行为。在这种情况下,配置很快就会变得复杂,以使 Turborepo 的缓存和应用程序的缓存协同工作。
虽然这些情况很少见,但请务必测试你的项目的行为,以确定在特定位置禁用缓存是否能带来性能优势。
后续步骤
现在你已经了解了 Turborepo 的缓存如何使你的仓库更快,让我们来看看如何在 Turborepo 中开发应用程序和库。
