Skip to main content

Qu’est-ce que package-lock.json et comment fonctionnent les fichiers de verrouillage pour Yarn et npm ?

Écrit par
Package Lock Files blog

14 mars 2019

0 minutes de lecture

Qu’est-ce que package-lock.json ?

Dans cet article, nous abordons le fichier de verrouillage des packages de npm, `package-lock.json`, ainsi que celui de Yarn, `_yarn.lock`. Les fichiers de verrouillage des packages constituent un inventaire détaillé des dépendances d’un projet. Ils spécifient les versions exactes des dépendances à installer, ainsi que celles de leurs dépendances, et ainsi de suite, afin de couvrir l’ensemble de l’arborescence des dépendances.

Un fichier de verrouillage des packages est créé dans un projet lors de la première installation de ses dépendances. L’ensemble de l’arborescence des dépendances est alors calculé et enregistré dans ce fichier, avec des métadonnées sur chacune d’elles, par exemple :

  • La version du package à installer

  • Une empreinte d’intégrité qui permet de vérifier que le package n’a pas été modifié

  • L’emplacement du registre d’où le package a été récupéré et où il devra l’être lors des prochaines installations

Éditeur de code affichant une entrée package-lock pour la dépendance acorn, avec la version 5.7.3, l’URL du registre, le hachage d’intégrité et l’indicateur dev.

Pourquoi utiliser des fichiers de verrouillage ?

Les fichiers de verrouillage servent à fixer, ou « verrouiller », toutes les versions de l’arborescence des dépendances au moment de leur création. Pourquoi est-il important d’utiliser un fichier de verrouillage des packages et d’en verrouiller les versions ?

Sans fichier de verrouillage des packages, un gestionnaire de packages comme Yarn ou npm sélectionne en temps réel la version la plus récente d’un package lors de l’installation des dépendances, au lieu de celle initialement prévue pour ce package.

Schéma du versionnage sémantique montrant les composants majeur, mineur et correctif.

Par exemple, si un projet dépend de dummy-pkg: ^1.0.0, deux installations effectuées à des moments différents peuvent récupérer des versions différentes de dummy-pkg. Cela peut arriver si une personne installe `dummy-pkg` et récupère la version 1.0.0, puis que le package publie une nouvelle version, 1.0.1, quelques minutes plus tard. Une autre personne qui installe alors les dépendances du projet récupérera `dummy-pkg` en version 1.0.1 plutôt qu’en version 1.0.0.

Les fichiers de verrouillage garantissent des installations identiques et reproductibles dans toute l’arborescence des dépendances, d’un utilisateur à l’autre — par exemple, entre les membres d’une même équipe — et d’un système à l’autre, notamment lors d’une compilation CI.

Comment fonctionnent les fichiers de verrouillage ?

Dans la plupart des projets de l’écosystème npm, on trouve deux types de fichiers de verrouillage des packages :

  • Le fichier yarn.lock de Yarn

  • Le fichier package-lock.json de npm

Rien de tel qu’un bon organigramme pour expliquer comment ces deux fichiers sont utilisés :

Schéma illustrant comment les fichiers de verrouillage de npm et Yarn guident l’installation des packages, leur publication, le contrôle des versions et la reproductibilité des builds.

Cette illustration utilise le fichier package-lock.json de npm, mais vous pouvez le remplacer partout par yarn.lock. La seule exception concerne le processus de publication du client npm : il n’ignore pas automatiquement un fichier yarn.lock, qui sera donc inclus dans l’archive tarball du package, sauf si vous l’excluez explicitement dans le fichier .npmignore. Cependant, comme le montre la partie gauche de l’illustration, même si ce fichier de verrouillage fait partie du package, il n’est pas utilisé par l’utilisateur final qui consomme la bibliothèque.

Yarn et npm ne tiennent jamais compte des fichiers de verrouillage des dépendances indirectes : les gestionnaires de packages les ignorent complètement. Seul le projet de niveau supérieur, dans lequel une installation est lancée, est pris en compte. Son arborescence complète des dépendances est alors déterminée à partir d’un fichier de verrouillage, que le gestionnaire de packages utilise comme manifeste des dépendances.

Fichiers de verrouillage shrinkwrap

Ne jamais dire jamais. Il existe un cas où un fichier de verrouillage spécial est pris en compte, même pour les dépendances indirectes. Le fichier npm-shrinkwrap.json fixe l’arborescence des dépendances comme les autres fichiers de verrouillage, mais le processus de publication de npm l’envoie également au registre. Plus important encore, lorsque les utilisateurs finaux intègrent la bibliothèque à une application classique et lancent une installation npm, le fichier shrinkwrap de la bibliothèque détermine les versions à récupérer, à la place de la résolution semver qui intervient habituellement pendant l’installation.

Il est important de noter que Yarn et npm ne gèrent pas de la même façon les packages contenant un fichier npm-shrinkwrap.json :

  • npm place toujours les dépendances spécifiées dans npm-shrinkwrap.json dans le dossier node_modules/ propre au package et ne tente pas de les remonter dans l’arborescence.

  • Yarn ne tient jamais compte de npm-shrinkwrap.json et l’ignore complètement.

À quoi sert un fichier shrinkwrap ? Il permet aux responsables de la maintenance d’une bibliothèque de fixer et de sélectionner les dépendances de leur bibliothèque afin de livrer des versions connues. Il nécessite toutefois une maintenance rigoureuse de toute l’arborescence des dépendances. De plus, si vous utilisez un fichier shrinkwrap, aucun autre fichier de verrouillage n’est nécessaire dans le contrôle de version. Le projet bien connu hapijs en est un bon exemple.

Fichiers de verrouillage désynchronisés

Les fichiers de verrouillage sont créés lorsque les développeurs interviennent sur un projet, par exemple en ajoutant une dépendance ou en installant les dépendances d’un clone vierge du projet. Il est courant d’ajouter ou de supprimer des dépendances au cours du développement. Mais que se passe-t-il si vous modifiez package.json et oubliez de valider le fichier de verrouillage correspondant ?

Si le fichier package.json d’un projet n’est pas synchronisé avec son fichier de verrouillage, des gestionnaires de packages comme npm et Yarn tentent de réconcilier les différences et de générer un nouveau manifeste. Cela peut sembler utile, mais risque en réalité de poser problème si cela se produit pendant l’intégration continue (CI).

Si l’étape de compilation ne signale pas l’écart entre le fichier de verrouillage et les dépendances déclarées dans package.json, les artefacts compilés ou testés risquent d’utiliser la version disponible au moment de la compilation, ce qui annule tous les avantages d’un fichier de verrouillage.

Il est donc recommandé de configurer les gestionnaires de packages pour qu’ils utilisent le fichier de verrouillage lors de l’installation des dépendances, par exemple :

$ yarn install --frozen-lock file
$ npm ci

Fichiers de verrouillage pour les applications et les bibliothèques

Les avis divergent sur l’utilisation des fichiers de verrouillage, selon qu’il s’agit du projet d’une application principale ou d’une bibliothèque destinée à être utilisée par une application ou une autre bibliothèque.

Les projets d’applications doivent utiliser un fichier de verrouillage, c’est un point qui fait consensus. Pour les bibliothèques, c’est moins évident. Pourquoi ?

L’argument principal contre l’utilisation de fichiers de verrouillage dans les bibliothèques est qu’elle crée des écarts entre les dépendances réellement récupérées par les utilisateurs de la bibliothèque. Les responsables de la maintenance des packages risquent alors de ne pas détecter les régressions de compilation.

Cependant, sans fichier de verrouillage, les dépendances ne sont résolues qu’au moment de l’installation et seront probablement différentes pour les responsables de la maintenance et les utilisateurs, de toute façon.

À mon avis, les projets de bibliothèques ne font pas exception et devraient inclure un fichier de verrouillage pour faciliter la collaboration entre les membres de l’équipe et garantir des compilations reproductibles.

Je vous propose toutefois une amélioration : si vous craignez vraiment que les dépendances de votre bibliothèque posent problème à vos utilisateurs, vous pouvez mettre en place deux compilations CI différentes pour détecter ces problèmes :

  • L’une utilise le fichier de verrouillage du projet, comme toute configuration de compilation classique.

  • L’autre ignore le fichier de verrouillage du projet et résout les dépendances en fonction de leurs dernières versions semver.

Cette approche vous permet de conserver des compilations reproductibles et des dépendances cohérentes pendant le développement, tout en aidant les développeurs à détecter les changements susceptibles de casser la compatibilité pour les utilisateurs de votre bibliothèque. Et tout cela en préservant la satisfaction de toute l’équipe.

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis de capture du drapeau en regardant à la demande notre atelier virtuel d’initiation.

Publié dans:

Lire la suite

Live Stream

Les agents de remédiation démystifiés : pourquoi corriger vaut mieux que détecter

Découvrez comment l’agent de remédiation de Snyk utilise les renseignements de sécurité, l’analyse de la cassabilité et la validation pour transformer les vulnérabilités en pull requests prêtes à être fusionnées.

feature insights context
Blog

Dans les coulisses de la compromission de keyv sur npm : malware preinstall, provenance fiable et hooks d’IDE

keyv 6.0.0 et dix versions npm associées ont diffusé un malware à l’installation. Découvrez les versions touchées, les empreintes, les étapes de détection et l’ordre de remédiation recommandé.

feature ai ide dark
Blog

Premiers aperçus d’Evo Agentic AppSec : remédiation agentique et défense contre le code malveillant

Découvrez les premières capacités d’Agentic AppSec de Snyk : un agent de remédiation autonome qui corrige les vulnérabilités et une défense contre le code malveillant qui bloque les packages à risque avant leur mise en production.