semver

semver

Locker les versions de vos dépendances Node.js

Locker les versions de vos dépendances Node.js

Node.js dispose d’un gestionnaire de dépendances très efficace et incontournable: npm.

Reposant sur les informations de dépendances déclarées dans le fichier package.json, il s’occupera de récupérer les dépendances déclarées et de les installées le dossier node_modules de votre projet, via l’exécution de la commande:

npm install

Pourquoi ?

Contrairement à la mécanique proposée par Maven dans le monde Java, Node.js repose sur une mécanique de dépendances hiérarchiques. C’est à dire que npm va récupérer et installer pour chaque niveau – application, et dépendances elles-mêmes – les librairies associées.

Par exemple, si votre projet, ainsi que les librairies dont il dépend, utilisent la librairie mkdirp, alors npm va charger et installer la dépendance mkdirp à la fois dans le dossier node_modules de votre projet, mais également dans le dossier node_modules de la librairie de votre projet.

Pour chaque librairie, dont vous dépendez, vous devez déclarer un pattern de sélection de version qui indiquera à npm quelle version de dépendance télécharger. Les patterns disponibles sont variés, allant du wildcard, à la version exacte.

Quels risques ?

Très rapidement, vous serez confronté à des problématiques de versions de dépendances qui évoluent.

Cela empêchera, au mieux, vos applications de tourner correctement. Au pire engendrera des bugs subtiles et très difficiles à détecter ou corriger, avec le risque de mettre en péril votre business, ou bien la qualité perçue de vos logiciels.

Quelles solutions ? Quels outils ?

Une technique possible pour se prémunir de ce problème, est de locker les versions de vos dépendances en indiquant des patterns de version plus restrictifs, voir complètement fixés.

Vous ne serez pas sorti d’affaire pour autant. Vous aurez beau fixer les versions de vos dépendances, celles-ci reposent également sur d’autres dépendances, pour lesquelles, leur auteurs respectifs n’appliquent peut-être pas les règles de gestion de versions qui vous arrange.

Ainsi, il est possible qu’une librairie donnée déclare une version de dépendance avec un wildcard. De fait, vous serez amené, à terme, à récupérer une version qui sera, soit incompatible avec votre code, soit tout simplement buggée.

Il faudrait, dans l’idéal, pouvoir locker toute la hiérarchie des versions de dépendances et pouvoir réinstaller ces dépendances de façon répétée dans les versions sélectionnées.

La bonne nouvelle, c’est qu’il existe des solutions pour répondre à ce besoin, dont les outils lockdown et npm-shrinkwrap.

lockdown

Le module lockdown propose de locker les versions des dépendances de votre projet dans le but de vous assurer que le code que vous développez reposera sur les même version de dépendances que ce soit dans votre IDE ou bien pendant vos phases de tests ou bien en production.

L’usage de Lockdown vous permettra de continuer à utiliser la commande npm install, tout en vous assurant d’obtenir le même code à chaque fois que la commande sera exécutée, ainsi qu’en vous évitant d’avoir à copier le code de vos dépendances dans votre gestionnaire de code source ou d’avoir à maintenir un repository privé npm.

Comme expliqué précédemment, même si vous exprimez la version exacte de vos dépendances dans votre fichier projet package.json, vous êtes toujours vulnérable à l’apparition soudaine d’une incompatibilité avec l’une de vos dépendances.

Par exemple, si votre projet dépend d’un package avec une version spécifique, qui, elle même dépend d’un autre package déclaré avec un version range, vous risquez de voir la version de votre dépendance changer lors d’une future exécution de la commande npm install.

Cet exemple n’est hélas pas la seule cause de problème. D’autre actions peuvent accidentellement casser le code de votre application:

  • En poussant une nouvelle version de librairie qui ne supporte plus la version de Node.js que vous utilisez
  • En introduisant un bug dans du code qui fonctionnait bien au préalable

Utilisation

1. Installez une dépendance dans votre projet. Par exemple, en ligne de commande:

npm install <module>@<version> --save

2. Générez le fichier lockdown.json en exécutant la commande lockdown-relock:

node_modules/.bin/lockdown-relock

3. Puis, ajoutez le fichier nouvellement créé à votre gestionnaire de code source.

Installer vos dépendances grâce au fichier lockdown.json

Une fois le fichier lockdown.json généré, il vous suffit d’appeler, de façon tout à fait classique, la commande npm install qui installera l’ensemble des dépendances dans les versions attendues.

Points forts

Lockdown se veut être un outil vous garantissant d’utiliser un code source identique, aussi bien en développement qu’en production. C’est pour cela, qu’en plus de stocker les versions des dépendances utilisées, il stocke également des checksums du code utilisé. Il permet donc de savoir qu’un code source dans une version donnée a été modifié, et vous alerte du problème.

Autre point intéressant: le projet est maintenu par Mozilla, ce qui a tendance à rassurer quant au sérieux et la pérennité de l’outil.

npm-shrinkwrap

Tout comme l’outil lockdown, la commande npm-shrinkwrap propose de figer les versions de dépendances de votre application.

Pas de souci d’installation néanmoins, puisque la commande est directement disponible dans la distribution de npm. Npm venant avec l’installation de Node.js, pas besoin de bouger le petit doigt pour avoir l’outil à disposition.

Le fichier de stockage des informations de version s’appelle quant à lui npm-shrinkwrap.json.

Utilisation

L’utilisation de npm-shrinkwrap est tout à fait similaire à celle de lockdown, il suffit d’utiliser la commande npm install pour installer vos dépendances, puis exécuter la commande npm shrinkwrap pour générer le fichier de version.

Gestion des checksums

Contrairement à lockdown, la commande npm-shrinkwrap ne gère pas de checksum. Néanmoins, il existe des solutions de remplacement, telles que le package npm-seal qui se propose de venir compléter la commande npm-shrinkwrap en proposant la fonctionnalité manquante.

Contrairement à l’utilitaire npm-shrinkwrap, le package npm-seal est un utilitaire 3rd party qui doit être installé en complément avec la commande suivante:

npm install seal -g

Points forts

Nous l’avons déjà vu, la commande est intégrée à la distribution de l’outil npm. Par ailleurs, l’outil est également maintenu par une entreprise gage de sérieux: Uber.

Bon à savoir

Même si les outils lockdown et npm-shrinkwrap vous proposent des solutions différentes, il est tout à fait possible de combiner l’usage de ces deux outils sans que cela pose de problème.