Automatiser l'installation des dépendances avec NPM

Les nouveaux outils tels que Gulp Grunt ou Bower, sont à installer de manière globale sur le poste de travail du développeur.

Si le projet sur lequel le développeur doit travailler est dépendant de Gulp, Bower, Bower-installer, Tsd et Flatten-packages par exemple, il va devoir s'assurer que ces plugins soient bien installés de manière globale.

Afin d'éviter cette tâche rébarbative, il est possible d'exploiter la section scripts du fichier package.json.

Cette section permet de déclarer un lot de commandes à exécuter suivant des évènements déclenchés par NPM.

Nous allons ici exploiter les commandes preinstall et postinstall afin d'installer l'environnement de développement lorsque le développeur exécute la commande : npm install.

Ci-dessous, la configuration du package.json nous permettant de réaliser ce type d'installation :

{
    "name": "npm-env-installer",
    "private": true,
    "version": "0.0.0",
    "description": "Use the scripts section of the NPM file to install your dev env.",
    "repository": { "type": "git", "url": "https://github.com/pagury/npm-env-installer" },
    "license": "MIT",
    "dependencies": {
    },
    "devDependencies": {
        "gulp": "^3.8.11"
    },
    "scripts": {
        "preinstall": "node ./npm-pre-install.js",
        "postinstall": "node ./npm-post-install.js"
    }
}

La section scripts contient 2 propriétés, preinstall et postinstall qui sont exécutées avant et après chaque exécution de la commande npm install.

Elles exécutent un script node.js situé au même niveau que le fichier package.json au sein de la solution.

Ci-dessous, le fichier npm-pre-install.js :

var exec = require("child_process").exec;
var install = function (command) {
    console.info(fileName, "Started : ", command);
    var output = exec(command).output;
    if (output) {
        console.info(output);
    }
    console.info(fileName, "Finished : ", command);
};

var fileName = "[npm-pre-install]";

install("where flatten-packages /q nofile || npm install flatten-packages -g");
install("where gulp /q nofile || npm install gulp -g");
install("where bower /q nofile || npm install bower -g");
install("where bower-installer /q nofile || npm install bower-installer -g");
install("where tsd /q nofile || npm install tsd -g");

Ce fichier exploite le module child_process natif à node.js. La fonction install déclenche une commande sur le système courant. Il est alors très simple de détecter si la commande globale existe. Si ce n'est pas le cas, il suffit de déclencher une installation globale via NPM.

Le fichier npm-post-install.js permet quant à lui de préparer l'environnement après installation des packages globaux et des packages locaux.

var exec = require("child_process").exec;
var install = function (command) {
    console.info(fileName, "Started : ", command);
    var output = exec(command).output;
    if (output) {
        console.info(output);
    }
    console.info(fileName, "Finished : ", command);
};

var fileName = "[npm-post-install]";

install("bower-installer install -r");
install("flatten-packages");

Ici, bower-installer est déclenché afin de mettre en place l'arborescence des librairies JavaScript clientes au sein du projet. La commande flatten-packages permet ici "d'aplatir" les dépendances stockées au sein du dossier node_modules afin d'éviter des erreurs dû à une trop grande profondeur de dossiers (notamment dans le cas d'un développement d'application Cordova).

Vous pouvez retrouver les sources à cette adresse :
https://github.com/pagury/npm-env-installer

Petite astuce finale, il est parfois utile de déplacer le dossier node_modules afin d'éviter qu'il soit embarqué dans le package final après une compilation d'application Cordova. Il est donc utile de déplacer celui-ci avant et après chaque exécution de la commande npm install.

npm-pre-install.js

IF exist ../node_modules ( move ../node_modules ./node_modules )

npm-post-install.js

move ./node_modules ../node_modules

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus