Gérer ses dépendances optionnelles

On a parfois des dépendances qui améliorent le fonctionnement de notre module, sans être pour autant obligatoires.

Par exemple, le module redis peut être accéléré par l’utilisation de hiredis (un parseur écrit en C, donc compilé lors du npm install). Pour gérer ça, il est indiqué dans le README qu’on peut installer hiredis si on veut que ça aille plus vite, mais que ça marchera sans.

Concrètement dans le code du module reposant sur une dépendance optionnelle, on aura ce genre de lignes :

// Load optional dependency
function require_optional (name) {
  try {
    // Try normal require
    return require(name);
  } catch (e) {
    // Something went wrong :(
    if (e.code == 'MODULE_NOT_FOUND') {
      // Special case "module not found": we just ignore this error
      return undefined;
    } else {
      // This is an other unexpected error
      throw e
    }
  }
}
 
// Somewhere in my module
var the_module = require_optional('the_module');
// …
if (the_module) {
  // use "the_module" to enhance my code
}

Mais pourquoi avoir des dépendances optionnelles ? Si c’est mieux avec autant l’inclure d’office ! deux bonnes raisons :

  • Le module peut ne pas compiler (par exemple hiredis ou msgpack ne se compilent pas très bien d’office sous Windows…) ;
  • C’est quelqu’un d’autre qui gère ce module, s’il lui prend l’envie de le renommer ou de le supprimer et que mon installation par conséquent peut échouer du jour au lendemain… autant pour une dépendance sans laquelle mon application ne peut pas marcher, je peux tolérer que ce soit fatal, autant pour une dépendance dont je pourrais clairement me passer c’est dommage de planter toute l’installation pour ça ;

Dans le cas de redis ils gèrent ça manuellement en nous disant simplement d’installer hiredis si on veut. Une autre manière aurait été d’utiliser les dépendances optionnelles du package.json. Pour ajouter une dépendance optionelle à votre module, ça se passe donc dans la section optionalDependencies, qu’on peut enrichir comme on s’en doute directement avec npm :

$ npm install --save-optional hiredis
 
$ git diff
…
+  "optionalDependencies": {
+    "hiredis": "~0.1.15"
+  }

Si le prochain qui fait le npm install est sous une machine sous Windows inutilisable où la compilation de hiredis échoue, ce n’est pas grave : il en sera notifié mais le reste de l’installation continuera.

La prochaine fois que vous vous dites que vous pouvez optimiser votre sérialisation avec msgpack, pensez à vos amis sous Windows, utilisez optionalDependencies et un petit require_optional() :)

2 réflexions au sujet de « Gérer ses dépendances optionnelles »

    1. naholyr Auteur de l’article

      « require_optional » n’existe que si on la code 😉 néanmoins le principe est simple.

      Un peu comme un « require_nocache » d’ailleurs qui n’est pas bien plus compliqué à obtenir.

      Répondre

Laisser un commentaire