Après vous avoir appris à développer vos premières applications de manière assez classique, nous nous portons vers une solution plus inhabituelle. Nous utiliserons pour cela JavaScript et Node.js pour un résultat multiplateforme.
Lorsqu’on cherche à présenter Node.js à des utilisateurs n'ayant jamais mis le nez dans cette plateforme, il est de bon ton de commencer par un tutoriel vous expliquant comment créer un serveur web en quelques lignes de code.
N'ayant jamais vraiment compris l’intérêt de commencer par cette étape, nous allons procéder autrement pour vous faire comprendre (un bout de) ce que permet cette solution, qui a révolutionné le petit monde de JavaScript il y a presque 10 ans.
Pour tout dire, l’exemple choisi sera sans doute considéré comme le pire croisement de choix possible pour un développeur en 2018. Mais après tout, la beauté du développement logiciel et la liberté donnée par un langage tel que JavaScript, c’est aussi ça.
Node.js, c’est quoi ?
Commençons par quelques bases. JavaScript est un langage qui s’exécute côté client. Il est interprété par votre machine, le plus souvent via votre navigateur, et non côté serveur comme c’est le cas pour PHP.
Créé en 1995 par Brendan Eich, il a fortement évolué depuis et a même été standardisé dès 1997 sous la forme d’ECMAScript. Il est simple à prendre en main, dispose de grandes possibilités, mais surtout d’une très large communauté tant il est au centre du web actuel.
Il a été pensé pour s’exécuter au sein d’une page web pour la rendre dynamique, et pas comme un langage de script à part entière tel que Python, Ruby ou PowerShell. Pour cela, il lui manquait un environnement d’exécution (ou runtime). C’est ce que lui a apporté Node.js.
Cette plateforme open source se base sur le moteur V8 de Chrome/Chromium. Mais plutôt que de le mettre à disposition d’un navigateur côté client, il permet une exécution au sein de n’importe quelle machine et donc côté serveur. Le tout, avec une architecture orientée évènements, capable de gérer un grand nombre d’accès asynchrones en simultané.
Vous pouvez donc faire fonctionner un programme JavaScript comme n’importe quelle autre application. Comme nous allons le voir, il est même possible de le compiler désormais, pour l’utiliser de manière indépendante dans différents systèmes d’exploitation. Mais pas sans quelques sacrifices.
Un IDE et c’est parti !
La première chose à faire pour commencer à exploiter Node.js est de l’installer sur votre machine. Deux branches sont disponibles : Current (10.x actuellement), avec toutes les dernières fonctionnalités, et LTS (8.x actuellement) qui se veut stable et suivie à long terme. Nous opterons pour cette dernière.
Des binaires sont disponibles pour Linux (ARM et x86), macOS ou Windows, ainsi que des plateformes moins courantes comme SunOS. Une image Docker est également fournie.
Une fois l’installation terminée, il nous faut un éditeur pour créer notre première application. Nous utiliserons Visual Studio Code, mais vous pouvez choisir ce que bon vous semble. Nous vous conseillons tout de même un IDE qui dispose d’outils pensés pour les développeurs et d’un terminal. Atom peut être une bonne alternative.
Une fois dans l’interface, créons un fichier hello.js
pour y taper la ligne suivante :
console.log("Hello, world !");
Une fois le fichier enregistré, il suffit de l’exécuter. Rendez-vous dans le terminal (CTRL+ù), dans le dossier où se situe le fichier, et lancez la commande suivante :
node hello.js
Le résultat devrait simplement afficher le texte « Hello, world ! » et revenir à la console :
C’est quand les vacances ?
Procédons maintenant à un essai un peu plus complexe : afficher le temps restant avant les vacances, en partant du principe qu'elles débutent le 15 juillet 2018.
Commençons par créer trois constantes : une contenant la date de nos vacances, une autre la date du jour et une dernière le délai entre les deux. Une fois leur valeur récupérée, elle sera affichée :
const dateVacances = new Date('2018-07-15');
const dateAjd = new Date();
const timeZone = dateAjd.getTimezoneOffset();
const delai = dateVacances - dateAjd + (timeZone * 60 * 1000);
console.log(dateVacances);
console.log(dateAjd);
console.log(delai);
Il suffit là encore de tester le résultat dans la console de notre IDE via la commande node hello.js
. Par défaut, le délai entre deux dates est renvoyé sous forme d'une valeur en millisecondes. On y ajoute le décalage horaire issu de la zone géographique qui est, elle, renvoyée sous forme d'une valeur en minutes.
Pour obtenir un résultat plus présentable, il nous faut calculer le nombre de jours, de semaines et de mois qui nous séparent de la date fatidique. Pour cela, nous allons ajouter la portion de code suivante :
const jours = Math.round(delai / 1000 / 3600 / 24);
const semaines = Math.round(delai / 1000 / 3600 / 24 / 7 * 10) / 10;
const mois = Math.round(delai / 1000 / 3600 / 24 / 365 * 12 * 10) / 10;
console.log(jours);
console.log(semaines);
console.log(mois);
Via la méthode
, nous obtenons des arrondis sous forme d’un entier. Pour obtenir un résultat à une décimale près, nous multiplions la valeur par dix avant de la diviser par dix une fois l’arrondi calculé.Math.round()
Nous pouvons désormais afficher notre résultat sous forme d’une phrase avec la ligne suivante :
console.log(`J-${jours} avant les vacances, soit ${semaines} semaines ou ${mois} mois`);
Cette méthode un peu simpliste a néanmoins quelques effets négatifs : si la date est passée, une valeur négative sera affichée, le pluriel n’est pas pris en compte, ainsi que les cas de dates proches de celle de nos vacances.
Nous allons donc définir trois cas spécifiques via des phrases prêtes à utiliser :
const stringTropTard = "Le début des vacances, c'était avant !";
const stringAjd = "Le début des vacances, c'est maintenant !";
const stringDemain = "Le début des vacances, c'est demain !";
Nous établissons également une série de règles pour définir la phrase finale, affichée une fois la situation analysée :
let stringFinale;
if (jours < -1) stringFinale = stringTropTard;
else if (delai < 0) stringFinale = stringAjd;
else if (jours < 2) stringFinale = stringDemain;
else
{
stringFinale = `J-${jours} avant les vacances`;
if (semaines >= 2 || mois >= 2) stringFinale += ", soit ";
if (semaines >= 2) stringFinale += `${semaines} semaines`;
if (semaines >= 2 && mois >= 2) stringFinale += " ou ";
if (mois >= 2) stringFinale += `${mois} mois`;
stringFinale += " !";
}
console.log(stringFinale);
Ici, notez l’utilisation du mot-clé let
plutôt que const
pour la variable stringFinale
. La raison est simple : sa valeur va être modifiée. On évite également la question du pluriel en ne prenant en compte le nombre de jours ou de semaines que si leur valeur est supérieure à 2.
On peut désormais nettoyer notre code en supprimant toutes les lignes contenant la méthode console.log()
, excepté la dernière qui affiche le résultat final. On peut aussi commenter ces lignes afin de pouvoir les réutiliser plus tard si nécessaire.
Et si on rendait le tout indépendant ? Merci npm et pkg
Notre petite application fonctionne bien dans un terminal, sur n’importe quelle plateforme. Mais pour l’exploiter il faut que Node.js soit installé, ce qui n’est pas simple pour la distribution et l'utilisation par un tiers.
Il nous faut alors créer un package intégrant l'environnement d'exécution. Il n’existe pas d’outil livré avec Node.js pour cette action, mais d'autres permettent de le faire. C’est notamment le cas de pkg, diffusé sous licence MIT et encore développé aujourd’hui. Son installation est simple grâce au gestionnaire de paquets de Node.js : npm.
Il suffit de taper la commande suivante dans le terminal de l’IDE :
npm install -g pkg
Les fichiers nécessaires seront téléchargés et installés, vous n’aurez ainsi plus qu’une ligne de commande à taper pour créer une version Linux, macOS et Windows :
pkg hellos.js
Trois fichiers sont créés : hello-linux
, hello-macos
et hello-win.exe
. Les deux premiers pèsent à peu près 35 Mo, 22 Mo pour le dernier… contre 1 ko pour le fichier de départ. L’environnement d’exécution intégré occupe en effet un minimum de place et ne permet pas d'obtenir un fichier plus compact.
On notera également que le résultat n’est pas affiché de manière instantanée, ce qui montre une certaine « lourdeur » par rapport à une application compilée, exploitant C++/C# par exemple.