缓存依赖

了解如何通过缓存依赖来加快构建速度。


在构建任务开始编译你的项目之前,所有项目依赖都需要在磁盘上可用。获取依赖所需的时间越长,你完成构建所需的等待时间就越长——因此缓存依赖是加快构建速度的重要部分。

🌐 Before a build job can begin compiling your project, all project dependencies need to be available on disk. The longer it takes to acquire the dependencies, the more you need to wait for your build to complete — so caching dependencies is an important part of speeding up your builds.

我们正在积极改进缓存以及构建过程的其他方面,以确保构建速度稳定快速。

自定义缓存

🌐 Custom caching

[eas.json](/build/eas-json) 中构建配置文件的 cache 字段可用于为特定文件和目录配置缓存。指定的文件将在构建成功后保存到持久存储中,并在随后安装 JavaScript 依赖后的构建中恢复。恢复不会覆盖现有文件。更改 cache.key 值会使缓存失效。更改 cache 对象的任何其他属性也会使缓存失效。

🌐 The cache field on build profiles in eas.json can be used to configure caching for specific files and directories. Specified files will be saved to persistent storage after a successful build and restored on subsequent builds after the JavaScript dependencies are installed. Restoring does not overwrite existing files. Changing the cache.key value will invalidate the cache. Changing any other property of the cache object will also invalidate the cache.

JavaScript 依赖

🌐 JavaScript dependencies

EAS Build 会运行一个 npm 缓存服务器,可以加快为你的构建任务下载 JavaScript 依赖的速度。默认情况下,使用 npm 或 Yarn 2+ 的项目将使用缓存。然而,Yarn 1(经典版)需要你应用此解决方法才能在项目的 package.json 中使用缓存。

🌐 EAS Build runs an npm cache server that can speed up downloading JavaScript dependencies for your build jobs. By default, projects using npm or Yarn 2+ will use the cache. However, Yarn 1 (Classic) requires that you apply this workaround to use the cache in your project's package.json.

要在构建中禁用使用我们的 npm 缓存服务器,请在 eas.json 中将 EAS_BUILD_DISABLE_NPM_CACHE 环境变量的值设置为 "1"

🌐 To disable using our npm cache server for your builds set the EAS_BUILD_DISABLE_NPM_CACHE env variable value to "1" in eas.json.

eas.json
{ "build": { "production": { "env": { "EAS_BUILD_DISABLE_NPM_CACHE": "1" %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% }

不可变的锁文件

🌐 Immutable lockfiles

默认情况下,Node 包将使用你偏好的包管理器的不可变锁文件标志/命令(例如,yarn --frozen-lockfilenpm ci)进行安装。如果你想禁用此功能,可以在 eas.json 中将 EAS_NO_FROZEN_LOCKFILE 环境变量设置为 "1"

🌐 By default, Node packages will be installed with your preferred package manager's immutable lockfile flag/command (for example, yarn --frozen-lockfile or npm ci). If you would like to disable this, you can set the EAS_NO_FROZEN_LOCKFILE environment variable to "1" in eas.json.

Android 依赖

🌐 Android dependencies

EAS Build 运行 Maven 缓存服务器,可以加快构建作业下载 Android 依赖的速度。

🌐 EAS Build runs a Maven cache server that can speed up downloading Android dependencies for your build jobs.

目前,我们正在缓存:

🌐 Currently, we are caching:

要在构建中禁用使用我们的 Maven 缓存服务器,请在 eas.json 中将 EAS_BUILD_DISABLE_MAVEN_CACHE 环境变量的值设置为 "1"

🌐 To disable using our Maven cache server for your builds set the EAS_BUILD_DISABLE_MAVEN_CACHE env variable value to "1" in eas.json.

eas.json
{ "build": { "production": { "env": { "EAS_BUILD_DISABLE_MAVEN_CACHE": "1" %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% }

使用 ccache 缓存 C/C++ 编译产物

🌐 Caching C/C++ compilation artifacts with ccache

ccache 是一个编译器缓存,通过缓存之前的编译结果来加快本地代码的重新编译速度。EAS 开箱即支持 ccache 配置。

你可以配置构建,使其使用这些环境变量自动保存和恢复 ccache 缓存:

🌐 You can configure builds to save and restore ccache cache automatically with these environment variables:

  • EAS_USE_CACHE:设置为 1 时,会在构建作业期间同时启用缓存结果的恢复和保存。
  • EAS_RESTORE_CACHE:控制在构建开始时恢复缓存。设置为 1 以启用,或设置为 0 以禁用。会覆盖 EAS_USE_CACHE
  • EAS_SAVE_CACHE:控制是否在构建结束时保存构建缓存。设置为 1 以启用,或设置为 0 以禁用。将覆盖 EAS_USE_CACHE

EAS 工作流程

🌐 EAS Workflows

对于 EAS 工作流程,请使用 eas/restore_cacheeas/save_cache

🌐 For EAS Workflows, use eas/restore_cache and eas/save_cache.

安卓示例:

.eas/workflows/build-android.yml
jobs: build_android: type: build steps: - uses: eas/checkout - uses: eas/restore_build_cache # This is equivalent to the step above. You can also use /restore_cache for other caching purposes by defining your own key pattern and path # - uses: eas/restore_cache # with: # key: android-ccache-${{ hashFiles('yarn.lock') }} # restore_keys: android # path: /home/expo/.cache/ccache - uses: eas/build - uses: eas/save_build_cache # - uses: eas/save_cache # with: # key: android-ccache-${{ hashFiles('yarn.lock') }} # path: /home/expo/.cache/ccache

iOS 示例:

.eas/workflows/build-ios.yml
jobs: build_ios: type: build steps: - uses: eas/checkout - uses: eas/restore_build_cache # This is equivalent to the step above. You can also use /restore_cache for other caching purposes by defining your own key pattern and path # - uses: eas/restore_cache # with: # key: ios-ccache-${{ hashFiles('yarn.lock') }} # restore_keys: ios # path: /Users/expo/Library/Caches/ccache - uses: eas/build - uses: eas/save_build_cache # - uses: eas/save_cache # with: # key: ios-ccache-${{ hashFiles('yarn.lock') }} # path: /Users/expo/Library/Caches/ccache

定制构建

🌐 Custom builds

在自定义构建中,如果你管理构建步骤,请添加 eas/restore_build_cacheeas/save_build_cache 以启用 ccache 缓存。

🌐 In custom builds where you manage the build steps, add eas/restore_build_cache and eas/save_build_cache to enable ccache cache.

.eas/build/custom.yml
build: name: Build with ccache steps: - eas/checkout - eas/restore_build_cache - eas/build - eas/save_build_cache

缓存键使用包管理器锁文件的哈希来创建一个基于你的依赖的唯一键。当依赖发生变化时,将创建新的缓存,同时仍然允许使用 restore_keys 回退到之前的缓存。

🌐 The cache key uses a hash of the package manager lock file to create a unique key based on your dependencies. When dependencies change, a new cache will be created while still allowing fallback to previous caches using restore_keys.

缓存键匹配

🌐 Cache key matching

在恢复缓存时,缓存系统会遵循特定的搜索顺序来查找匹配的缓存条目。缓存键要么是自动生成的(使用 eas/restore_build_cacheeas/save_build_cache 时),要么是通过 key 参数显式提供的(使用 eas/restore_cacheeas/save_cache 时)。

🌐 When restoring a cache, the cache system follows a specific search sequence to find matching cache entries. The cache key is either automatically generated (when using eas/restore_build_cache or eas/save_build_cache) or explicitly provided via the key parameter (when using eas/restore_cache or eas/save_cache).

搜索序列:

🌐 The search sequence:

  1. 精确匹配:首先,它会搜索与缓存键(自动生成或明确提供)完全匹配的项
  2. 恢复键:如果未找到完全匹配项,restore_keys 将按顺序检查最近的前缀匹配

如果与提供的 key 完全匹配,则视为直接缓存命中,缓存会立即恢复。如果是部分匹配或来自 restore_keys 的匹配,缓存会被恢复,但可能无法达到最佳性能

🌐 If there is an exact match to the provided key, this is considered a direct cache hit and the cache is restored immediately. If there is a partial match or a match from restore_keys, the cache is restored but may not perform as effectively

使用恢复密钥

🌐 Using restore keys

注意: 密钥匹配的恢复由缓存系统自动处理,无需手动配置。这是对预期行为细节的参考。

恢复密钥 android-ccache- 匹配任何以字符串 android-ccache- 开头的密钥。例如,密钥 android-ccache-fd3052deandroid-ccache-a9b253ff 都匹配该恢复密钥。将使用创建日期最新的缓存。此示例中的密钥按以下顺序进行搜索:

🌐 The restore key android-ccache- matches any key that starts with the string android-ccache-. For example, both of the keys android-ccache-fd3052de and android-ccache-a9b253ff match the restore key. The cache with the most recent creation date would be used. The keys in this example are searched in the following order:

  1. android-ccache-${{ hashFiles('yarn.lock') }} 匹配特定哈希。
  2. android-ccache- 匹配以 android-ccache- 为前缀的缓存键。
  3. android- 匹配任何以 android- 开头的键。

缓存限制

🌐 Cache restrictions

访问限制通过在不同的 Git 分支或用户之间创建逻辑边界来提供缓存隔离和安全性。在构建应用时,了解并利用这些限制对你和你的用户的安全非常重要。

🌐 Access restrictions provide cache isolation and security by creating logical boundaries between different Git branches or users. It is important for security of yours and your users to understand and leverage them when building your app.

GitHub 运行

🌐 GitHub run

当从 GitHub 运行构建时,缓存会被限定到构建运行的分支。构建可以恢复在以下位置创建的缓存:

🌐 When a build is run from GitHub, caches get scoped to the branch the build is running from. A build can restore caches created in:

  • 当前分支
  • 默认分支(mainmaster

EAS CLI 运行

🌐 EAS CLI run

当从 eas-cli 触发构建时,缓存会针对运行构建的用户范围进行限制。这些以用户为范围的缓存可以实现隔离,从而在开发过程中或用户之间,构建及其缓存的修改不会被意外共享。

🌐 When a build is triggered from eas-cli, caches are scoped to the user running the build. These user-scoped caches allow for isolation so that modifications to the build and its cache are not unintentionally shared during development or between users.

默认分支缓存

🌐 Default branch cache

如果构建未能恢复用户范围的缓存,它将自动回退到恢复由默认分支触发的 GitHub 构建发布的缓存。这使得即使尚不存在用户范围的缓存,构建也可以利用受信任来源创建的缓存。

🌐 If a build doesn't restore a user-scoped cache, it will automatically fallback to restoring caches published from GitHub builds triggered on the default branch. This allows builds to benefit from caches created by trusted sources even when no user-scoped cache exists yet.

共享用户行为

🌐 Shared user behavior

当单个用户角色在多人之间共享时(例如使用访问令牌或从 GitHub Actions 触发构建),用户范围的缓存规则仍然适用。这意味着在该共享账户下运行的构建将不再拥有独立缓存,并有可能共享意外的构建产物。为避免这种情况,我们建议不要在共享用户下为生产构建恢复缓存,并且应安排特定的作业来仅保存干净的、新的缓存。

🌐 When a single user-actor is shared between multiple people (such as when using access tokens or triggering builds from GitHub Actions), user-scoped cache rules still apply. This means that builds operating under that shared account will no longer have isolated caches and run the risk of sharing unintended artifacts. To avoid this, we recommend not restoring cache for production builds under a shared user, and to have designated jobs to only save clean, new caches.

指定用于缓存创建的任务

🌐 Designated jobs for cache creation

你可以通过禁用缓存恢复并仅保存缓存来配置作业,以发布干净的新缓存。

🌐 You can configure a job to publish clean, new caches by disabling cache restoration and only saving the cache.

禁用生产构建的缓存恢复:

你可以通过配置这些环境变量来为特定的构建配置禁用缓存恢复:

🌐 You can disable cache restoration for specific build profiles by configuring these environment variables:

eas.json
{ "build": { "production": { "env": { "EAS_RESTORE_CACHE": "0", "EAS_SAVE_CACHE": "1" } }, "preview": { "env": { "EAS_USE_CACHE": "1" } } } }

仅保存指定作业的缓存:

为了确保只有可信来源发布缓存,你可以配置工作流程,仅从主分支上的特定任务保存缓存。

🌐 To ensure only trusted sources publish cache, you can configure a workflow to only save cache from specific job on the main branch.

.eas/workflows/build.yml
jobs: build_production: type: build if: ${{ github.ref_name == 'main' }} env: EAS_RESTORE_CACHE: '0' EAS_SAVE_CACHE: '1' params: platform: android profile: production

注意: 设置 EAS_SAVE_CACHE: '1' 并不会使缓存保存仅限于此任务,其他具有相同环境变量的任务仍然可以保存并覆盖缓存。

iOS 依赖

🌐 iOS dependencies

EAS Build 大部分通过缓存服务器提供 CocoaPods 构件。这提高了 pod install 时间的一致性,并且通常能加快速度。如果你提供自己的 .netrc.curlrc 文件,缓存将会自动被绕过。

🌐 EAS Build serves most CocoaPods artifacts from a cache server. This improves the consistency of pod install times and generally improves speed. The cache will be bypassed automatically if you provide your own .netrc or .curlrc files.

要禁用在构建中使用我们的 CocoaPods 缓存服务器,请在 eas.json 中将 EAS_BUILD_DISABLE_COCOAPODS_CACHE 环境变量的值设置为 "1"

🌐 To disable using our CocoaPods cache server for your builds set the EAS_BUILD_DISABLE_COCOAPODS_CACHE env variable value to "1" in eas.json.

eas.json
{ "build": { "production": { "env": { "EAS_BUILD_DISABLE_COCOAPODS_CACHE": "1" %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% }

在使用 prebuild 远程生成你的 ios 目录 在构建时 时,通常不会将项目的 Podfile.lock 提交到源码管理中。 缓存你的 Podfile.lock 可能很有用,这样可以实现确定性的构建,但在这种情况下的权衡是,由于你在本地开发时不使用锁文件,因此你在确定何时需要更改以及更新特定依赖的能力会受到限制。 如果你缓存了此文件,有时可能会遇到需要清除缓存才能解决的构建错误。 要缓存 Podfile.lock,请在 eas.json 的构建配置文件中的 cache.paths 列表中添加 ./ios/Podfile.lock

🌐 It is typical to not have your project Podfile.lock committed to source control when using prebuild to generate your ios directory remotely at build time. It can be useful to cache your Podfile.lock to have deterministic builds, but the tradeoff in this case is that, because you don't use the lockfile during local development, your ability to determine when a change is needed and to update specific dependencies is limited. If you cache this file, you may occasionally end up with build errors that require clearing the cache. To cache Podfile.lock, add ./ios/Podfile.lock to the cache.paths list in your build profile in eas.json.

eas.json
{ "build": { "production": { "cache": { "paths": ["./ios/Podfile.lock"] %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% } %%placeholder-start%%... %%placeholder-end%% }