npm

npm

Détecter les versions dépassées de vos dépendances Node.js

Détecter les versions dépassées de vos dépendances Node.js

L’écosystème Node.js est non seulement très jeune, mais également très dynamique. Les versions des librairies que vous utilisez ont tendance à changer très vite. Pour vous économiser la recherche permanente des versions de librairies les plus récentes pour mettre à jour votre fichier package.json, npm met à disposition l’outil npm-outdated qui se charge d’analyser vos dépendances et de vous indiquer celles qui ne sont plus à jour.

npm-outdated

L’outil npm-outdated s’utilise très simplement en l’appelant de la façon suivante:

npm outdated --depth=0

Et produira la sortie ci-dessous:

npm-outdated

Les versions plus anciennes de l’outil ne produiront pas de sortie colorisée, il est donc intéressant de monter de version. La version de npm utilsée ici est la 1.4.9.

npm-outdated analysera aussi bien vos dépendances standards que les dépendances de développement sans faire de distinction.

La sortie retournée par l’outil ne montre que les dépendances ayant une version dépassée. Vous ne verrez donc pas les dépendances ayant une version à jour.

3 versions différentes sont renseignées: Current, Wanted et Latest. Ces versions représentent respectivement la version courante, puis la dernière version à jour correspondant au pattern de version déclaré pour votre dépendance dans le fichier package.json, et enfin la dernière version disponible de la librairie.

Option depth

Le paramètre –depth=0 permet de se limiter aux dépendances directes sans se soucier des dépendances tirées par les librairies elles-même tirées par vos dépendances directes.

Si nous utilisons le paramètre –depth=2, les dépendances indirectes commenceront alors à être matérialisées dans la sortie de l’outil:

npm-outdated-depth-1

Option json

Le paramètre –json permet quant à lui d’obtenir une sortie JSON. Cette option est particulièrement pratique pour exploiter l’information produite dans des rapports de build par exemple, ou bien pour être exploiter par d’autres outils.

En exécutant la ligne de commande suivante:

npm outdated --depth=0 --json

Vous obtiendrez la sortie suivante:

{
  "coffee-script": {
    "current": "1.6.3",
    "wanted": "1.6.3",
    "latest": "1.7.1",
    "location": "node_modules/coffee-script"
  },
  "passport-local": {
    "current": "0.1.6",
    "wanted": "0.1.6",
    "latest": "1.0.0",
    "location": "node_modules/passport-local"
  },
  "uglify-js": {
    "current": "2.4.13",
    "wanted": "2.4.14",
    "latest": "2.4.14",
    "location": "node_modules/uglify-js"
  }, ...
}

npm-update

Maintenant que vous connaissez les dernières versions disponibles, vous souhaitez peut-être en mettre certaines à jour. Pour cela, vous pouvez utiliser l’outil npm update.

Pour mettre à jour la librairie request, il faudrait exécuter la commande suivante:

npm update request

Badges pour votre repository GitHub

Le projet David vous permet de générer des badges indiquant si les versions de vos librairies sont à jour ou bien dépassées.

Ce projet est particulièrement intéressant car, non seulement, il génère des rapports pour votre projet sans que vous ayez à lever le petit doigt, mais il génère également des badges que vous pouvez exposer les pages de votre projet permettant d’indiquer l’état des versions de vos dépendances.

Pour exemple, pour savoir si le projet gtfs-playground a les versions de ses dépendances à jour, vous pouvez vous rendre sur la page suivante: https://david-dm.org/akinsella/gtfs-playground

L’outil fonctionne exclusivement avec les repositories Github. Pour construire un rapport pour votre projet, il suffit de renseigner votre organization et du nom de votre repository dans l’url suivante avant de l’appeler:

https://david-dm.org/<organization>/<repository>

De même, pour obtenir le badge correspondant à votre projet, il suffit de construire la balise img comme suit:

https://david-dm.org/<organization>/<repository>.<extension>

Ce qui donne le résultat suivant pour le format png:

gtfs-playground-png

Et pour le format svg:

gtfs-playground-svg

Conclusion

L’écosystème Node.js évolue rapidement. Les librairies proposent donc régulièrement de nouvelles fonctionnalités ou bien encore des corrections de bug. Il ne faut donc pas hésiter à mettre à jour ses librairies.

Attention cependant à ne pas non plus se précipiter et installer une version de librairie qui ne serait plus compatible avec votre code ou bien encore d’installer une version buggée. Il faut donc penser à faire tourner ses tests pour s’assurer qu’aucune regression n’impacte votre base de code.

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.