GitHub Actions执行Jest分片测试时NPM依赖缓存报错问题
问题根因
配置错了两个地方,直接导致跳过安装步骤后测试运行失败:
- 缓存路径不对:现在的配置只缓存了npm的全局下载目录
~/.npm,这里面存的都是下载好的依赖压缩包,根本不是项目运行要用的、已经解压好的node_modules目录。CI每次启动都是全新容器,项目根目录默认没有node_modules,跳过安装步骤必然会报找不到依赖的错误。 - 对npm缓存的逻辑理解有偏差:
npm ci本身就会自动复用~/.npm里的缓存包,不需要重复走网络下载,但就算命中全局缓存,npm ci还是要执行解压、写入node_modules、链接可执行文件的操作,直接跳过整个安装步骤,不可能生成可用的依赖环境。
修正方案
有两种可行方案,根据项目实际情况选择即可:
方案1:直接缓存node_modules目录(速度最快,推荐)
把安装完成的node_modules直接纳入缓存,命中缓存时可以完全跳过安装步骤,执行效率最高。注意缓存key要绑定操作系统、Node版本、package-lock.json的哈希值,避免跨环境用错缓存导致依赖不兼容。
修正后的完整工作流配置:
run_tests: runs-on: [self-hosted] name: Run Tests continue-on-error: false strategy: matrix: shard: [1, 2, 3, 4] steps: - name: Checkout Codebase uses: actions/checkout-action@v2 - name: Use Node v14.15.1 uses: actions/setup-node@v1 with: node-version: 14.15.1 - name: Cache NPM dependencies id: npmCacheStep uses: actions/cache@v2 with: path: | node_modules ~/.npm key: ${{ runner.OS }}-node-14.15.1-npm-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.OS }}-node-14.15.1-npm- - name: Install Dependencies if: steps.npmCacheStep.outputs.cache-hit != 'true' run: npm ci - name: Run tests run: npm run test -- --colors --coverage --shard=${{ matrix.shard }}/${{ strategy.job-total }}
注意:如果项目里存在带原生C++扩展的依赖(比如node-sass、sqlite3这类),要保证所有self-hosted运行器的操作系统、CPU架构完全一致,不然缓存里的二进制文件换机器可能无法正常运行,这种情况选方案2更稳妥。
方案2:只缓存npm全局下载目录(兼容性最好)
如果担心原生依赖跨运行器出兼容问题,可以只缓存~/.npm全局下载目录,不要跳过npm ci执行步骤。这种模式下npm ci不需要从远程仓库下载依赖包,直接读取本地缓存的压缩包执行安装,速度比无缓存快70%以上,同时每次安装都会适配当前运行器的环境,不会出现二进制兼容问题。
对应调整点:
- 缓存path保留原来的
~/.npm即可 - 删除Install Dependencies步骤的
if判断,所有测试分片都正常执行npm ci命令
两种方案都能实现避免重复下载依赖、加速CI流程的效果,方案1执行速度更快,方案2稳定性更高,按需选择即可。
内容的提问来源于stack exchange,提问作者Probosckie
相关产品推荐
相关产品推荐

