node monfichier vs npm run monscript
Depuis la console, il est possible de lancer les applications Node.js de deux manières soit en usant de Node, au travers de l’instruction node fichier.js
ou alors depuis NPM en employant npm run lescript
. L’un comme l’autre possède certaines particularités que nous allons essayer de démystifier au travers de cet article.
node application
Avec cette instruction, il suffit de pointer vers le fichier, ou le package, à exécuter et le cas échéant d’ajouter autant de paramètres que nécessaire. Ces paramètres peuvent être de diverses natures;
- soit propres à node (-f pour forcer l’application à s’exécuter, -g pour être globalisé, etc…), il s’agit d’options,
- soit propres à chaque application (–output-style, –source, etc…), il s’agit d’arguments,
- ou propre à des propriétés internes qui seraient transmis (–argument, etc…), là encore il s’agit d’arguments.
Au niveau de l’écriture, depuis la console, cela se traduit sous la forme suivante;
node options fichier.js argumentA argumentB ...
Mettons tout cela en application au travers de quelques exemples. Préparons un dossier de projet, Projet-Node par exemple, plaçons le pointeur de l’invite de commande sur ce dossier, lançons une initialisation de projet avec npm init -y
.
Créons et enregistrons un simple fichier base.js qui va nous servir de passerelle de travail. Ajoutons y le contenu console.log("fichier base");
.
L’idée va donc être d’invoquer ce fichier et de lui transmettre un ensemble de paramètres. En ce qui concerne les options transmises à Node.js je vous invite à vous rapprocher de la documentation. Concentrons nous sur la transmition et la récupération d’arguments. Depuis la console, validons la ligne suivante ;
node base argumentA argumentB argumentC
L’application se lance, et affiche son message, mais nous n’avons aucune information relatives au passage d’arguments. Rien ne nous indique s’ils ont été transmis.
Pour suivre les arguments, nous allons employer l’objet global process et plus particulièrement sa propriété argv. L’objet process fournis toute une série d’informations, et d’écouteurs d’événements, concernant le processus Node.js en cours. Sa propriété argv renvoie la ligne de commande sous forme de tableau (array). Modifions le fichier base.js afin d’explorer le tableau renvoyé par process.argv.
process.argv.forEach((val, index) => { console.log(`${index}: ${val}`); });
À y regarder de plus près, les deux première valeurs du tableau (0 et 1) renvoient respectivement, le chemin d’accès à l’exécutable et le fichier JavaScript invoqué. Il nous faut donc, avant d’entamer la boucle d’itération, retirer ces deux premiers éléments du tableau pour ne conserver que les arguments:
var args = process.argv.slice(2) args.forEach((val, index) => { console.log(`${index}: ${val}`); });
Indexons les tableaux d’arguments
Les arguments sont renvoyés en tant que tels, les uns à la suite des autres, et indexé sur un simple tableau (0, 1, 2….), il n’est donc pas possible de travailler avec un tableau indexé. Si tel est le besoin, nous pouvons alors, nous appuyer sur le package, minimist, intégré à Node.js qu’il nous suffit alors de charger. Les arguments peuvent être ainsi passé sous la forme de propriété valeur séparés par un simple espace. La propriété est indiquée en usant d’un tiret devant son nom.
node base -a valeur argumentA -b 46 argumentB argumentC
Attention cette fois-ci il ne faut plus employer de boucle pour parser les arguments, mais simplement les invoquer. Minimist s’occupe de tout, y compris de gérer l’ensemble des arguments qui sont transmis sans préciser de propriété d’indexation, et qui sont ajoutés à une liste _:[]. Modifions le code du fichier base.js avec le code suivant:
var minimist = require('minimist'); var args = minimist(process.argv.slice(2)); console.log(args); console.log(args['a']); console.log(args['_'][1]);
npm run lescript
NPM le gestionnaire de paquets employé par Node peut également être invoquer depuis la console de commande aussi bien pour installer des modules que pour lancer des scripts définis dans le fichier package.json. Pour mieux en comprendre les intérêts, installons un module qui nous servira d’exemple, prenons au hasard node-sass qui permet tout simplement de compiler des fichiers .scss ou .sass en fichier .css. Lors de l’installation, demandons l’installation globale de ce modulenpm install -g node-sass
, ce qui en facilitera son utilisation ultérieure.
Pour travailler avec ce module, nous avons besoin de deux dossiers, sources et sortie. Créons donc à la racine du dossier projet, ces deux dossiers, nommons les respectivement sources (qui va contenir les fichiers .scss) et css (qui recevra les fichiers .css compilés). Plaçons également un fichier styles.scss dans le dossier sources et qui sera utilisé pour la compilation. À titre de test, nous pouvons simplement y coller le contenu de reset proposé par Eric Meyer, CSS Tools: Reset CSS.
Maintenant, comme à l’habitude, depuis la console de commande nous allons pouvoir invoquer notre module et lui passer un certain nombre d’arguments. Rapprochons nous de Command Line Interface afin de consulter l’ensemble des options disponibles depuis la commande. En ce qui nous concerne, et pour l’exemple de cet article, optons pour les options suivantes. Bien sûr que cela est purement arbitraire:
- –output-style CSS output style (nested | expanded | compact | compressed)
- –indent-type Indent type for output CSS (space | tab)
- –indent-width Indent width; number of spaces or tabs (maximum value: 10)
Ce qui donnerait lieu à deux types de ligne de commande possibles, une première utilisable en développement avec l’ensemble du code étendu et indenté de manière précise, et, une seconde uniquement nécessaire lors de la mise en production des fichiers qui au contraire compacterait l’ensemble des codes. Bien évidement, l’une comme l’autre doivent également mentionner, en complément des options, le chemin d’accès au(x) fichier(s) source(s) et le chemin du fichier de sortie.
node-sass --output-style expanded --indent-type tab --indent-width 2 sources/styles.scss css/styles.css
node-sass --output-style compressed sources/styles.scss css/styles.css
Tour à tur, exécutez les deux lignes de commandes et à chaque fois ouvrez le fichier généré dans un éditeur de code pour en vérifier le résultat. Vous constaterez qu’en mode production, le fichier est compacté et ne contient plus de commentaires. Ce qui est attendu afin de gagner du poids lors du chargement.
Tout fonctionne comme attendu, mais cependant cela reste des lignes de commandes qui sont assez verbeuses et qui peuvent être lourdes à gérer si on doit les répéter fréquemment. C’est là que vont intervenir les scripts NPM.
Ces scripts se placent dans le fichier package.json et sont contenus dans la propriété « scripts ». Il s’agit d’un objet de type json qui peut être complété d’autant de valeurs que nous avons besoin pour notre notre projet. Par défaut celle-ci contient déjà une valeur « test » qui a été généré lors de l’initialisation du projet.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
Nous pouvons retirer cette valeur, et ajouter nos deux nouveaux scripts qui vont simplement reprendre nos ligne de commandes. Nommons le premier « dev » et le second « prod ». Il est important de préserver l’ensemble des propriétés et des valeurs entre double quote. N’oubliez surtout pas d’échapper d’éventuels double quote qui serait contenu dans la ligne de commande, comme nous pouvons le voir dans la propriété « test » de la valeur par défaut.
Tout est en place il ne nous reste plus qu’à invoquer les scripts. Avant cela, assurez vous que le fichier package.json soit bien enregistré et prenez le temps de supprimer le fichier de sortie styles.css afin de vérifier le bon fonctionnement de l’appel des scripts. Une fois prêt, retournez dans la console.
Pensez à vérifier entre chaque lancé de script que les modifications soient bien prises en compte et se reflètent dans le fichier de sortie. L’ensemble de ces scripts ont été donnés à titre d’exemple afin de faire ressortir la manière de les employer. Libre à vous de les adapter et de les affiner pour mieux servir vos propres flux de travail.