缓存
Turborepo 使用缓存来加速构建,确保你永远不会重复做同样的工作。当你的任务可以被缓存时,Turborepo 会使用任务首次运行时的指纹从缓存中恢复任务的结果。
Turborepo 的缓存在本地工作时可以显著节省时间 - 当启用远程缓存时更加强大,可以在整个团队和 CI 之间共享缓存。
在本页面中,你将了解:
Good to know:
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 将不会缓存它们。对于某些任务(如代码检查器)来说这可能没问题 - 但许多任务会产生你想要缓存的文件。
如果你遇到命中缓存时文件不可用的错误,请确保你已经为你的任务定义了输出。
日志
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 相比缓存未命中 |
包哈希输入
输入 | 示例 |
---|---|
包配置更改 | 更改包的 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 如果你想要以网页视图查看你的运行摘要。
关闭缓存
有时,你可能不想将任务的输出写入缓存。这可以通过"cache": false
永久设置任务,或使用--no-cache
标志为整个运行设置。
覆盖缓存
如果你想强制 turbo
重新执行已缓存的任务,使用--force
标志。注意,这会禁用读取缓存,而不是写入。
缓存任务比执行任务更慢
可能会出现缓存最终比不缓存更慢的情况。这些情况很少见,但以下是一些例子:
- 执行极快的任务:如果任务执行的速度比到远程缓存的网络往返更快,你应该考虑不缓存该任务。
- 输出资产巨大的任务:可能会创建一个大到上传或下载时间超过重新生成时间的制品,比如完整的 Docker 容器。在这些情况下,你应该考虑不缓存该任务。
- 有自己缓存的脚本:某些任务有自己的内部缓存行为。在这些情况下,配置很快就会变得复杂,需要让 Turborepo 的缓存和应用程序缓存一起工作。
虽然这些情况很少见,但请务必测试你的项目的行为,以确定在特定位置禁用缓存是否能提供性能优势。
下一步
现在你已经看到了 Turborepo 的缓存如何让你的仓库更快,让我们看看如何在你的 Turborepo 中开发应用程序和库。