You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Github Action npm缓存最简示例失效问题排查与修复

问题根源分析

  1. npm缓存认知偏差
    你混淆了~/.npm(npm下载缓存目录)与项目node_modules目录的作用:~/.npm仅存储npm下载的包压缩包,用于避免重复从网络拉取,但不会自动生成项目的node_modules目录。因此即使恢复了~/.npm缓存,项目目录下依然没有已安装的依赖,npm list报缺失是正常现象——但此时执行npm install应该会跳过下载步骤,直接从缓存解压到node_modules,速度会显著提升。

  2. 缓存未被有效保存
    从deploy任务的缓存恢复输出可见,缓存大小仅195B,说明build任务中保存的~/.npm目录几乎是空的,没有实际的包缓存。原因包括:

    • GitHub Actions runner中npm的默认缓存路径可能不是~/.npm,硬编码路径会导致缓存抓空;
    • 缓存保存条件steps.cache-npm-restore.outputs.cache-hit != 'true'存在逻辑缺陷:若后续build任务命中旧缓存,即使依赖已更新,也不会保存新缓存;
    • deploy任务缺失setup-node步骤,可能导致Node/npm版本与build任务不一致,缓存无法复用。

修复方案

推荐两种方案,按需选择:

方案一:直接缓存项目node_modules目录(最直观,直接复用已安装依赖)

这种方式直接缓存项目内的node_modules,恢复后无需重复执行完整的npm install,适合需要快速恢复项目依赖的场景。

修改后的完整工作流:

name: Build
on:
  push:
    branches: 
      - main
      - fix-*
      - feature-*
  workflow_dispatch:

env:
  nodejs_version: ${{ github.event.inputs.nodejs_version || '20.4.0' }}
  repo_dir: repo
  cache_name: npm-node-modules-cache 
 
jobs:
  build:
    name: Build
    runs-on: ubuntu-latest

    steps:
      - name: Clone Deploy Repository (Latest)
        uses: actions/checkout@v3
        with:
          path: ${{ env.repo_dir }}
 
      - name: Setup NodeJS
        uses: actions/setup-node@v3
        with:
          node-version: ${{ env.nodejs_version }}

      - name: Restore node_modules cache
        uses: actions/cache/restore@v3
        id: cache-node-modules-restore
        with:
          path: ${{ env.repo_dir }}/node_modules
          key: ${{ runner.os }}-node-${{ env.nodejs_version }}-${{ hashFiles(format('{0}/package-lock.json', env.repo_dir)) }}
          restore-keys: |
            ${{ runner.os }}-node-${{ env.nodejs_version }}-

      - name: Install NodeJS modules (cache miss only)
        if: ${{ steps.cache-node-modules-restore.outputs.cache-hit != 'true' }}
        run: | 
          cd $repo_dir && npm install
 
      - name: Save node_modules cache
        if: ${{ steps.cache-node-modules-restore.outputs.cache-hit != 'true' }}
        uses: actions/cache/save@v3
        with:
          path: ${{ env.repo_dir }}/node_modules
          key: ${{ steps.cache-node-modules-restore.outputs.cache-primary-key }}
 
      - name: Build
        run: |
          cd $repo_dir && npm run build
          
      - name: Test
        run: |
          cd $repo_dir && npm run test
      
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    needs: build
  
    steps:
      - name: Clone Deploy Repository (Latest)
        uses: actions/checkout@v3
        with:
          path: ${{ env.repo_dir }}

      - name: Setup NodeJS
        uses: actions/setup-node@v3
        with:
          node-version: ${{ env.nodejs_version }}
          
      - name: Restore node_modules cache
        uses: actions/cache/restore@v3
        id: cache-node-modules-restore
        with:
          path: ${{ env.repo_dir }}/node_modules
          key: ${{ runner.os }}-node-${{ env.nodejs_version }}-${{ hashFiles(format('{0}/package-lock.json', env.repo_dir)) }}
          restore-keys: |
            ${{ runner.os }}-node-${{ env.nodejs_version }}-

      - name: Install NodeJS modules (cache miss only)
        if: ${{ steps.cache-node-modules-restore.outputs.cache-hit != 'true' }}
        run: | 
          cd $repo_dir && npm install
          
      - name: Deploy
        run: |
          cd $repo_dir && npm run deploy

修改要点:

  • 缓存路径改为项目的node_modules目录;
  • 缓存key加入package-lock.json哈希值,确保依赖变更时缓存自动更新;
  • 加入restore-keys,允许匹配同Node版本的旧缓存,提升命中率;
  • deploy任务补充setup-node步骤,保证版本一致性。

方案二:正确缓存npm下载缓存(加速npm install的下载阶段)

若想通过缓存npm下载包来加速安装,需确保缓存路径正确,并加入依赖哈希避免缓存过时:

关键步骤修改:

# 在build和deploy任务中都需要执行以下步骤
- name: Setup NodeJS
  uses: actions/setup-node@v3
  with:
    node-version: ${{ env.nodejs_version }}

- name: Get npm cache directory
  id: npm-cache-dir
  run: |
    echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT

- name: Restore npm cache
  uses: actions/cache/restore@v3
  id: cache-npm-restore
  with:
    path: ${{ steps.npm-cache-dir.outputs.dir }}
    key: ${{ runner.os }}-npm-${{ hashFiles(format('{0}/package-lock.json', env.repo_dir)) }}
    restore-keys: |
      ${{ runner.os }}-npm-

- name: Install NodeJS modules
  run: | 
    cd $repo_dir && npm install --prefer-offline

- name: Save npm cache
  if: ${{ steps.cache-npm-restore.outputs.cache-hit != 'true' }}
  uses: actions/cache/save@v3
  with:
    path: ${{ steps.npm-cache-dir.outputs.dir }}
    key: ${{ steps.cache-npm-restore.outputs.cache-primary-key }}

修改要点:

  • 通过npm config get cache动态获取实际缓存路径,避免硬编码错误;
  • 缓存key加入package-lock.json哈希,确保依赖更新时缓存同步更新;
  • npm install添加--prefer-offline参数,强制优先使用本地缓存;
  • deploy任务必须补充setup-node步骤,保证版本与build任务一致。

额外说明

  • 若使用方案二,恢复缓存后npm list依然会报依赖缺失(因为node_modules未生成),但npm install会跳过下载步骤,直接从缓存解压,速度会明显加快;
  • 两种方案都必须将Node版本、依赖哈希加入缓存key,否则会出现缓存失效或依赖不兼容问题。

内容的提问来源于stack exchange,提问作者vy218

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:27:33