L'auteur du matériel, dont nous publions la traduction aujourd'hui, dit que l'un des problèmes auxquels les programmeurs doivent faire face est que leur code fonctionne pour eux et qu'il donne des erreurs à quelqu'un d'autre. Ce problème, peut-être l'un des plus courants, se pose du fait que différentes dépendances que le programme utilise sont installées dans les systèmes du créateur et de l'utilisateur du programme. Pour lutter contre ce phénomène, des fichiers dits de verrouillage existent dans les
gestionnaires de paquets
yarn et
npm . Ils contiennent des informations sur les versions exactes des dépendances. Le mécanisme est utile, mais si quelqu'un développe un package dont la publication est prévue dans npm, il vaut mieux ne pas utiliser de fichiers de verrouillage. Ce matériel est dédié à l'histoire de la raison pour laquelle il en est ainsi.

La chose la plus importante en bref
Les fichiers de verrouillage sont extrêmement utiles lors du développement d'applications Node.js comme les serveurs Web. Cependant, si vous parlez de créer une bibliothèque ou un outil de ligne de commande dans le but de publier dans npm, vous devez savoir que les fichiers de verrouillage dans npm ne sont pas publiés. Cela signifie que si ces fichiers sont utilisés pendant le développement, le créateur du package npm et ceux qui utilisent ce package utiliseront différentes versions des dépendances.
Qu'est-ce qu'un fichier de verrouillage?
Le fichier de verrouillage décrit l'arborescence de dépendance complète sous la forme qu'il a acquise au cours du travail sur le projet. Cette description inclut également les dépendances imbriquées. Le fichier contient des informations sur des versions spécifiques des packages utilisés. Dans le gestionnaire de packages npm, ces fichiers sont appelés
package-lock.json
, dans yarn -
yarn.lock
. Dans les deux gestionnaires, ces fichiers se trouvent dans le même dossier que
package.json
.
Voici à quoi pourrait ressembler
package-lock.json
.
{ "name": "lockfile-demo", "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { "color-convert": "^1.9.0" } }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } } } }
Voici un exemple de fichier
yarn.lock
. Il n'est pas conçu comme
package-lock.json
, mais il contient des données similaires.
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" supports-color "^5.3.0"
Ces deux fichiers contiennent des informations de dépendance critiques:
- La version exacte de chaque dépendance installée.
- Informations de dépendance pour chaque dépendance.
- Informations sur le package téléchargé, y compris la somme de contrôle utilisée pour vérifier l'intégrité du package.
Si toutes les dépendances sont répertoriées dans le fichier de verrouillage, pourquoi ajoutent-elles également des informations à leur sujet dans
package.json
? Pourquoi deux fichiers sont-ils nécessaires?
Comparaison des fichiers package.json et lock
Le champ des
dependencies
du fichier
package.json
pour objet d'afficher les dépendances du projet qui doivent être installées pour qu'il fonctionne correctement. Mais cela n'inclut pas d'informations sur les dépendances de ces dépendances. Les informations de dépendance peuvent inclure des versions de package exactes ou une certaine plage de versions spécifiées conformément aux règles de contrôle de
version sémantique . Lors de l'utilisation de la gamme npm ou fil, la version la plus appropriée de l'emballage est sélectionnée.
Supposons que la commande
npm install
été exécutée pour installer les dépendances d'un certain projet. Au cours du processus d'installation, npm a récupéré les packages appropriés. Si vous exécutez à nouveau cette commande, après un certain temps, et si de nouvelles versions des dépendances sont publiées pendant cette période, il peut arriver que la deuxième fois que d'autres versions des packages utilisés dans le projet soient chargées. Par exemple, si vous installez une dépendance, comme
twilio
, à l'aide de la
npm install twilio
, l'entrée suivante peut apparaître dans la section des
dependencies
du fichier
package.json
:
{ "dependencies": { "twilio": "^3.30.3" } }
Si vous consultez la
documentation de gestion des versions sémantique npm, vous pouvez voir que l'icône
^
indique que n'importe quelle version du package est appropriée, dont le nombre est supérieur ou égal à 3.30.3 et inférieur à 4.0.0. Par conséquent, s'il n'y a pas de fichier de verrouillage dans le projet et qu'une nouvelle version du package est publiée, la commande
npm install
ou
yarn install
installera automatiquement cette nouvelle version du package. Les informations contenues dans
package.json
ne seront pas mises à jour. Lorsque vous utilisez des fichiers de verrouillage, tout semble différent.
Si npm ou yarn trouve le fichier de verrouillage correspondant, ils installeront des packages basés sur ce fichier, et non sur
package.json
. Cela est particulièrement utile, par exemple, lorsque vous utilisez des systèmes d'intégration continue (CI) sur des plates-formes sur lesquelles vous devez garantir un fonctionnement uniforme du code et des tests dans un environnement dont les caractéristiques sont connues à l'avance. Dans de tels cas, vous pouvez utiliser des commandes ou des indicateurs spéciaux lors de l'appel des gestionnaires de packages appropriés:
npm ci # , package-lock.json yarn install --frozen-lock-file # , yarn.lock,
Ceci est extrêmement utile si vous développez un projet comme une application Web ou un serveur, car dans un environnement CI, vous devez simuler le comportement de l'utilisateur. Par conséquent, si nous incluons un fichier de verrouillage dans le référentiel du projet (par exemple, créé à l'aide des outils git), nous pouvons être sûrs que chaque développeur, chaque serveur, chaque système de construction de code et chaque environnement CI utilise les mêmes versions dépendances.
Pourquoi ne pas faire de même lors de la publication de bibliothèques ou d'autres outils logiciels dans le registre npm? Avant de répondre à cette question, nous devons parler du fonctionnement du processus de publication des packages.
Processus de publication des packages
Certains développeurs pensent que ce qui est publié dans npm est exactement ce qui est stocké dans le référentiel git, ou ce que le projet se transforme après l'achèvement des travaux sur celui-ci. Ce n'est en fait pas le cas. Lors de la publication d'un package, npm recherche les fichiers à publier en accédant à la clé de
files
dans le fichier
package.json
et le fichier
.npmignore
. Si rien de tout cela ne peut être détecté, le fichier
.gitignore
est utilisé. De plus, certains fichiers sont toujours publiés et d'autres ne sont jamais publiés. Vous pouvez découvrir quels sont ces fichiers
ici . Par exemple, npm ignore toujours le dossier
.git
.
Après cela, npm prend tous les fichiers appropriés et les place dans un fichier
tarball
à l'aide de la commande
npm pack
. Si vous souhaitez regarder ce qui est exactement contenu dans un tel fichier, vous pouvez exécuter la commande
npm pack --dry-run
dans le dossier du projet et consulter la liste des matériaux dans la console.
Npm pack - sortie de la commande sècheLe fichier
tarball
résultant est ensuite téléchargé dans le registre npm. Lorsque vous exécutez la commande
npm pack --dry-run
vous pouvez faire attention au fait que s'il existe un fichier
package-lock.json
dans le projet, il n'est pas inclus dans le fichier tarball. Cela est dû au fait que ce fichier, conformément aux
règles npm, est toujours ignoré.
Le résultat est que si quelqu'un installe le package de quelqu'un d'autre, le fichier
package-lock.json
ne sera pas impliqué. Ce qui se trouve dans ce fichier, le développeur du package ne sera pas pris en compte lors de l'installation du package par quelqu'un d'autre.
Cela peut, par une coïncidence malchanceuse, conduire au problème dont nous avons parlé au tout début. Dans le système du développeur, le code fonctionne correctement et dans d'autres systèmes, il génère des erreurs. Mais le fait est que le développeur du projet et ceux qui utilisent le projet utilisent différentes versions des packages. Comment y remédier?
Refus de fichiers verrouillés et utilisation de la technologie de film rétractable
Vous devez d'abord empêcher l'inclusion de fichiers de verrouillage dans le référentiel du projet. Lorsque vous utilisez git, vous devez inclure les éléments suivants dans votre fichier
.gitignore
projet:
yarn.lock package-lock.json
La documentation de
yarn.lock
indique que
yarn.lock
doit être ajouté au référentiel même s'il s'agit de développer la bibliothèque que vous prévoyez de publier. Mais si vous voulez que vous et vos utilisateurs de bibliothèque travaillez avec le même code, je recommanderais d'inclure
yarn.lock
dans le fichier
.gitignore
.
Vous pouvez désactiver la création automatique du fichier
package-lock.json
en
.npmrc
fichier
.npmrc
avec le contenu suivant dans le dossier du projet:
package-lock=false
Lorsque vous travaillez avec yarn, vous pouvez utiliser la commande
yarn install --no-lockfile
, qui vous permet de désactiver la lecture du fichier
yarn.lock
.
Cependant, le fait que nous nous soyons débarrassés du fichier
package-lock.json
ne signifie pas que nous ne pouvons pas capturer d'informations sur les dépendances et les dépendances imbriquées. Il
existe un autre fichier appelé
npm-shrinkwrap.json
.
En général, il
s'agit du même fichier que
package-lock.json
, il est créé par la
npm shrinkwrap
. Ce fichier pénètre dans le registre npm lorsque le package est publié.
Afin d'automatiser cette opération, la
npm shrinkwrap
peut être ajoutée à la section de description de script du fichier
package.json
en tant que script de préemballage. Vous pouvez obtenir le même effet en utilisant le hook git commit. Par conséquent, vous pouvez être sûr que dans votre environnement de développement, dans votre système CI et les utilisateurs de votre projet utilisent les mêmes dépendances.
Il convient de noter qu'il est recommandé d'utiliser cette technique de manière responsable. En créant des fichiers de film rétractable, vous validez des versions spécifiques des dépendances. D'une part, cela est utile pour assurer le fonctionnement stable du projet, d'autre part, cela peut empêcher les utilisateurs d'installer des correctifs critiques, ce qui, sinon, se ferait automatiquement. En fait, npm recommande fortement de ne pas utiliser de fichiers rétractables lors du développement de bibliothèques, limitant leur utilisation à quelque chose comme les systèmes CI.
Recherche d'informations sur les packages et les dépendances
Malheureusement, avec toute la richesse des informations sur la gestion des dépendances dans la
documentation npm, il est parfois difficile de naviguer dans ces informations. Si vous voulez savoir exactement ce qui est installé lors de l'installation des dépendances ou emballé avant d'envoyer le paquet à npm, vous pouvez, avec différentes commandes, utiliser l'
--dry-run
. L'utilisation de ce drapeau conduit au fait que l'équipe n'affecte pas le système. Par exemple, la commande
npm install --dry-run
n'installe pas réellement les dépendances et la commande
npm publish --dry-run
ne démarre pas le processus de publication du package.
Voici quelques commandes similaires:
npm ci --dry-run # , package-lock.json npm-shrinkwrap.json npm pack --dry-run # , npm install <dep> --verbose --dry-run #
Résumé
Une grande partie de ce dont nous avons parlé ici repose sur les spécificités de l'exécution de diverses opérations à l'aide de npm. Nous parlons d'empaquetage, de publication, d'installation de packages, de travail avec les dépendances. Et étant donné que le npm évolue constamment, nous pouvons dire que tout cela peut changer à l'avenir. De plus, la possibilité d'application pratique des recommandations données ici dépend de la façon dont le développeur du package perçoit le problème de l'utilisation de différentes versions de dépendances dans différents environnements.
J'espère que ce matériel vous a aidé à mieux comprendre le fonctionnement de l'écosystème de dépendance npm. Si vous souhaitez approfondir cette question, vous pouvez lire ici les différences entre les commandes d'
npm install
npm ci
et
npm install
.
Ici, vous pouvez découvrir ce qui se trouve exactement dans les
npm-shrinkwrap.json
package-lock.json
et
npm-shrinkwrap.json
.
Voici la page de documentation de npm où vous pouvez découvrir quels fichiers de projet sont inclus et non inclus dans les packages.
Chers lecteurs! Utilisez-vous le fichier npm-shrinkwrap.json dans vos projets?
