模块缓存
模块缓存 {#module-cache}
Section titled “模块缓存 {#module-cache}”::: warning 要求
- 一个
生成的项目 - 一个
Tuist 账户和项目
:::
Tuist 模块缓存提供了一种通过将模块缓存为二进制文件(.xcframework)并在不同环境之间共享来优化构建时间的强大方法。此功能使你能够利用之前生成的二进制文件,减少重复编译的需求并加快开发过程。
预热 {#warming}
Section titled “预热 {#warming}”Tuist 高效地
这个被称为*“预热”*的操作会生成用于本地使用或通过 Tuist 与队友和 CI 环境共享的二进制文件。预热缓存的过程很简单,可以用以下命令启动:
tuist cache该命令会重用二进制文件以加快这个过程。
使用方法 {#usage}
Section titled “使用方法 {#usage}”默认情况下,当 Tuist 命令需要生成项目时,如果缓存中有可用的依赖项,它们会自动将依赖项替换为它们的二进制版本。此外,如果你指定了要聚焦的目标列表,Tuist 还将用它们的缓存二进制文件替换任何依赖目标(如果可用)。对于喜欢不同方法的人,可以使用特定标志选择完全退出此行为:
::: code-group
tuist generate # 仅依赖项tuist generate Search # 依赖项 + Search 的依赖项tuist generate Search Settings # 依赖项,以及 Search 和 Settings 的依赖项tuist generate --cache-profile none # 完全不使用缓存tuist test:::
::: warning
二进制缓存是为开发工作流设计的,例如在模拟器或设备上运行应用,或运行测试。它不适用于发布构建。归档应用时,使用 --cache-profile none 生成包含源码的项目。
:::
缓存配置文件 {#cache-profiles}
Section titled “缓存配置文件 {#cache-profiles}”Tuist 支持缓存配置文件来控制生成项目时目标被缓存二进制替换的积极程度。
- 内置配置:
only-external:仅替换外部依赖(系统默认)all-possible:替换尽可能多的目标(包括内部目标)none:永远不用缓存二进制替换
使用 tuist generate 上的 --cache-profile 选择配置:
# 内置配置文件tuist generate --cache-profile all-possible
# 自定义配置文件(在 Tuist 配置中定义)tuist generate --cache-profile development
# 使用配置默认值(无标志)tuist generate
# 聚焦特定目标(意味着 all-possible)tuist generate MyModule AnotherTarget
# 完全禁用二进制替换tuist generate --cache-profile none::: info 已弃用的标志
--no-binary-cache 标志已被弃用。请改用 --cache-profile none。为了向后兼容,弃用的标志仍然有效。
:::
解析有效行为时的优先级(从高到低):
--cache-profile none- 目标聚焦(将目标传递给
generate)→ 配置all-possible --cache-profile <value>- 配置默认值(如果设置)
- 系统默认 (
only-external)
支持的产品 {#supported-products}
Section titled “支持的产品 {#supported-products}”只有以下目标产品可以被 Tuist 缓存:
- 不依赖于 XCTest 的框架(静态和动态)
- Bundle
- Swift 宏
我们正在努力支持依赖于 XCTest 的库和目标。
::: info 上游依赖
当一个目标不可缓存时,它也会使上游目标不可缓存。例如,如果你有依赖图 A > B,其中 A 依赖于 B,如果 B 不可缓存,A也将不可缓存。
:::
效率 {#efficiency}
Section titled “效率 {#efficiency}”二进制缓存能达到的效率水平很大程度上取决于图结构。为了获得最佳结果,我们建议:
- 避免过于嵌套的依赖图。图越浅越好。
- 使用协议/接口目标而不是实现目标来定义依赖项,并从最顶层目标依赖注入实现。
- 将经常修改的目标拆分为更小的、变更可能性更低的目标。
上述建议是
推荐设置 {#recommended-setup}
Section titled “推荐设置 {#recommended-setup}”我们建议有一个 CI 作业在主分支的每个提交上运行来预热缓存。这将确保缓存始终包含 main 中更改的二进制文件,以便本地和 CI 分支可以在此基础上增量构建。
::: tip 保持缓存预热隔离
在专门的 CI 步骤中运行 tuist cache,而不依赖于生成的工作空间的后续步骤。由于 tuist cache 修改工作空间以进行缓存构建,任何需要工作空间的 CI 步骤应首先运行 tuist generate 以获取新的可用工作空间。
::: tip 缓存预热使用二进制
tuist cache 命令也利用二进制缓存来加速预热。
:::
以下是一些常见工作流程的示例:
开发者开始开发新功能 {#a-developer-starts-to-work-on-a-new-feature}
Section titled “开发者开始开发新功能 {#a-developer-starts-to-work-on-a-new-feature}”- 他们从
main创建新分支。 - 他们运行
tuist generate。 - Tuist 从
main中提取最新的二进制文件,并用它们生成项目。
开发者向上游推送更改 {#a-developer-pushes-changes-upstream}
Section titled “开发者向上游推送更改 {#a-developer-pushes-changes-upstream}”- CI 流水线将运行
xcodebuild build或tuist test来构建或测试项目。 - 工作流程将从
main中提取最新的二进制文件,并用它们生成项目。 - 然后它将增量构建或测试项目。
配置 {#configuration}
Section titled “配置 {#configuration}”缓存并发限制 {#cache-concurrency-limit}
Section titled “缓存并发限制 {#cache-concurrency-limit}”默认情况下,Tuist 下载和上传缓存产物没有任何并发限制,以最大化吞吐量。你可以使用 TUIST_CACHE_CONCURRENCY_LIMIT 环境变量来控制此行为:
# 设置特定的并发限制export TUIST_CACHE_CONCURRENCY_LIMIT=10tuist generate
# 使用 "none" 表示无限制(默认行为)export TUIST_CACHE_CONCURRENCY_LIMIT=nonetuist generate这在网络带宽受限的环境或减少缓存操作期间的系统负载时可能很有用。
故障排除 {#troubleshooting}
Section titled “故障排除 {#troubleshooting}”它没有为我的目标使用二进制 {#it-doesnt-use-binaries-for-my-targets}
Section titled “它没有为我的目标使用二进制 {#it-doesnt-use-binaries-for-my-targets}”确保diff 命令比较两次 tuist generate 调用或跨环境或运行生成的项目。
还要确保目标不直接或间接依赖于
缺少符号 {#missing-symbols}
Section titled “缺少符号 {#missing-symbols}”使用源码时,Xcode 的构建系统通过 Derived Data 可以解析未显式声明的依赖。但是,当你依赖二进制缓存时,依赖必须显式声明;否则当你找不到符号时可能会看到编译错误。为了调试这个问题,我们建议使用tuist inspect dependencies --only implicit