Paul Esch Laurent Ozmurwfhob4 Unsplash With Nexus Logo

Qu’est-ce qu’un package-lock.json, et qu’est-ce que ça mange en hiver?

Publié le avril 17, 2020 par Larry.huot Blogue Larry Huot

Avec l’arrivée de la version 5 de NPM en 2017, plusieurs nouveaux outils furent distribués aux développeurs, tels que le nouveapackage-lock.json. Comme ça fait plusieurs mois que je cherche une explication claire sur l’utilité de package-lock.json et que je n’ai jamais trouvé d’article concis qui l’explique de A-Z, j’ai décidé de partager ce que j’en avais compris après plusieurs heures d’investigation. Avec un peu de chance, l’article suivant vous sauvera ces heures! 

Le problème

  • npm install n’est pas déterministe. Si aujourd’hui j’exécute npm install, et que demain j’exécute npm install, je n’aurai peut-être pas le même résultat.
  • Ce qui arrive, c’est que les bons vieux ~ et ^ dans package.json font en sorte que npm install va parfois installer des versions plus récentes des packages listés dans package.json. Considérons la syntaxe 1.0.1 = major.minor.patch comme étant la syntaxe utilisée pour gérer les versions des npm packages
  • ~1.0.1: installe la version patch la plus récente pour cette version de minor. Donc ça peut inclure 1.0.2, 1.0.3, 1.0.4, ainsi de suite, mais PAS 1.1.0. TL;DR: met à jour le patch seulement, tant que la version du package reste à ce minor
  • ^1.0.1 : même principe mais pour le minor  Donc ça peut inclure 1.0.2, 1.0.3, 1.0.4, 1.1.0, 1.2.0, mais pas 2.0.0. TL;DR: upgrade le patch, le minor, tant que la version du package reste à ce major

La solution

  • package-lock.json : aggrège une version immuable du package.json, de façon à ce que l’on puisse, par exemple, aller chercher du vieux code (qui contient une image immutable des packages utilisés à ce moment) et avoir le même node_modules comme extrant de npm install.
  • package-lock.json est généré par npm install. Donc si npm install décide de mettre à jour un package, un nouveau package-lock.json sera généré. Celui-ci contient les packages les plus récents qui respectent les règles d’upgrade établies dans le package.json.
  • avec le package-lock.json vient la belle commande npm ci. Elle fait exactement la même chose que npm install, mais avec package-lock.json au lieu de package.json.

En résumé

  • npm install n’est pas déterministe, et génère un package-lock.json
  • package-lock.json permet d’avoir un node_modules déterministe avec la commande npm ci.
  • Rouler un npm ci sur un package-lock.json va TOUJOURS générer le MÊME node_modules

Pourquoi c’est important dans votre vie de dev?

  • La beauté de la chose, c’est que maintenant, on peut mettre en cache notre dossier node_modules!!!
  • On génère une clef de cache à partir du contenu de package-lock.json.
  • Si notre package-lock.json n’a pas bougé depuis la dernière fois, on va aller chercher notre node_modules dans notre cache, et ainsi couper quelques minutes d’attente d’intégration! (your mileage may vary).

Annexe

Le temps d’installation est rendu quasiment nul !!

Npm Ci

Npm Ci

Voici un exemple de définition de tâche d’un pipeline d’intégration en continu avec la notation YAML

- task: Cache@2 
  inputs: 
    key: '**/package-lock.json, !**/node_modules/**/package-lock.json, !**/.*/**/package-lock.json' 
    path:$PATH_TO_YOUR_FRONTEND\ClientApp\node_modules' 
    cacheHitVar: 'CacheRestored' 
 
- task: Npm@1 
  displayName: 'npm ci' 
  condition: ne(variables['CacheRestored'], 'true') 
  inputs: 
    command: 'ci' 
    workingDir: '$PATH_TO_YOUR_FRONTEND\ClientApp' 

 

Vous avez un concept innovateur...

Laissez-nous vous proposer les meilleurs technologies