GitHub Actions 如何缓存 npm?前端项目依赖安装速度优化指南
2026-10-12 2 0
为什么 GitHub Actions 需要缓存 npm?
在使用 GitHub Actions 构建 Vue、React、Next.js 等前端项目时,工作流通常需要执行 npm ci 安装依赖。每次运行新的 CI 任务,运行环境往往都是临时创建的,之前下载的 npm 包不会自动保留。
项目依赖较多时,安装过程可能占用数分钟。启用缓存后,GitHub Actions 可以复用之前保存的 npm 下载缓存,减少重复从注册表下载软件包的时间。
需要注意,npm 缓存主要保存下载的包数据,并不等于缓存整个 node_modules 目录。使用缓存后,npm ci 仍然会根据锁文件安装依赖,但通常能减少网络下载开销。
使用 actions/setup-node 配置 npm 缓存
最简单的方式是使用官方维护的 actions/setup-node,通过 cache: 'npm' 开启 npm 缓存。
在项目中创建 .github/workflows/ci.yml:
name: Frontend CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
这里有三个关键配置。
- node-version 指定 Node.js 版本,应尽量与本地开发和生产构建环境保持一致。示例使用 Node.js 22,实际项目可以根据自身要求调整。
- cache: npm 让 setup-node 自动配置 npm 缓存。默认情况下,缓存键会参考依赖锁文件的哈希值,锁文件变化后会生成新的缓存键。
- npm ci 根据 package-lock.json 安装依赖,适合持续集成环境。它要求锁文件与 package.json 保持一致,并会清理已有的 node_modules,避免残留依赖影响构建结果。
如何避免 npm 缓存失效?
npm 缓存能否命中,与依赖锁文件密切相关。以下几种情况值得关注。
1. 提交 package-lock.json
使用 npm 管理依赖时,应将 package-lock.json 纳入版本控制。如果只提交 package.json,不同环境可能解析出不同的依赖版本,也会影响缓存策略的稳定性。
2. 不要频繁修改锁文件
更新依赖版本会改变锁文件哈希,导致工作流使用新的缓存键。这属于正常行为,可以避免新旧依赖混用。没有必要为了追求缓存命中而忽略真实的依赖更新。
3. 检查缓存是否命中
打开 GitHub 仓库的 Actions 页面,查看对应工作流日志。如果缓存成功恢复,通常能看到缓存恢复相关信息。若每次都重新下载依赖,应检查锁文件路径、Node.js 配置以及工作流运行环境是否一致。
4. 不要把 node_modules 当作 npm 下载缓存
setup-node 的 npm 缓存机制缓存的是 npm 的下载缓存目录,而不是整个 node_modules。如果希望直接复用已安装的依赖,需要额外设计目录缓存和失效策略,但通常没有必要,尤其是在使用 npm ci 的项目中。
如何进一步优化前端项目构建速度?
启用 npm 缓存后,还可以从以下方面减少 CI 时间。
- 使用 npm ci: 避免依赖版本漂移,保持安装过程可复现。
- 减少不必要的依赖: 清理未使用的包,检查重复依赖,降低下载和安装成本。
- 合理安排工作流: 将代码检查、测试和构建步骤按需拆分,避免每次提交都执行不必要的任务。
- 缓存构建工具数据: 对于 Vite、Next.js 等工具,可以评估是否缓存其构建缓存目录,但必须确认缓存键和恢复逻辑正确。
- 避免重复安装依赖: 如果一个 job 中有多个连续步骤需要使用同一套依赖,可以在安装一次后共享当前工作目录,不要在每个步骤中重新执行 npm ci。
常见问题
开启 npm 缓存后,为什么首次运行没有明显提速?
首次运行通常需要下载依赖并建立缓存,因此提升有限。后续工作流在缓存命中后,才更容易体现速度改善。
package-lock.json 更新后,缓存会丢失吗?
旧缓存不会因此立即消失,但新锁文件通常对应新的缓存键。旧缓存可能仍然存在,只是当前工作流不再使用它作为首选缓存。
npm 缓存和 node_modules 缓存应该选哪个?
大多数使用 npm ci 的 GitHub Actions 项目,优先采用 actions/setup-node 的 npm 缓存即可。它配置简单,能够减少重复下载依赖的成本,也不容易因残留文件影响安装结果。
总结
优化 GitHub Actions 中的 npm 安装速度,可以先使用 actions/setup-node 的 cache: npm,再配合 npm ci 和版本控制中的 package-lock.json。这种方式配置简单,适合大多数 Vue、React 和其他 Node.js 前端项目。完成配置后,可以对比缓存启用前后的 Actions 日志,观察依赖安装时间与缓存命中情况,再决定是否需要进一步缓存构建产物。