启用构建缓存(实验性)
Rush 一直支持 增量分析 功能,它允许 rush build
来跳过一些自上次构建后没有文件修改的项目(该优化同样适用于自定义指令,只要在 custom-commands.json 中开启 incremental
即可)。然而,构建产物并没有并时刻保存,因此当切换到另外一个分支时,通常需要执行 rebuild 来重新构建。
Rush 中实验性的构建缓存将在每个项目的构建产物中创建一个 tar 文件,该文件会被缓存,如果 rush build
可以匹配到缓存,则会从缓存中读取该文件,从而避免了重新构建。这就可以显著提高构建速度,例如将一个 30 分钟的构建耗时缩短到 30 秒。缓存的键值是源文件和 NPM 依赖的哈希值,与增量分析的基本规则相同。
构建缓存的文件将保存在两个地方:
本地磁盘的缓存目录下。这样做可以在切换分支时候不会丢掉数据,你甚至可以在机器上配置一个共享的缓存目录,其默认位置是 common/temp/build-cache.
云端(可选)。一般而言,CI 系统可以配置成允许写入云端存储,同时每个用户只有可读权限。例如,每次 PR 被合并到
main
分支时,CI 系统会以此为基准进行构建并将其上传到云上。这样,对于即使是git clone
的开发者而言,他们的rush build
也是非常快的。
构建缓存被认为是跳过构建的替代方案,一旦被启动,支持增量构建的指令将从缓存中读取数据,而不是之前的“跳过”。 如果项目没有配置构建缓存,或者故意的禁止掉构建缓存,将会使用默认的跳过。
启用本地磁盘缓存
在 build-cache.json 中可以开启本地构建缓存,你可以从该页面拷贝或者使用 rush init
创建这个文件。
本地构建缓存有两个配置项:
common/config/rush/build-cache.json
{
. . .
/**
* (必须)实验性 -当该值为 true 时将会启动构建缓存。
*
* 可以查阅 https://rushjs.io/pages/maintainer/build_cache/ 了解更多
*/
"buildCacheEnabled": true,
/**
* (必须)选择哪些项目的构建产物需要被缓存。
*
* 可能的值:"local-only","azure-blob-storage","amazon-s3"
*/
"cacheProvider": "local-only",
. . .
}
升级提示:早期版本的该功能需要在 experiments.json 中设定
"buildCache": true
. 这个配置项已经被 build-cache.json 下的"buildCacheEnabled"
替代。
配置项目的输出目录
当你运行 rush rebuild --verbose
时,会看到如下警告:
Project does not have a rush-project.json configuration file, or one provided by a rig, so it does not support caching.
构建缓存需要知道哪些目录需要被存储在 tar 的压缩包中,这些细节可能由于工具链的不同而不同,因此每个项目都需要使用 rush-project.json 来单独配置。
例如:
<your-project>/config/rush-project.json
. . .
/**
* 指定你的工具链的产物输出目录,如果此字段开启,Rush 构建缓存将从缓存中恢复这些目录。
*
* 字符串是项目根目录下的目录名,这些项目不应被 Git 记录到,并且必须不能包含符号链接。
*/
"projectOutputFolderNames": ["lib", "dist"]
. . .
}
建议使用 rig 包 来避免每个项目目录中都拷贝一份。
测试构建缓存
当开启缓存后项目的输出日志示例为:
$ rush rebuild --verbose
. . .
==[ example-project ]==============================================[ 1 of 5 ]==
This project was not found in the build cache.
Invoking: heft test --clean
. . .
Caching build output folders: lib
Successfully set cache entry.
"example-project" completed successfully in 11.27 seconds.
当第二次执行相同的命令时,Rush 会将压缩包解压,而不是再次执行构建任务。
$ rush rebuild --verbose
. . .
==[ example-project ]==============================================[ 1 of 5 ]==
Build cache hit.
Clearing cached folders: lib, dist
Successfully restored output from the build cache.
example-project was restored from the build cache.
注意 rush rebuild
将不会再读取缓存。将 RUSH_BUILD_CACHE_WRITE_ALLOWED
的环境变量设置为 0
可以禁止在 rush rebuild
时阶段写入缓存,
默认而言,缓存的 tar 压缩包存储在 common/temp/build-cache 目录中,因此可以被 rush purge
删除。
启用云端存储
目前 cacheProvider
有三个选项:
"local-only"
:不启用云端存储,压缩包只保存在本地磁盘上"azure-blob-storage"
:Microsoft Azure blob storage container"amazon-s3"
:Amazon S3 bucket
(以上能力由 modeled as Rush plugins. 自定义的云存储服务可参考该插件实现)
例如,这里是如何配置 Azure blob 容器的方法:
common/config/rush/build-cache.json
{
. . .
/**
* (必须)实验性的 - 设定为 true 启用构建缓存功能。
*
* 更多信息可参考 https://rushjs.io/pages/maintainer/build_cache/
*/
"buildCacheEnabled": true,
/**
* (必须)选择哪些项目的构建产物需要被缓存。
*
* 可能的值:"local-only","azure-blob-storage","amazon-s3"
*/
"cacheProvider": "azure-blob-storage",
/**
* 设定 "azure-blob-storage" 时使用此配置
*/
"azureBlobStorageConfiguration": {
/**
* (必须) Azure 账户名
*/
"storageAccountName": "example",
/**
* Azure 存储账户中的容器名称
*/
"storageContainerName": "my-container"
/**
* 当其值为 true 时候,允许像 cache 中写入
* 默认为 false
*/
"isCacheWriteAllowed": false
. . .
注意,当设定 "isCacheWriteAllowed": false
时,可以防止普通用户写入容器。(稍后会使用环境变量覆盖此配置,以便 CI 任务能够写入容器。)
用户权限
如果你的仓库并不关心安全性,那么你可以简单地配置容器以允许匿名访问。容器可以通过包含随机字符串的 HTTPS 协议的 URL 来访问,这个 URL 很难背猜到,除非其他人可以在 Git 仓库中查看。这点通过隐蔽性来保障安全。
更安全的组织方式是对于即使只读的情况也要用户认证,Rush 提供了 rush update-cloud-credentials指令来让用户进行更简单的配置:
$ rush update-cloud-credentials --interactive
Rush Multi-Project Build Tool 5.45.6 (unmanaged) - https://rushjs.io
Node.js version is 12.20.1 (LTS)
Starting "rush update-cloud-credentials"
╔═════════════════════════════════════════════════════════════════════════╗
║ To sign in, use a web browser to open the page ║
║ https://microsoft.com/devicelogin and enter the code XAYBQEGRK ║
║ to authenticate. ║
╚═════════════════════════════════════════════════════════════════════════╝
认证信息会被保存在用户的主目录下的 ~/.rush-user/credentials.json
.
CI 设置
通常配置下,用户只有只读权限,缓存通常被一个账号自动更新。例如,每次 PR 被合并到 main
后会执行一个 CI 任务。在上述事例中,"isCacheWriteAllowed": false
是为了防止了用户写入缓存。CI 任务可以通过设置 RUSH_BUILD_CACHE_WRITE_ALLOWED 环境变量来覆盖此配置,并通过 RUSH_BUILD_CACHE_CREDENTIAL 环境变量来提供认证信息。
对于 Azure 而言,必须使用序列化的 SAS 口令来充当一个 query 参数,可以查看此篇文章 来获取更多信息,你可以通过 设置 > 访问密钥 页面来获取你的存储账号的访问密钥。
构建缓存功能依然在开发中,有意见或者建议请联系我们!
一些相关的 GitHub 提问: