Dois-je valider le fichier package-lock.json créé par npm 5?

1397

npm 5 est sorti aujourd'hui et l'une des nouvelles fonctionnalités inclut des installations déterministes avec la création d'un package-lock.jsonfichier.

Ce fichier est-il censé être conservé sous contrôle de code source?

Je suppose que c'est similaire à yarn.locket composer.lock, qui sont tous deux censés rester sous contrôle de source.

rink.attendant.6
la source
20
Réponse courte: oui. Un commentaire: lorsque package-lock.json change, vous pouvez valider uniquement cette modification, indépendamment des autres modifications sources. Cela rend git logplus facile à gérer.
Purplejacket
14
Un fichier ne peut pas aider à produire une installation déterministe s'il n'existe pas.
Alan H.
4
Dépend du projet. github.com/npm/npm/issues/20603
Gajus
3
Si vous faites vraiment confiance à npm, le but est de rapporter plus explicitement ce que le projet utilise. Si vous voulez vraiment la prévisibilité, ignorez ce fichier et installez plutôt vos node_modules (voir .npmrc et la configuration associée dans les réponses + commentaire) et utilisez-le pour suivre ce qui change réellement plutôt que ce que votre gestionnaire de paquets déclare qu'il fait. En fin de compte: quel est le plus important? Votre gestionnaire de packages ou le code que vous utilisez.
jimmont

Réponses:

1617

Oui, package-lock.jsonest destiné à être vérifié dans le contrôle de code source. Si vous utilisez npm 5, vous pouvez voir ceci sur la ligne de commande: created a lockfile as package-lock.json. You should commit this file.Selon npm help package-lock.json:

package-lock.jsonest généré automatiquement pour toutes les opérations où npm modifie l' node_modulesarborescence ou package.json. Il décrit l'arborescence exacte qui a été générée, de sorte que les installations suivantes peuvent générer des arborescences identiques, indépendamment des mises à jour de dépendance intermédiaires.

Ce fichier est destiné à être validé dans les référentiels sources et sert à diverses fins:

  • Décrivez une représentation unique d'une arborescence de dépendances telle que les coéquipiers, les déploiements et l'intégration continue sont garantis pour installer exactement les mêmes dépendances.

  • Fournir aux utilisateurs la possibilité de "voyager dans le temps" vers les états précédents node_modulessans avoir à valider le répertoire lui-même.

  • Pour faciliter une meilleure visibilité des changements d'arbre grâce à des différences de contrôle de source lisibles.

  • Et optimisez le processus d'installation en permettant à npm d'ignorer les résolutions de métadonnées répétées pour les packages précédemment installés.

Un détail clé package-lock.jsonest qu'il ne peut pas être publié, et il sera ignoré s'il est trouvé ailleurs que dans le package de niveau supérieur. Il partage un format avec npm-shrinkwrap.json (5), qui est essentiellement le même fichier, mais permet la publication. Ceci n'est pas recommandé, sauf si vous déployez un outil CLI ou utilisez le processus de publication pour produire des packages de production.

Si les deux package-lock.jsonet npm-shrinkwrap.jsonsont présents à la racine d'un package, package-lock.jsonseront complètement ignorés.

vine77
la source
78
Dans quel type de projets est-il réellement utile de valider le fichier? L'intérêt de semver et package.json est que les dépendances compatibles mises à jour ne doivent pas être notées.
curiousdannii
45
Le mot clé est "ne devrait pas avoir besoin d'être" - mais dans la pratique, les gens ne suivent pas parfaitement. C'est pourquoi vous pouvez utiliser package-lock.json et package.json ensemble pour faciliter la mise à jour des packages tout en vous assurant que chaque développeur et chaque application déployée utilisent la même arborescence de dépendances.
Panu Horsmalahti
34
@trusktr: Sindre Sorhus recommande d'utiliser "Lockfiles pour les applications, mais pas pour les packages".
vine77
23
Une autre chose est que package-lock.json est ignoré pour la publication sur NPM, donc si un développeur l'utilise pour un développeur de bibliothèque, il minimise les chances qu'il intercepte une régression à partir d'une version de dépendance mise à jour et passe donc bug sur les utilisateurs finaux. Pour cette raison, ne pas utiliser de fichier de verrouillage pour le développement de la bibliothèque augmente les chances d'envoyer moins de bogues.
trusktr
129
Personnellement, j'ai maintenant dû recourir à ajouter package-lock.jsonà mon .gitignore... cela me posait beaucoup plus de problèmes que de les résoudre. Il y a toujours des conflits lorsque nous fusionnons ou rebasons, et lorsqu'une fusion entraîne une package-lock.jsoncorruption sur le serveur CI, c'est juste une douleur de devoir continuer à le réparer.
Stefan Z Camilleri
111

Oui, il est destiné à être enregistré. Je veux suggérer qu'il obtient son propre commit unique. Nous constatons que cela ajoute beaucoup de bruit à nos diffs.

xer0x
la source
19
il est juste de débattre s'il doit être archivé dans votre référentiel de code source, mais la publication de ce fichier dans npm n'est pas vraiment à débattre - vous devez inclure soit votre package-lock.json ou votre fichier shrinkwrap dans votre registre npm. si vous ne le faites pas, votre package publié sera soumis à des changements non dépendants des dépendances de vos dépendances de 1ère génération. vous ne remarquerez pas que ce soit un problème jusqu'à ce qu'une de ces dépendances de 2e génération publie un changement de rupture et que votre package publié soit mystérieusement cassé. ce fichier package-lock.json a été créé pour résoudre ce problème.
guerillapresident le
9
@BetoAveiga par bruit, je veux dire que les validations avec package-lock.json peuvent avoir tellement de lignes de versions de packages de nœuds, que tout autre travail dans cette validation devient caché.
xer0x
7
Je garde généralement les installations de packages séparées des autres travaux. Je n'ai jamais besoin de différencier un commit comme "Installed chai and mocha", car je sais déjà ce qui a changé.
Keith
3
Des conseils concernant le package-lock.jsonfichier lorsque vous travaillez sur un système SCM avec des troncs et des branchements? J'effectue des modifications sur une branche qui doit être fusionnée dans le tronc ... dois-je maintenant (en quelque sorte) résoudre les conflits entre les deux package-lock.jsonfichiers? C'est douloureux.
kmiklas
3
@guerillapresident Si je comprends bien, vous avez partiellement raison. La publication de ce fichier sur npm n'est pas sujette à débat. Vous ne pouvez pas le publier.
Tim Gautier
66

Oui tu devrais:

  1. valider le package-lock.json.
  2. utiliser npm ciau lieu denpm install lors de la création de vos applications sur votre CI et votre machine de développement locale

Le npm ciworkflow nécessite l'existence d'un package-lock.json.


Un gros inconvénient de la npm installcommande est son comportement inattendu qui peut muter package-lock.json, alors qu'il npm cin'utilise que les versions spécifiées dans le fichier de verrouillage et produit une erreur

  • si package-lock.jsonet ne package.jsonsont pas synchronisés
  • s'il package-lock.jsonmanque un.

Par conséquent, fonctionnant npm installlocalement, esp. dans des équipes plus grandes avec plusieurs développeurs, cela peut conduire à de nombreux conflits au sein du package-lock.jsonet les développeurs peuvent décider de supprimer complètement le à la package-lock.jsonplace.

Pourtant, il existe un cas d'utilisation solide pour pouvoir croire que les dépendances du projet se résolvent de manière répétée et fiable sur différentes machines.

D'un package-lock.jsonvous obtenez exactement cela: un état connu pour fonctionner.

Dans le passé, j'avais des projets sans package-lock.json/ npm-shrinkwrap.json/ yarn.lockfichiers dont la construction échouait un jour parce qu'une dépendance aléatoire avait une mise à jour de rupture.

Ces problèmes sont difficiles à résoudre car vous devez parfois deviner quelle était la dernière version de travail.

Si vous souhaitez ajouter une nouvelle dépendance, vous exécutez toujours npm install {dependency}. Si vous souhaitez mettre à niveau, utilisez soit npm update {dependency}ou npm install ${dependendency}@{version}et validez la modification package-lock.json.

Si une mise à niveau échoue, vous pouvez revenir au dernier fonctionnement connu package-lock.json.


Pour citer npm doc :

Il est fortement recommandé de valider le verrouillage du package généré au contrôle de code source: cela permettra à toute autre personne de votre équipe, à vos déploiements, à votre intégration continue / CI et à toute autre personne qui exécute l'installation npm dans votre source de package d'obtenir la même arborescence de dépendances exacte. que vous développiez. De plus, les différences de ces changements sont lisibles par l'homme et vous informeront de toutes les modifications que npm a apportées à vos node_modules, vous pouvez donc remarquer si des dépendances transitives ont été mises à jour, hissées, etc.

Et en ce qui concerne la différence entre npm civsnpm install :

  • Le projet doit avoir un package-lock.json ou npm-shrinkwrap.json existant.
  • Si les dépendances dans le verrou de package ne correspondent pas à celles dans package.json, se npm citerminera avec une erreur, au lieu de mettre à jour le verrou de package.
  • npm ci ne peut installer que des projets entiers à la fois: les dépendances individuelles ne peuvent pas être ajoutées avec cette commande.
  • Si un node_modulesest déjà présent, il sera automatiquement supprimé avant de npm cicommencer son installation.
  • Il n'écrira jamais package.jsonni sur aucun des verrous de package: les installations sont essentiellement gelées.

Remarque: j'ai posté une réponse similaire ici

k0pernikus
la source
10
Cette réponse mérite plus de crédit, en particulier en utilisant npm ci. Son utilisation atténue la plupart des problèmes rencontrés par les utilisateurs avec le verrouillage des packages.
JamesB
J'ai trouvé que l'utilisation d'une version fixe dans package.json (sans caret ni tilde) était une option beaucoup plus propre. Cela me sauve du whose build would fail one day because a random dependency got a breaking updategenre de problème. Bien que cela laisse la possibilité d'une dépendance de l'enfant causant le même problème.
Ashwani Agarwal
58

Oui, la meilleure pratique consiste à s'enregistrer (OUI, ENREGISTREMENT)

Je suis d'accord que cela causera beaucoup de bruit ou de conflit en voyant la différence. Mais les avantages sont:

  1. garantir exactement la même version de chaque paquet . Cette partie est la plus importante lors de la construction dans différents environnements à différents moments. Vous pouvez l'utiliser ^1.2.3dans votre package.json, mais comment pouvez-vous vous assurer que chaque fois npm installrécupérera la même version sur votre machine de développement et sur le serveur de build, en particulier ces packages de dépendance indirecte? Eh bien, package-lock.jsonje m'en assurerai. (À l'aide de npm cilaquelle installe des packages basés sur le fichier de verrouillage)
  2. il améliore le processus d'installation.
  3. cela aide avec la nouvelle fonctionnalité d'audit npm audit fix(je pense que la fonctionnalité d'audit est de npm version 6).
Xin
la source
3
Pour autant que je sache, ne jamais utiliser semver (que les développeurs npm ne comprennent pas de toute façon) devrait donner le même comportement que d'avoir un fichier de verrouillage au moins dans 99% des cas. Ma propre expérience est que les fuckups semver se produisent principalement avec des packages primaires (dépendances directes, datepickers jquery merdiques, etc.). Mon expérience personnelle avec npm a été que les fichiers de verrouillage étaient du bruit pour toujours. J'espère que cette sagesse est inchangée avec les versions récentes.
Svend
13
+1 pour mentionner npm ci. Les gens mentionnent fréquemment que a package-lock.jsonpermet une installation déterministe des packages mais ne mentionnent presque jamais la commande qui facilite ce comportement! Beaucoup de gens pensent probablement à tort npm installinstallations exactement ce qui est dans le fichier de verrouillage ...
ahaurat
npm ci n'est pas dans npm 5.
dpurrington
Je vous remercie! Il est logique de valider package-lock.json si vous utilisez npm ci. Votre équipe / développeur principal peut décider du moment de la mise à jour. Si tout le monde le commet arbitrairement, cela ne sert à rien, et cela crée juste du bruit dans votre référentiel. La documentation NPM devrait rendre cela plus clair. Je pense que la plupart des développeurs sont simplement confus par cette fonctionnalité.
adampasz
@adampasz en fait, chaque développeur peut valider le fichier de verrouillage, et une fois les tests réussis et fusionnés, la deuxième branche renouvelle simplement le fichier de verrouillage si les packages sont modifiés (nous ne changeons pas souvent package.json, nous sommes moins confrontés à ce problème (
Xin
38

Je ne valide pas ce fichier dans mes projets. À quoi ça sert ?

  1. Il est généré
  2. C'est la cause d'une erreur d'intégrité du code SHA1 dans gitlab avec les builds gitlab-ci.yml

Bien qu'il soit vrai que je n'utilise jamais ^ dans mon package.json pour les bibliothèques car j'ai eu de mauvaises expériences avec.

Deunz
la source
11
Je souhaite que cela puisse être expliqué davantage à partir de la documentation npm - Il serait utile d'avoir un aperçu de ce que vous perdez spécifiquement en ne vous engageant pas package-lock.json. Certains référentiels peuvent ne pas nécessiter les avantages qui en découlent et peuvent préférer ne pas avoir de contenu généré automatiquement dans la source.
PotatoFarmer
2
Je peux voir comment cela peut être utile pour le débogage (un diff entre deux verrous par exemple) pour aider à résoudre les problèmes. Je suppose que cela peut également être utilisé pour empêcher ce genre de choses, mais cela peut également être pénible de l'avoir dans un référentiel partagé où il peut subir des conflits de fusion à cause de cela. Pour commencer, je veux garder les choses simples, je vais simplement utiliser package.json seul jusqu'à ce que je vois qu'il y a un réel besoin pour package-lock.json.
radtek
6
Vous ne pouvez pas utiliser ^ sur votre package.json, mais vous pouvez être sûr que vos dépendances ne l'utilisent pas?
neiker
35

Aux personnes qui se plaignent du bruit en faisant git diff:

git diff -- . ':(exclude)*package-lock.json' -- . ':(exclude)*yarn.lock'

J'ai utilisé un alias:

alias gd="git diff --ignore-all-space --ignore-space-at-eol --ignore-space-change --ignore-blank-lines -- . ':(exclude)*package-lock.json' -- . ':(exclude)*yarn.lock'"

Pour ignorer package-lock.json dans diffs pour l'ensemble du référentiel (tous ceux qui l'utilisent), vous pouvez ajouter ceci à .gitattributes:

package-lock.json binary
yarn.lock binary

Cela se traduira par des différences qui affichent "les fichiers binaires a / package-lock.json et b / package-lock.json diffèrent chaque fois que le fichier de verrouillage du package a été modifié. De plus, certains services Git (notamment GitLab, mais pas GitHub) excluront également ces fichiers (plus de 10 000 lignes modifiées!) des diffs lors de la visualisation en ligne en faisant cela.

Raza
la source
1
J'ai gd() { git diff --color-words $1 $2 -- :!/yarn.lock :!/package-lock.json; }dans mon .bashrc au lieu d'un alias.
apostl3pol
16

Oui, vous pouvez valider ce fichier. Extrait des documents officiels du npm :

package-lock.jsonest généré automatiquement pour toutes les opérations où npmmodifie l’ node_modulesarborescence ou package.json. Il décrit l'arborescence exacte qui a été générée, de sorte que les installations suivantes peuvent générer des arborescences identiques, indépendamment des mises à jour de dépendance intermédiaires.

Ce fichier est destiné à être validé dans les référentiels sources [.]

Bablu Singh
la source
13
Une installation ne mettra-t-elle pas toujours à jour node_modules, et donc la mise à jour package-lock.json?
Tim Gautier
2
Non, vous pouvez exécuter l' npm ciinstallation à partir du package-lock.json
William Hampshire
Vous devez souligner dans votre réponse que vous DEVEZ utiliser npm ci dans votre build d'intégration continue si vous avez package-lock.json sur le
dépôt
6

Désactiver globalement package-lock.json

tapez ce qui suit dans votre terminal:

npm config set package-lock false

ça marche vraiment pour moi comme par magie

Balogun Ridwan Ridbay
la source
2
cela crée ~/.npmrc(au moins sur mes macos) avec du contenu package-lock=falseet la même chose peut être faite dans n'importe quel projet spécifique à côté node_modules/(par exempleecho 'package-lock=false' >> .npmrc
jimmont
6
c'est assez drôle pour moi que ce soit un point négatif. la communauté npm ne peut tout simplement pas accepter que la génération automatique de package-lock.json était une mauvaise implication de la communauté. vous ne devriez pas faire de choses qui peuvent avoir un impact sur un processus d'équipe. cela aurait dû être une option à activer, pas forcé. combien de personnes font juste "git add *" sans même le remarquer et bousiller les builds. Si vous avez n'importe quel type de flux basé sur la fusion, je sais que le flux git est comme la Bible pour les personnes qui l'utilisent, cela ne fonctionnera pas. vous ne pouvez pas avoir de génération lors de la fusion! le versionnement de npm est cassé, le paquet: 1.0.0 devrait être déterministe!
Eric Twilegar
3
pourquoi est-ce rejeté? il s'agit clairement d'un moyen légitime de désactiver une fonctionnalité qui ne fonctionne pas. Et bien qu'il ne réponde pas à la question en soi, il discute la question. c'est-à-dire qu'il n'a plus besoin de répondre.
Bravo
La raison pour laquelle il est voté est parce que vous désactivez simplement une fonctionnalité.
Raza
5

Oui, c'est une pratique standard pour valider package-lock.json

La principale raison de la validation de package-lock.json est que tout le monde dans le projet est sur la même version de package.

Avantages:-

  • Si vous suivez un contrôle de version strict et que vous ne permettez pas la mise à jour vers les versions majeures automatiquement pour vous éviter les modifications incompatibles en amont dans les packages tiers, la validation du verrouillage de package est très utile.
  • Si vous mettez à jour un package particulier, il est mis à jour dans package-lock.json et tous les utilisateurs du référentiel sont mis à jour vers cette version particulière lorsqu'ils prennent la traction de vos modifications.

Les inconvénients:-

  • Cela peut rendre vos demandes de pull moche :) '

Edit: - npm install ne s'assurera pas que tout le monde dans le projet est sur la même version de package. npm ci vous y aidera.

Nikhil Mohadikar
la source
4
Les inconvénients disparaîtraient si vous utilisiez npm ciau lieu de npm install.
k0pernikus
2
Portée rampant un peu, mais voici plus d'informations sur cet excellent conseil de @ k0pernikus .
ruffin
1
"Tout le monde dans le projet sera sur la même version de package, tout ce que vous avez à faire est d'installer npm" Pas vrai, vous devez utiliser "npm ci" à la place
reggaeguitar
Merci, @reggaeguitar. Mise à jour de ma réponse pour cela.
Nikhil Mohadikar
2

Mon utilisation de npm est de générer des css / js minifiés / uglifiés et de générer le javascript nécessaire dans les pages servies par une application django. Dans mes applications, Javascript s'exécute sur la page pour créer des animations, parfois effectuer des appels ajax, travailler dans un framework VUE et / ou travailler avec le css. Si package-lock.json a un certain contrôle sur ce qui se trouve dans package.json, il peut être nécessaire qu'il existe une version de ce fichier. D'après mon expérience, cela n'affecte pas ce qui est installé par npm install, ou si c'est le cas, cela n'a pas affecté à ce jour les applications que je déploie à ma connaissance. Je n'utilise pas mongodb ou d'autres applications similaires qui sont traditionnellement des clients légers.

Je supprime package-lock.json du référentiel car l'installation de npm génère ce fichier et l'installation de npm fait partie du processus de déploiement sur chaque serveur qui exécute l'application. Le contrôle de version du nœud et de npm se fait manuellement sur chaque serveur, mais je fais attention à ce qu'ils soient les mêmes.

Lorsqu'il npm installest exécuté sur le serveur, il modifie package-lock.json, et s'il y a des modifications dans un fichier enregistré par le référentiel sur le serveur, le prochain déploiement WONT vous permet d'extraire de nouvelles modifications de l'origine. Autrement dit, vous ne pouvez pas déployer, car l'extraction écrasera les modifications apportées à package-lock.json.

Vous ne pouvez même pas écraser un package-lock.json généré localement avec ce qui est sur le référentiel (réinitialiser le maître d'origine dur), car npm se plaindra chaque fois que vous émettez une commande si le package-lock.json ne reflète pas ce qui se trouve dans node_modules en raison de l'installation de npm, interrompant ainsi le déploiement. Maintenant, si cela indique que des versions légèrement différentes ont été installées dans node_modules, encore une fois cela ne m'a jamais posé de problème.

Si node_modules n'est pas sur votre dépôt (et il ne devrait pas l'être), alors package-lock.json doit être ignoré.

Si je manque quelque chose, corrigez-moi dans les commentaires, mais le fait que la version est extraite de ce fichier n'a aucun sens. Le fichier package.json contient des numéros de version, et je suppose que ce fichier est celui utilisé pour créer des packages lorsque l'installation de npm se produit, car lorsque je le supprime, l'installation de npm se plaint comme suit:

jason@localhost:introcart_wagtail$ rm package.json
jason@localhost:introcart_wagtail$ npm install
npm WARN saveError ENOENT: no such file or directory, open '/home/jason/webapps/introcart_devtools/introcart_wagtail/package.json'

et la construction échoue, cependant lors de l'installation de node_modules ou de l'application de npm pour construire js / css, aucune plainte n'est faite si je supprime package-lock.json

jason@localhost:introcart_wagtail$ rm package-lock.json 
jason@localhost:introcart_wagtail$ npm run dev

> introcart@1.0.0 dev /home/jason/webapps/introcart_devtools/introcart_wagtail
> NODE_ENV=development webpack --progress --colors --watch --mode=development

 10% building 0/1 modules 1 active ...
Lampe magique
la source
Juste pour ajouter, j'ai maintenant validé mon package-lock.json dans mon référentiel, et j'utilise npm ci sur mon déploiement ansible, que je crois supprimer les node_modules de delete, et installe tout dans package-lock.json sans le mettre à jour. Cela permet à mon front-end de mettre à niveau les éléments javascript sans avoir besoin d'une intervention manuelle dans le déploiement.
MagicLAMP