Les projets Node.js ont souvent des centaines de dépendances. Sans cache,
chaque npm ci télécharge tout depuis le registre npm — 30 à 60 secondes
minimum. Avec le cache, c'est réduit à quelques secondes.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Activer le cache intégré de
setup-nodepour npm, pnpm et yarn - Configurer
actions/cachequand vous avez besoin de contrôle - Cacher les builds Next.js, Turborepo et ESLint
- Gérer un monorepo à workspaces
- Éviter les pièges du cache de
node_moduleset de pnpm
Cache intégré avec setup-node
Section intitulée « Cache intégré avec setup-node »La méthode la plus simple :
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'npm' # Détecte automatiquement package-lock.json
- run: npm ciDétection automatique du gestionnaire
Section intitulée « Détection automatique du gestionnaire »setup-node détecte le gestionnaire de paquets selon les fichiers présents :
| Fichier présent | Gestionnaire détecté |
|---|---|
package-lock.json | npm |
pnpm-lock.yaml | pnpm |
yarn.lock | yarn |
# Pour pnpm- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'pnpm'
- run: pnpm install
# Pour yarn- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'yarn'
- run: yarn install --frozen-lockfileCache manuel
Section intitulée « Cache manuel »Pour plus de contrôle ou des cas spécifiques :
Cache npm
Section intitulée « Cache npm »- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20'
- name: Get npm cache directory id: npm-cache-dir shell: bash run: echo "dir=$(npm config get cache)" >> "$GITHUB_OUTPUT"
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: ${{ steps.npm-cache-dir.outputs.dir }} key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} restore-keys: | npm-${{ runner.os }}-
- run: npm ciCache pnpm
Section intitulée « Cache pnpm »- uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 with: version: 9
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'pnpm'
- run: pnpm install --frozen-lockfileCache yarn (v3+)
Section intitulée « Cache yarn (v3+) »- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'yarn'
- run: yarn install --immutableCache du node_modules
Section intitulée « Cache du node_modules »Pour des gains maximum, cachez directement node_modules :
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20'
- name: Cache node_modules uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 id: cache-node-modules with: path: node_modules key: node-modules-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
- name: Install dependencies if: steps.cache-node-modules.outputs.cache-hit != 'true' run: npm ciCache des builds
Section intitulée « Cache des builds »Au-delà des dépendances, les outils de build maintiennent leur propre cache sur disque. Le préserver d'un run à l'autre accélère franchement la compilation.
Cache Next.js
Section intitulée « Cache Next.js »- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: | .next/cache key: nextjs-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} restore-keys: | nextjs-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}- nextjs-${{ runner.os }}-Cache Turborepo
Section intitulée « Cache Turborepo »- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: .turbo key: turbo-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}-${{ github.sha }} restore-keys: | turbo-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}- turbo-${{ runner.os }}-Cache ESLint
Section intitulée « Cache ESLint »- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: .eslintcache key: eslint-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
- run: npm run lint -- --cacheWorkflow complet
Section intitulée « Workflow complet »name: Node.js CI
on: push: branches: [main] pull_request: branches: [main]
# Aucun droit par défaut : le job demande le minimumpermissions: {}
jobs: build: runs-on: ubuntu-24.04 permissions: contents: read
strategy: matrix: node-version: [18, 20, 22]
steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false
- name: Setup Node.js ${{ matrix.node-version }} uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'npm'
- name: Install dependencies run: npm ci
- name: Lint run: npm run lint
- name: Test run: npm test
- name: Build run: npm run buildMonorepo avec workspaces
Section intitulée « Monorepo avec workspaces »- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'npm' cache-dependency-path: '**/package-lock.json' # Tous les lockfiles
- run: npm ci --workspacesAvec pnpm workspaces
Section intitulée « Avec pnpm workspaces »- uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 with: version: 9
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'pnpm'
- run: pnpm install --frozen-lockfile- run: pnpm -r build # Build tous les packagesOptimisations avancées
Section intitulée « Optimisations avancées »Certains cas particuliers — modules natifs, tests end-to-end — ont leurs propres caches à connaître.
Packages natifs (node-gyp)
Section intitulée « Packages natifs (node-gyp) »Pour les packages avec compilation native (sharp, bcrypt, etc.) :
- name: Cache native modules uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: | ~/.npm ~/.node-gyp key: native-${{ runner.os }}-node${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }}- name: Cache Cypress uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: ~/.cache/Cypress key: cypress-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}Erreurs courantes
Section intitulée « Erreurs courantes »Deux problèmes reviennent souvent avec le cache Node.js. Voici comment les reconnaître et les corriger.
Cache invalide sur npm ci
Section intitulée « Cache invalide sur npm ci »npm ERR! `npm ci` can only install packages when your package.json and package-lock.json are in syncLa clé de cache doit inclure le hash du lockfile :
# ✅ Correctkey: npm-${{ hashFiles('**/package-lock.json') }}pnpm : store non trouvé
Section intitulée « pnpm : store non trouvé »# Assurez-vous d'installer pnpm avant setup-node- uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: cache: 'pnpm'À retenir
Section intitulée « À retenir »- Le cache intégré de
setup-node(cache: 'npm'/'pnpm'/'yarn') couvre la majorité des projets. - Pour pnpm, installez
pnpm/action-setupavantsetup-node, sinon le store reste introuvable. - Cacher
node_modulesdirectement est plus rapide mais fragile : les scriptspostinstallsont sautés sur un cache hit. - Cachez les builds (
.next/cache,.turbo,.eslintcache) en plus des dépendances pour le gain maximal. - En monorepo,
cache-dependency-path: '**/package-lock.json'couvre tous les workspaces.