LOGO Lionel Groulx

Site Web du cours « Programmation de Systèmes »

Node.js Chapitre 1
Introduction au langage :

1.1.   Qu'est-ce que JavaScript ?

- JavaScript est un langage de Script. Ou plus précisément il s’appuie sur la compilation « à la volée » (Just In Time ou JIT).

- JavaScript est un langage orienté objet, à prototype (sans classe, et avec héritage dynamique)

- JavaScript est surtout utilisé dans la programmation Web, tout autant du côté client (pages interactives) que du côté serveur (avec Node.js justement).

- Il est standardisé (ECMA 262)

- Il peut être utilisé dans une page Web : JavaScript peut être intégré directement dans le HTML et dans ce cas sera exécuté par le Navigateur (on dit dans ce cas « côté client »).

- Il peut être utilisé dans un serveur Web http, comme PHP ou ASP. Pour ce faire, on utilise node.js, un projet indépendant et Open Source d'implémentation de serveurs en JavaScript (on dit dans ce cas « côté serveur »).

- Bien que « scripté », ses performances sont exceptionnelles depuis que Google a intégré le moteur V8 dans Chrome, qui fait office de machine virtuelle, pour s’occuper de ces scripts. Par effet boule de neige, ses performances sont accrues chez Mozilla, et Microsoft, qui veulent rester dans la concurrence.

Ses avantages :

- Un langage unique, autant du côté serveur que du côté client : favorise le partage de code.

- JSON est un format d’échange de données très populaire, il est natif JavaScript.

- JavaScript est le langage utilisé par les bases de données NoSQL, de plus en plus populaires.

- De plus en plus de langages en expansion se « compilent » en JavaScript, qui devient une plateforme commune.

- Node.js est parfait pour concevoir des applications web dites « DIRTy » (« data-intensive real-time »). Exemple : une page de « chat ». 

1.2.   Qu'est-ce que node.js ?

Node.js permet d’exécuter du JavaScript pour créer une plateforme de serveur Web, sans avoir recours à des logiciels externes comme Apache.

C’est une plateforme polyvalente de développement d'applications réseau gratuite d’utilisation se basant sur le moteur JavaScript V8 (développé par Google).

Ainsi, le JavaScript est interprété sur le serveur, pour générer des pages Web dynamiques, AVANT d’être envoyées au client (voir détails sur le Web dynamique : référentiel PHP, Chapitre 1).

Node.js est la technologie de serveur Web utilisée entre autres par les sites de compagnies comme : Youtube, Yahoo, Amazon, Netflix, eBay, Reddit, LinkedIn, Paypal, Groupon ou Walmart.

Il bénéficie d’un écosystème très riche : on peut faire appel à des modules sous forme de « paquets » via un gestionnaire de dépendances appelé « NPM ».

Créé en 2009, il est accessible depuis le célèbre site GitHub (voir références), où il est le second projet le plus suivi. C’est un signe de sa popularité.

Node.js exploite JavaScript de façon asynchrone, événementielle et non-bloquante.

Notion d’asynchrone, d’évènementiel et code non-bloquant :

Node.js s’appuie sur le paradigme de langage dit « événementiel ». Contrairement à la programmation dite « séquentielle », ou concurrentielle, l’événementiel se visualise comme chaque action en conséquence d’un événement de déclenchement. Comme Qt et l’exploitation des événements (avec les « signals » et les « slots »).

Le caractère « asynchrone » de Node.js se traduit par le fait que celui-ci « surveille » toute activité liée à des données qui entrent ou sortent du programme (les « I/O », ou « événements »). Celui-ci ouvre la porte à son aptitude à ne pas « bloquer » son exécution.

En effet, en étant « non-bloquant », Node.js ne s’exécute pas forcément de haut en bas. Chaque événement déclencheur est surveillé en « parallèle », et celui du dessous peut très bien s’exécuter avant celui au-dessus, si l’événement lié tombe avant. 

Exemple :

Une structure de programme suivant un Modèle bloquant serait :

Télécharger une image

Afficher l’image

Écrire « coucou »

Dans ce cas, le programme attendra d’avoir terminé le téléchargement, PUIS de l’afficher, et ENFIN écrira « coucou ».

En opposition, une structure de programme suivant un modèle non-bloquant serait :

Télécharger une image

Quand le téléchargement est terminé, Afficher l’image

Écrire « coucou »

Ici, le programme écrira « coucou » AVANT que le téléchargement se termine, mais APRÈS qu’il ait commencé.


Node.js, combinant ces 3 aspects, devient très intéressant pour réaliser une plateforme de serveur Web : il peut gérer des applications « temps-réel » de façon bien plus efficace.

En effet, constamment à l’écoute des « I/O » (ou événements déclencheurs), il peut paralléliser les exécutions, sans bloquer. C’est ce qui fait sa force comparativement à un serveur en PHP. On dit que Node.js est parfait pour réaliser une application serveur qui « peut monter en charge ». De plus, tout se réalise dans une seule tâche programme, sans faire appel à des mécanismes complexes de multitâche.

L’aspect événementiel du Node.js se matérialise concrètement dans le code par le système de callbacks. Voici un exemple de code qui illustre le mécanisme de « callback » (« fonction de rappel » en français) de Node.js :

Ici, on remarque :

- console.log permet d’afficher du texte sur la console « serveur ».

- la fonction request lance un téléchargement.

- le mot-clé function : cela créée une fonction ANONYME.

- la fonction « function » est placée en paramètre du request : c’est ce qu’on appelle un CALLBACK. JavaScript permet de mettre des fonctions comme paramètre, comme une variable.

- le CALLBACK, (qui contient ici le premier console.log), se déclenchera quand le téléchargement sera terminé.

- ATTENTION à bien comprendre la succession des symboles fermants, ligne 3. Au besoin, décomposez-les. Mais à la longue, vous vous habituerez :

                - L’accolade ferme le corps de la fonction anonyme

                - la parenthèse ferme la commande request

                - le point-virgule est celui de la commande request

Il est hautement conseillé de suivre ce modèle de présentation (symboles fermants ET indentation) pour vos futurs programmes Node.js

Une écriture plus détaillée du programme ci-dessus donnerait :

Les 2 programmes réalisent exactement la même chose. Ici cependant on créee nommément le callback, déclaré comme une fonction en lignes 3 et 4. On dit qu’elle est explicite, contrairement à l’exemple précédent, dans lequel notre fonction callback était implicite.

L’aspect non-bloquant ici se traduit par le fait que le téléchargement commence au même moment que le console.log en ligne 8 se réalise.

Nos expliquerons les paramètres (error, response, body) de la fonction anonyme en ligne 3 plus tard (voir chapitre 1.5).

Notes importantes :

- JavaScript est sensible à la casse, comme C

- une commande JavaScript peut se terminer par un point-virgule, comme en C, mais il est à noter que le retour charriot (retour à la ligne) peut le remplacer (mais ce n’est pas conseillé).

- JavaScript n’est pas sensible à l’indentation, comme C, et contrairement au python. Cependant ceux-ci sont fortement conseillés pour une pagination qui rend la lecture plus compréhensible.

- Les commentaires dans JavaScript se gèrent de la même façon que dans C :

- commentaire en bloc avec /**/

- commentaire ligne avec //


 1.3.   Installer Node.js

Node.js peut être utilisé sur Windows, Mac OS, et Linux.

Il s’installe très simplement : aller sur le site suivant pour télécharger le fichier d’installation voulu : http://www.nodejs.org

Une fois fait, vous disposez de 2 programmes :

- Node.js qui est l’interpréteur de commande, et qui est fort peu utilisé (pas du tout dans le cadre de ce cours)

- Node.js command prompt qui est la console système (Windows pour nous) qui est toute prête pour lancer des fichiers source Node.js 

1.4.   Exécuter un fichier js et faire des console.log :

Tout fichier possédant l’extension js sera vu comme un programme source à interpréter par JavaScript, et s’il est exécuté dans la console Node.js, il sera interprété comme du Node.js.

Ainsi, pour créer un programme Node.js il suffit de créer un fichier texte avec extension js et de l’éditer avec n’importe quel éditeur de texte (Notepad, Notepad++, Atom ou encore VS Code).

Atom présente les avantages d’être très léger, rapide à ouvrir, et de présenter la coloration syntaxique adéquate. VS Code bénéficie d’une foule de modules complémentaires très pratiques en programmation Web et autre.

Une fois le fichier créé, il s’exécute depuis la console Node.js en tapant « node ».

Exemple : Créons un fichier texte test.js contenant 1 seule ligne de texte :

console.log("Coucou !");

Puis exécutons le fichier dans la console avec la commande suivante (il faut être dans le bon dossier contenant le fichier test.js) :

node test.js


 1.5.   Créer mon premier serveur http

Voici le code « minimal » pour créer un serveur HTTP avec Node.js :

Essayons maintenant de comprendre ce code Node.js.

require est la commande qui fait appel à un Module (une bibliothèque) de Node.js. Le Module « http » permet de créer un serveur HTTP.

createServer est la méthode de l’objet http qui attend les accès au serveur : elle attend une connexion d’un client. Ici, ce « I/O » (événement déclencheur) est créé et stocké dans la variable server

La méthode est « connectée » avec une fonction anonyme. Ainsi, le contenu des accolades (lignes 4 à 6) s’exécutera à chaque fois qu’un client est connecté au serveur. C’est un CALLBACK par fonction implicite.

Dans l’exemple d’un callback lié à createServer, on a 2 paramètres, req et res :

req

Cet objet contient toutes les informations de l’origine du callback (« request »), ce qui l’a déclenché. Ici, cet objet contient le nom de la page demandée par le client, des champs de formulaire, des paramètres, le type de navigateur, etc…

Nous l’exploiterons plus tard.


res

C’est la réponse (« response »), la conséquence au callback. Ici, on renvoie des données au client :

res.writeHead

                Première réponse : on écrit un code HTTP au début de la page. 200 veut dire « tout va bien ». Plus de détails sur les codes HTTP : (voir références)

res.end

                Deuxième réponse (au même événement) : du texte brut, qui sera écrit dans la page, et qui clot la page.

C’est avec cette commande que l’on créée véritablement le serveur, et on lui dit d’écouter sur le port 8080. C’est le numéro de port à privilégier pour le DÉVELOPPEMENT d’un site. En exploitation, on utilise plutôt le port 80. Plus de détails sur les ports : (voir références)

Pour envoyer du vrai contenu HTML, on modifie le writeHead comme ceci :

Ceci permet d’indiquer au navigateur de traiter les chaînes de texte comme du HTML.

Autres possibilités (appelées les « type MIME ») :

"Content-Type" : "text/plain"   // pour du texte standard

"Content-Type" : "text/css"     // pour du code CSS

"Content-Type" : "image/jpeg"

"Content-Type" : "video/mp4"

Etc

Maintenant, on peut utiliser les balises HTML :

Avec ces nouveaux paramètres, notre navigateur interprète les balises HTML dans la chaîne de caractères envoyée par res.end et nous affiche un titre. L’utilisation de res.end peut être complétée avec celle de res.write. Exemple :