Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Node.js
  3. Concepts
Extrait - Node.js Exploitez la puissance de JavaScript côté serveur
Extraits du livre
Node.js Exploitez la puissance de JavaScript côté serveur
1 avis
Revenir à la page d'achat du livre

Concepts

Introduction

C’est à partir d’ici que débute la véritable plongée au cœur de Node. Dans ce chapitre, vous aborderez le vocabulaire, les outils et les concepts qui composent cette plate-forme. La première partie aborde les modules, qui sont l’ossature de Node, puis la suivante détaille ensuite ses variables globales.

Enfin, nous verrons le concept de programmation asynchrone, essentiel dans Node : vous allez en effet forcément l’utiliser.

Modules

Les modules sont les unités de base de l’organisation du code dans Node. À tel point que tout fichier JavaScript constitue un module. Cette notion est réellement centrale : c’est même ce qui fait de Node un bel exemple de la programmation orientée composant, avec tous ses avantages.

Dans chaque module, il y a un objet global module qui le décrit. Cet objet possède plusieurs propriétés :

  • id : identifiant du module (souvent la même valeur que filename).

  • filename : chemin absolu du module.

  • loaded : booléen indiquant si le module est complètement chargé.

  • parent : le module qui a requis le module en question (le premier module parent du moins, en cas de dépendances multiples).

  • children : la liste des modules requis par le module en question.

Il y a également la propriété exports : elle contient la valeur qui est retournée lorsque le module est requis. Cette dernière est modifiable et peut contenir n’importe quelle valeur en JavaScript. Par exemple le module suivant exporte tout simplement la valeur 42 :


module.exports = 42;
 

Par défaut, cette propriété est initialisée à un objet vide ({}) qui peut être utilisé pour exporter plusieurs valeurs.

Il est à noter aussi qu’il existe une variable globale exports pointant sur le même objet que module.exports et qui peut être utilisée :


// Plus grand dénominateur commun utilisant l'algorithme d'Euclide.  
function gcd(a...

Variables globales

En plus des variables globales définies par ECMAScript 5 (la spécification de JavaScript) comme Boolean et Date, Node définit les variables suivantes, accessibles dans tous les modules.

1. global

Cet objet représente le contexte racine du fichier courant, un peu comme l’objet window dans un navigateur.


console.log(foo);  
//   undefined  
  
  
global.foo = 'bar';  
  
console.log(foo);  
//   bar
 

En dehors de l’aspect amusant de créer des variables à la volée, il est plutôt déconseillé de modifier global directement : cela nuit à la compréhension du code, et par conséquent, personne ne procède de cette manière.

2. process

L’objet process représente le processus courant, il contient un certain nombre d’informations concernant par exemple la version de Node utilisée ou bien l’environnement d’exécution.

a. Événements

exit : émis juste avant l’arrêt de Node, cet événement permet d’effectuer d’ultimes actions. Attention : aucune action asynchrone n’est exécutée, le code doit être synchrone !


process.on('exit', function () {  
    console.log('le programme se termine');  
});
 

uncaughtException : émis quand une exception n’a pas été rattrapée, cet événement permet d’effectuer les actions nécessaires comme afficher un message d’erreur et fermer proprement les ressources. Il est important de noter que Node est à ce moment-là dans un état instable et qu’il est plus que conseillé d’arrêter le processus courant.


process.on('uncaughtException', function (exception) {  
    console.error('Erreur', exception);  
  
    process.exit(1);  
});
 

b. Signaux

Les signaux système sont également notifiés via des événements :


// Ce signal est couramment utilisé pour indiquer à un programme  
// de recharger sa configuration.  
process.on('SIGHUP', function () {  
    console.log('Rechargement...

Programmation asynchrone

La plupart des situations concrètes en programmation sont limitées par les entrées/sorties et non par le CPU. Et justement JavaScript propose une solution intéressante : les événements, JavaScript n’étant pas pourvu du concept de threads.

Node lui-même utilise parfois des threads de façon interne pour gérer les entrées/sorties. Néanmoins ceux-ci ne sont pas exposés du côté du JavaScript.

Pour certains, ne pas posséder de threads est archaïque. Pourtant en y regardant de plus près, on peut remarquer que ces derniers sont très difficiles à manipuler pour plusieurs raisons :

  • Les accès aux données partagées doivent être protégés par des verrous.

  • Tout oubli dans le code (autrement dit chaque bug introduit) peut induire une corruption de données.

  • Un verrouillage mal géré peut mener à des interblocages.

En outre se posent des problèmes de performances : activer et désactiver des verrous est très coûteux en termes de ressources. De plus, en cas d’utilisation massive de threads, le système d’exploitation les interrompt constamment pour passer la main au suivant dans la liste, ce qui pose des problèmes de performances.

Ne sous-estimez pas l’impact des threads sur la consommation globale de ressources. Si vous utilisez des services de Cloud facturés à l’utilisation, vous pouvez faire de réelles économies, souvent de l’ordre de 20 %, en fonction de vos types d’applications bien entendu.

C’est aussi ça le secret des performances de Node, car il n’est pas affecté par ces problématiques. Explorons maintenant plus en détail le comportement de JavaScript.

Tout d’abord, contrairement aux threads, Node se base sur un modèle coopératif et non préemptif : il n’y a pas d’interruption au milieu d’une tâche. Au passage, vous éliminez les problèmes de synchronisation (par exemple, avec les verrous). À l’inverse, vous perdez la concurrence du CPU : c’est pourquoi Node n’est pas forcément adapté aux programmes nécessitant des calculs intensifs. Ceci dit, il reste possible de lancer une autre instance...