Accueil / Articles

Passer un projet Node de npm à pnpm sans perturber l’équipe

npm vs pnpm en ce qui concerne la structure du disque, les dépendances fantômes et les fichiers de verrouillage, puis une migration d’équipe Node.js utilisant pnpm import, only-allow ainsi qu’un champ packageManager fixé.

Éditeur : REACTAPP.TOP6 min de lecture1317 mots

Sources: Switching from npm to pnpm

Les gestionnaires de paquets décident de la manière dont les dépendances sont enregistrées sur le disque, du fichier de verrou à commiter, ainsi que du niveau de strictesse des importations en cas de problème. Pour de nombreux projets Node, npm reste la valeur par défaut. Les équipes qui gèrent plusieurs répertoires doivent également faire face à un flux constant d’avertissements de sécurité exigeant des mises à jour de version. Dependabot peut automatiser certaines de ces mises à jour ; d’autres nécessitent une intervention manuelle, soit parce que les correctifs transitoires entrent en conflit, soit parce que la solution définitive consiste à remplacer complètement un paquet.

Pour peu de temps après, GitHub a modifié Dependabot afin que les demandes de mise à jour de version non liées à la sécurité attendent trois jours avant d’être traitées. Ce changement de politique est principalement indépendant du choix du gestionnaire de paquets, mais il montre à quel point les mises à jour automatiques étaient devenues problématiques.

Pendant ce temps, les incidents liés à la chaîne d’approvisionnement continuent de figurer dans les gros titres. Des paquets compromis ou vulnérables se trouvent au sein d’applications qui intègrent des ensembles d’icônes, des outils d’authentification et divers utilitaires de tokens, ce qui fait que l’ampleur des risques augmente à chaque lien transitoire. Les alertes de sécurité arrivent rarement une par une : un ordinateur portable qui utilise quelques services verra des avertissements concernant des analyseurs transitoires, des kits d’interface utilisateur et des middlewares d’authentification la même semaine. Les bots automatisés sont utiles lorsque le problème est de nature mécanique, mais ils peinent face à des mises à jour majeures qui réécrivent les API ou lorsque deux dépendances sont en désaccord au sujet d’un même intermédiaire. Dans de tels cas, il est légitime de se demander si l’installateur lui-même peut réduire les risques – en refusant des dépendances fictives, en partageant le contenu sur le disque afin que les audits ne voient qu’une seule copie d’une version, et en ralentissant les publications complètement nouvelles jusqu’à ce que l’écosystème ait eu le temps d’examiner la situation.

L’une des suggestions récurrentes est de passer de npm à pnpm : commandes quotidiennes similaires, un modèle d’installation plus strict, et généralement moins de sollicitation du disque. Les sections suivantes comparent les deux outils sans prétendre déterminer un gagnant absolu — uniquement suffisamment de détails pour décider si le changement en vaut la peine en termes de coûts de migration.

Informations générales sur npm / pnpm

Points de base succincts pour chaque outil :

npm

  • Fourni par défaut avec Node.js en tant que gestionnaire de paquets.
  • Gère l’installation des dépendances ainsi que les scripts du package.json.
  • Les commandes courantes incluent npm install (installation à partir du fichier de verrouillage), npm install <nom> (ajout d’une dépendance), npm run <script>, et npm uninstall <nom>.
  • Génère le fichier package-lock.json.
  • Stocke les paquets dans le répertoire node_modules.

npm fournit également npx, qui exécute un paquet sans l’ajouter au projet ni l’installer de manière globale. Les outils de squelette tels que npx create-vite@latest project-name le téléchargent temporairement, l’exécutent, puis laissent package.json inchangé. La distinction avec npm install est intentionnelle : exécution ponctuelle contre dépendance permanente.

pnpm

  • Un gestionnaire de paquets tiers ayant la même fonction — gérer les dépendances et les scripts — mais mis en œuvre différemment sur le disque.
  • Les commandes familières ont des équivalents proches : pnpm install, pnpm add <name>, pnpm run <script>, pnpm remove <name>.
  • Il utilise généralement moins d’espace disque et termine les installations plus rapidement en stockant chaque version une seule fois.
  • Il restreint les importations à ce que package.json déclare.
  • Utilise pnpm-lock.yaml au lieu de package-lock.json.
  • Applique des paramètres par défaut plus stricts pour les versions récemment publiées (par exemple en retardant leur adoption).
  • L’exécuteur unique similaire à npx est pnpm dlx — utile, par exemple, lors de la création de structures avec create-vite à jour. De nombreux générateurs acceptent également pnpm create. Pour les fichiers binaires déjà présents dans node_modules, pnpm exec est l’exécuteur local.

    Avantages et inconvénients de pnpm

    Les compromis sont tout aussi importants que les slogans :

    • npm copie les paquets dans node_modules de chaque projet, ce qui duplique le contenu entre les répertoires ; pnpm conserve une seule copie adressable par version et établit des liens depuis les projets.
    • Cette organisation réduit généralement l’utilisation du disque et accélère les installations répétées.
    • La résolution historiquement plus simple de npm peut permettre à du code d’exiger un paquet qui n’a jamais été déclaré ; pnpm refuse les importations non déclarées, ce qui réduit la surface d’attaque accidentelle.
    • L’adoption différée par pnpm des versions entièrement nouvelles diminue les chances de télécharger immédiatement une version compromise.
    • Npm a acquis des fonctionnalités similaires au fil du temps, mais plusieurs restent optionnelles plutôt que par défaut.
    • Pnpm nécessite une étape d’installation séparée ; npm est fourni avec Node.
    • Les plugins plus anciens qui supposent la structure de npm peuvent nécessiter des ajustements en raison du lienage plus strict de pnpm.
    • La mémoire musculaire des équipes penche encore en faveur de npm, ce qui peut nécessiter une courte période d’adaptation lors de l’intégration.

    Les différences de disposition des disques se manifestent rapidement sur les exécutants CI qui stockent mal node_modules ainsi que sur les ordinateurs des développeurs qui ont déverrouillé une dizaine d’applications. Le stockage à adresse de contenu signifie que les deuxièmes et troisièmes projets ayant besoin de lodash@4.x créent principalement des liens plutôt qu’un arbre complet supplémentaire. Une visibilité plus stricte des dépendances modifie également le processus de débogage : lorsque l’import échoue parce que le paquet n’a jamais été déclaré, l’échec est visible lors de l’installation ou du contrôle de type, au lieu d’apparaître à l’exécution de manière inattendue, uniquement parce qu’un autre paquet l’a inclus par hasard.

    Passer à pnpm

    Une installation globale minimale se présente comme suit :

    // Installation command (once)
    npm install -g pnpm
    
    // Usage
    pnpm install
    pnpm add [package name]
    pnpm run [script name]
    pnpm remove [package name]
    

    Après la première installation réussie dans un projet, attendez-vous à trouver pnpm-lock.yaml à côté de (et finalement à la place de) package-lock.json.

    D’autres méthodes d’installation existent, y compris des scripts autonomes ; la documentation d’installation de pnpm les liste.

    Migrer un projet npm existant signifie généralement supprimer node_modules et package-lock.json, puis exécuter pnpm install. La plupart des applications fonctionnent correctement ; cependant, des modules natifs complexes ou des résolveurs obsolètes peuvent nécessiter des corrections ponctuelles.

    Pour importer les versions à partir d’un fichier lock existant, exécutez pnpm import. Pour supprimer les éléments résiduels de npm :

    // For macOS/Linux/Git Bash:
    rm -rf node_modules package-lock.json
    
    // For Windows PowerShell:
    rm -Recurse -Force node_modules, package-lock.json
    

    Pour empêcher une exécution accidentelle de npm install par la suite, ajoutez une protection preinstall :

    "scripts": {
      "preinstall": "npx only-allow pnpm"
    }
    

    Ensuite, ajoutez cet outil en tant que dépendance de développement :

    pnpm add -D only-allow
    

    Pour fixer précisément la version de la CLI à utiliser par les collaborateurs, utilisez le champ packageManager (remplacez la chaîne de version selon les besoins) :

    {
      "packageManager": "pnpm@11.22.0"
    }
    

    Ce pin maintient CI et ordinateurs portables sur une même version de CLI ; n’oubliez pas de l’actualiser délibérément lorsque l’équipe met à jour le système.

    Vérifiez et mettez à jour automatiquement avec :

    pnpm --version
    
    pnpm self-update
    

    Si la mise à jour automatique ne fonctionne pas correctement, réinstallez-le globalement avec npm install -g pnpm puis redémarrez la shell.

    Après un changement réussi, vous devriez voir :

    • package-lock.json a disparu.
    • pnpm-lock.yaml est présent.
    • package.json reste inchangé, à l’exception des pins ou scripts que vous avez ajoutés.
    • node_modules a été réécrit sous l’outil de liaison de pnpm (ou recréé via une nouvelle commande pnpm install).
    • Les commandes quotidiennes diffèrent principalement par le nom du outil en tête.
    • Les exécutables ponctuels via pnpm dlx à la place de npx utilisé précédemment.

    La documentation officielle reste la source à consulter pour les cas limites ; les notes ci-dessus suffisent pour évaluer la migration et effectuer un basculement de routine.

    Considérez le premier répertoire migré comme un essai : exécutez l’ensemble de tests, vérifiez que les builds Docker fonctionnent toujours correctement, et assurez-vous que tous les addons natifs se compilent avec le nouveau lienur. Une fois cette étape franchie, l’application du même paramètre packageManager ainsi que de la règle only-allow aux services associés permet de maintenir la cohérence de l’ensemble du système. Si un outil obsolète ne peut vraiment pas supporter la structure de pnpm, isolez-le plutôt que d’abandonner les paramètres par défaut plus stricts ailleurs.