Dépendances
Qu'est-ce qu'un lockfile ?
Un lockfile enregistre la version exacte de chaque dépendance résolue par un gestionnaire de paquets, directe ou transitive, pour que l'installation suivante obtienne le même arbre. C'est le meilleur plan dont vous disposez pour un build. Ce n'est pas un enregistrement de ce que le build a réellement utilisé.
Mis à jour le
Ce qu'enregistre un lockfile
Votre manifeste, tel que package.json ou pyproject.toml, liste les paquets dont vous dépendez
et les plages de versions que vous acceptez. Le gestionnaire de paquets transforme ces plages en versions exactes pour tout l'arbre,
dépendances transitives comprises, et écrit le résultat dans le lockfile.
La documentation de npm présente package-lock.json comme décrivant « l'arbre exact qui a été généré,
de sorte que les installations suivantes puissent générer des arbres identiques ».
Une entrée de package-lock.json se présente ainsi :
"node_modules/raw-body": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
"integrity": "sha512-...",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.6.3",
"unpipe": "1.0.0"
}
}
- version est la version exacte choisie.
- resolved indique d'où elle a été récupérée : une URL de tarball d'un registre, ou une URL git avec un commit.
- integrity est un hash Subresource Integrity du tarball : un téléchargement altéré échoue donc.
- dependencies liste ses propres dépendances : c'est ainsi que l'arbre, ou graphe de dépendances, est assemblé.
Les lockfiles par gestionnaire de paquets
| Gestionnaire de paquets | Lockfile | Installer sans le modifier |
|---|---|---|
| npm | package-lock.json | npm ci |
| Yarn (Berry) | yarn.lock | yarn install --immutable |
| pnpm | pnpm-lock.yaml | pnpm install --frozen-lockfile |
| uv | uv.lock | uv sync --locked |
| Poetry | poetry.lock | poetry install |
| Cargo | Cargo.lock | cargo build --locked |
| Bundler | Gemfile.lock | bundle config set frozen true |
| Go modules | Versions de go.mod et sommes de contrôle de go.sum |
Par défaut, les commandes de build ne mettent pas à jour go.mod |
Avec pip seul, le substitut habituel est un requirements.txt avec des versions exactes. Il épingle ce qu'il liste,
mais tout ce qu'il omet est résolu à nouveau à chaque installation.
Utilisez des installations figées en CI
Un lockfile n'aide que si le build installe à partir de lui. Un simple npm install peut mettre à jour
package-lock.json lorsqu'il ne correspond plus à package.json : le build résout alors discrètement un
nouvel arbre. npm ci est conçu pour les environnements automatisés :
- Il exige un
package-lock.jsonou unnpm-shrinkwrap.json. - Si le lockfile et
package.jsondivergent, il s'arrête avec une erreur au lieu de mettre à jour le lockfile. - Il commence par supprimer tout
node_modulesexistant. - Il n'écrit jamais dans
package.jsonni dans le lockfile.
Les autres commandes du tableau ci-dessus font le même travail pour leurs gestionnaires de paquets.
Applications et bibliothèques
Commitez le lockfile pour les applications et tout ce que vous déployez. Pour les bibliothèques, il ne verrouille que votre propre développement
et votre CI : npm ne publie jamais package-lock.json et l'ignore partout ailleurs que dans le projet racine. Les
applications qui installent votre bibliothèque résolvent elles-mêmes ses dépendances, dans vos plages de versions. La seule
exception de npm est npm-shrinkwrap.json, qui est publié et prévaut, et que la plupart des
bibliothèques ne devraient pas utiliser.
Pourquoi un lockfile n'est pas un enregistrement de ce qui a été livré
Un lockfile est le plan d'un gestionnaire de paquets dans un projet. Le build qui a produit votre release ne s'est pas contenté de suivre ce plan :
- Il ne l'a peut-être pas utilisé. Une installation non figée, un lockfile manquant ou un second lockfile dans un monorepo signifie que l'arbre a été résolu autrement que dans le fichier que vous regardez.
- Les caches. Les paquets restaurés depuis un cache CI sont installés sans être récupérés, et un cache restauré par une clé partielle peut être antérieur au lockfile actuel. Voir ce que le cache GitHub Actions dissimule.
- Les outils de build. Les actions de configuration, les compilateurs, les linters et les générateurs de code arrivent par d'autres canaux, avec leurs propres arbres de dépendances.
-
Les téléchargements et les scripts d'installation. Un
curldans une étape de build ou le script d'installation d'un paquet récupère du code qu'aucun lockfile ne liste. - Les images de base. Un build de conteneur récupère des images et des paquets de système d'exploitation qui échappent à tous les lockfiles de langage.
Les hashs d'intégrité n'y changent rien. Ils prouvent que les paquets du lockfile n'ont pas été altérés ; ils ne disent rien de ce que le build a récupéré en dehors. Les outils SCA qui transforment un lockfile en SBOM héritent des mêmes angles morts.
Enregistrez le build, gardez le lockfile
Continuez à commiter les lockfiles et à installer à partir d'eux avec des installations figées. Ils rendent les builds reproductibles. Pour l'enregistrement de ce que contient une release, CRACI enregistre le build lui-même : un proxy qui comprend les paquets, placé sur ses runners GitHub Actions, enregistre chaque paquet récupéré par chaque job, y compris les paquets restaurés depuis les caches CI, et la SBOM de chaque job indique sa propre complétude. Cet enregistrement donne une vue plus complète des dépendances utilisées qu'un scan du lockfile. Voir les SBOM au build, ou réservez une démo pour comparer les deux sur l'un de vos propres builds.
Lockfiles : questions fréquentes
Qu'est-ce qu'un lockfile ?
Un lockfile est un fichier écrit par un gestionnaire de paquets pour enregistrer la version exacte de chaque dépendance résolue, directe ou transitive, avec sa provenance et une somme de contrôle. Les installations suivantes le lisent pour reproduire le même arbre au lieu de résoudre à nouveau les plages de versions.
Dois-je commiter mon lockfile ?
Oui, pour les applications et tout ce que vous déployez. Sans lockfile commité, chaque nouvelle installation résout à nouveau les plages de versions et peut récupérer de nouvelles versions transitives. Commitez-le et installez à partir de lui avec une installation figée telle que npm ci en CI.
Un lockfile épingle-t-il les dépendances transitives ?
Oui. C'est son rôle principal. Le manifeste ne liste que vos dépendances directes et leurs plages autorisées ; le lockfile enregistre la version exacte choisie pour chaque paquet de l'arbre.
Les lockfiles s'appliquent-ils aux bibliothèques que je publie ?
Pas pour vos utilisateurs. npm, par exemple, ne publie jamais package-lock.json et l'ignore partout ailleurs que dans le projet racine. Les applications qui installent votre bibliothèque résolvent elles-mêmes ses dépendances, dans les plages autorisées par votre package.json.
À quoi sert le champ integrity de package-lock.json ?
Il contient un hash Subresource Integrity, généralement sha512, du tarball du paquet. npm vérifie le paquet téléchargé par rapport à ce hash : un tarball altéré pour une version verrouillée ne s'installe donc pas. Il protège les paquets du lockfile, et rien de ce que le build récupère en dehors.
Un lockfile est-il la même chose qu'une SBOM ?
Non. Un lockfile est une entrée : le plan qu'un gestionnaire de paquets suit pour un projet. Une SBOM est un inventaire d'une release. Les outils SCA transforment souvent un lockfile en SBOM, ce qui fonctionne lorsque le build a installé exactement le lockfile et rien d'autre.
Comparez votre lockfile avec votre build
Exécutez un workflow sur CRACI et mettez sa SBOM enregistrée des paquets récupérés en regard de ce que dit votre lockfile.
Réserver une démo