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

    Avec l’arrivée de la version 5 de NPM en 2017, plusieurs nouveaux outils furent distribués aux développeurs, tels que le nouveau package-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 npminstall, et que demain j’exécute npminstall, 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 npminstallva parfois installer des versions plus récentes des packages listés dans package.json. Considérons la syntaxe 1.0.1 = major.minor.patchcomme é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 installn’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.jsonn’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! (yourmileagemayvary).

    Annexe

    Le temps d’installation est rendu quasiment nul !!

    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' 
    
    Faisons connaissance
    Vous désirez en savoir plus et/ou collaborer avec nous?

    Nous avons hâte de vous lire.