返回

GitHub Actions 如何缓存 npm?前端项目依赖安装速度优化指南

2026-10-12 GitHub Actions npm 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 日志,观察依赖安装时间与缓存命中情况,再决定是否需要进一步缓存构建产物。

顶部