dependency-upgrade

Par wshobson · agents

Gérez les mises à niveau majeures de versions de dépendances avec une analyse de compatibilité, un déploiement progressif et des tests complets. À utiliser lors de la mise à niveau de versions de framework, de la mise à jour de dépendances majeures ou de la gestion des changements cassants dans les bibliothèques.

npx skills add https://github.com/wshobson/agents --skill dependency-upgrade

Mise à jour des dépendances

Maîtrisez les mises à jour majeures de dépendances, l'analyse de compatibilité, les stratégies de mise à niveau échelonnées et les approches de test complètes.

Quand utiliser cette compétence

  • Mettre à niveau les versions majeures de frameworks
  • Mettre à jour les dépendances vulnérables à la sécurité
  • Moderniser les dépendances héritées
  • Résoudre les conflits de dépendances
  • Planifier les chemins de mise à niveau progressifs
  • Tester les matrices de compatibilité
  • Automatiser les mises à jour de dépendances

Révision du versionnage sémantique

MAJOR.MINOR.PATCH (p. ex., 2.3.1)

MAJOR : changements incompatibles
MINOR : nouvelles fonctionnalités, rétrocompatible
PATCH : corrections de bogues, rétrocompatible

^2.3.1 = >=2.3.1 <3.0.0 (mises à jour mineures)
~2.3.1 = >=2.3.1 <2.4.0 (mises à jour de patch)
2.3.1 = version exacte

Analyse des dépendances

Audit des dépendances

# npm
npm outdated
npm audit
npm audit fix

# yarn
yarn outdated
yarn audit

# Vérifier les mises à jour majeures
npx npm-check-updates
npx npm-check-updates -u  # Mettre à jour package.json

Analyser l'arborescence des dépendances

# Voir pourquoi un package est installé
npm ls package-name
yarn why package-name

# Trouver les packages en doublon
npm dedupe
yarn dedupe

# Visualiser les dépendances
npx madge --image graph.png src/

Matrice de compatibilité

// compatibility-matrix.js
const compatibilityMatrix = {
  react: {
    "16.x": {
      "react-dom": "^16.0.0",
      "react-router-dom": "^5.0.0",
      "@testing-library/react": "^11.0.0",
    },
    "17.x": {
      "react-dom": "^17.0.0",
      "react-router-dom": "^5.0.0 || ^6.0.0",
      "@testing-library/react": "^12.0.0",
    },
    "18.x": {
      "react-dom": "^18.0.0",
      "react-router-dom": "^6.0.0",
      "@testing-library/react": "^13.0.0",
    },
  },
};

function checkCompatibility(packages) {
  // Valider les versions des packages par rapport à la matrice
}

Stratégie de mise à niveau échelonnée

Phase 1 : Planification

# 1. Identifier les versions actuelles
npm list --depth=0

# 2. Vérifier les changements incompatibles
# Lire CHANGELOG.md et MIGRATION.md

# 3. Créer un plan de mise à niveau
echo "Ordre de mise à niveau :
1. TypeScript
2. React
3. React Router
4. Bibliothèques de test
5. Outils de build" > UPGRADE_PLAN.md

Phase 2 : Mises à jour progressives

# Ne pas tout mettre à niveau d'un coup !

# Étape 1 : Mettre à niveau TypeScript
npm install typescript@latest

# Tester
npm run test
npm run build

# Étape 2 : Mettre à niveau React (une version majeure à la fois)
npm install react@17 react-dom@17

# Tester à nouveau
npm run test

# Étape 3 : Continuer avec d'autres packages
npm install react-router-dom@6

# Et ainsi de suite...

Phase 3 : Validation

// tests/compatibility.test.js
describe("Compatibilité des dépendances", () => {
  it("devrait avoir des versions React compatibles", () => {
    const reactVersion = require("react/package.json").version;
    const reactDomVersion = require("react-dom/package.json").version;

    expect(reactVersion).toBe(reactDomVersion);
  });

  it("ne devrait pas avoir d'avertissements de peer dependency", () => {
    // Exécuter npm ls et vérifier les avertissements
  });
});

Gestion des changements incompatibles

Identifier les changements incompatibles

# Vérifier le changelog directement
curl https://raw.githubusercontent.com/facebook/react/master/CHANGELOG.md

Codemod pour les corrections automatisées

# Exécuter jscodeshift avec l'URL de transformation
npx jscodeshift -t <transform-url> <path>

# Exemple : Renommer les méthodes de cycle de vie non sûres
npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/rename-unsafe-lifecycles.js src/

# Pour les fichiers TypeScript
npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/rename-unsafe-lifecycles.js --parser=tsx src/

# Exécution à blanc pour prévisualiser les modifications
npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/rename-unsafe-lifecycles.js --dry src/

Script de migration personnalisé

// migration-script.js
const fs = require("fs");
const glob = require("glob");

glob("src/**/*.tsx", (err, files) => {
  files.forEach((file) => {
    let content = fs.readFileSync(file, "utf8");

    // Remplacer l'ancienne API par la nouvelle API
    content = content.replace(
      /componentWillMount/g,
      "UNSAFE_componentWillMount",
    );

    // Mettre à jour les imports
    content = content.replace(
      /import { Component } from 'react'/g,
      "import React, { Component } from 'react'",
    );

    fs.writeFileSync(file, content);
  });
});

Stratégie de test

Tests unitaires

// Vérifier que les tests réussissent avant et après la mise à niveau
npm run test

// Mettre à jour les utilitaires de test si nécessaire
npm install @testing-library/react@latest

Tests d'intégration

// tests/integration/app.test.js
describe("Intégration de l'app", () => {
  it("devrait être rendu sans crash", () => {
    render(<App />);
  });

  it("devrait gérer la navigation", () => {
    const { getByText } = render(<App />);
    fireEvent.click(getByText("Navigate"));
    expect(screen.getByText("New Page")).toBeInTheDocument();
  });
});

Tests de régression visuelle

// visual-regression.test.js
describe("Régression visuelle", () => {
  it("devrait correspondre au snapshot", () => {
    const { container } = render(<App />);
    expect(container.firstChild).toMatchSnapshot();
  });
});

Tests E2E

// cypress/e2e/app.cy.js
describe("Tests E2E", () => {
  it("devrait compléter le flux utilisateur", () => {
    cy.visit("/");
    cy.get('[data-testid="login"]').click();
    cy.get('input[name="email"]').type("user@example.com");
    cy.get('button[type="submit"]').click();
    cy.url().should("include", "/dashboard");
  });
});

Mises à jour automatisées des dépendances

Configuration de Renovate

// renovate.json
{
  "extends": ["config:base"],
  "packageRules": [
    {
      "matchUpdateTypes": ["minor", "patch"],
      "automerge": true
    },
    {
      "matchUpdateTypes": ["major"],
      "automerge": false,
      "labels": ["major-update"]
    }
  ],
  "schedule": ["before 3am on Monday"],
  "timezone": "America/New_York"
}

Configuration de Dependabot

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5
    reviewers:
      - "team-leads"
    commit-message:
      prefix: "chore"
      include: "scope"

Plan de restauration

// rollback.sh
#!/bin/bash

# Enregistrer l'état actuel
git stash
git checkout -b upgrade-branch

# Tenter la mise à niveau
npm install package@latest

# Exécuter les tests
if npm run test; then
  echo "Mise à niveau réussie"
  git add package.json package-lock.json
  git commit -m "chore: upgrade package"
else
  echo "Mise à niveau échouée, restauration"
  git checkout main
  git branch -D upgrade-branch
  npm install  # Restaurer à partir de package-lock.json
fi

Modèles de mise à niveau courants

Gestion du fichier de verrouillage

# npm
npm install --package-lock-only  # Mettre à jour le fichier de verrouillage uniquement
npm ci  # Installation complète à partir du fichier de verrouillage

# yarn
yarn install --frozen-lockfile  # Mode CI
yarn upgrade-interactive  # Mises à niveau interactives

Résolution des peer dependencies

# npm 7+ : peer dependencies stricts
npm install --legacy-peer-deps  # Ignorer les peer deps

# npm 8+ : remplacer les peer dependencies
npm install --force

Mises à niveau d'espace de travail

# Mettre à jour tous les packages de l'espace de travail
npm install --workspaces

# Mettre à jour un espace de travail spécifique
npm install package@latest --workspace=packages/app

Skills similaires