setup-node还原yarn缓存后yarn --frozen-lockfile仍耗时原因问询
问题原因分析
actions/setup-node内置的yarn缓存仅缓存yarn的全局依赖下载缓存目录(即你看到的/home/runner/.cache/yarn/v6),这里存储的是所有下载过的npm包的压缩归档文件,并没有存储项目内已经完成解压、依赖链接、原生模块编译的node_modules目录。- 即便全局缓存命中,yarn执行
--frozen-lockfile时仍然需要完成以下流程:解析锁定文件的依赖树、从全局缓存中提取对应包的压缩包到项目目录、处理包之间的软链接、执行部分包的原生编译脚本,这些流程在依赖数量较多的项目中会消耗大量时间,也就是你看到的44秒耗时的来源。 - 你自定义缓存
node_modules目录后,yarn检测到所有依赖已经按照锁定文件的要求完成安装,只会做轻量的一致性校验,所以3秒就能完成执行。
最优配置方案(兼顾正确性与构建速度)
推荐同时使用两级缓存,配合yarn参数优化,在保证构建正确性的前提下最大化速度:
1. 合理设计node_modules缓存规则
缓存key需要覆盖所有可能影响node_modules兼容性的变量,避免缓存脏数据导致构建异常:
- name: 缓存项目node_modules uses: actions/cache@v3 with: path: '**/node_modules' # 缓存key包含操作系统、node版本、yarn.lock哈希,三者任意变化都会生成新缓存 key: ${{ runner.os }}-node${{ matrix.node-version }}-modules-${{ hashFiles('**/yarn.lock') }} # fallback规则:当yarn.lock变更时,复用同系统同node版本的最近缓存,只需增量安装变化的依赖,无需全量重新安装 restore-keys: | ${{ runner.os }}-node${{ matrix.node-version }}-modules-
2. 保留setup-node的全局yarn缓存
全局缓存可以作为node_modules缓存未命中时的降级,避免所有包都要从npm registry重新下载:
- uses: actions/setup-node@v3 with: node-version: '14.15.5' cache: 'yarn'
3. 优化yarn执行参数
执行安装时添加--prefer-offline参数,优先使用本地缓存的包,跳过向registry发起的版本查询请求:
yarn install --frozen-lockfile --prefer-offline
正确性保障说明
只要缓存key包含了操作系统、node版本、yarn.lock哈希三个变量,就能保证缓存的node_modules和你重新全量执行yarn安装的结果完全一致,不会出现依赖版本错误、兼容性问题:
- 操作系统变化:不同系统的原生编译模块不兼容,key变化自动重建缓存
- node版本变化:部分原生依赖和node版本强绑定,key变化自动重建缓存
- yarn.lock变化:依赖版本/结构变化,key变化自动重建缓存
内容的提问来源于stack exchange,提问作者Adam Jenkins
相关产品推荐
相关产品推荐

