You are on page 1of 180

P R O G R A M M A T I O N A V E C

NODE JS

le guide complet - Practical Programming

Claudia Alves
( 2 e édition )
Programmation avec Node.js
Copyright © 2020 par Claudia Alves

Pour information contactez :


(alabamamond@gmail.com )
http://www.memlnc.com

Design de la couverture par memlnc

2 ème édition: 31 juillet - 2020


Qu'est-ce que Node.js? ............................................
.............................. 9
Comment installer Node.js?
.......................................... ............... 11
N ode Binaires vs Version Manager
……………………………………… 11
"Bonjour le monde!" la manière Node.js
………………………………………… 11
Node.js offre un excellent support pour le J avaScript
moderne ……… 12
Installation d'un package à l'échelle mondiale
………………………………………………… 14
jshint index.js
………………………………………………………
………………… .. 14
Installation d'un package localement
………………………………………………… .. 15
L'histoire de Node.js
………………………………………………………
………. 17
Les avantages de Node.js
……………………………………………………. 20
Un champ d'application pour Node.js
…………………………………………… 21
Le cœur - le moteur V8
………………………………………………… .. 23
Le modèle de mémoire
………………………………………………………
……… .. 24
Accès aux propriétés
………………………………………………………
………. 25
Génération de code machine
………………………………………………………
28
Collecte des ordures
………………………………………………………
………… 29
Bibliothèques autour du moteur
………………………………………………… .. 31
Boucle d'événement
………………………………………………………
……………………… .. 32
Entrée et sortie
………………………………………………………
……………. 34
Libuv
………………………………………………………
……………………………… .. 35
DNS
………………………………………………………
………………………………… 36
Zlib
………………………………………………………
………………………………… .. 37
Analyseur HTTP
………………………………………………………
………………… .. 38
Résumé
………………………………………………………
………………………… 38
CHAPITRE
1_______________________________________ 39
Installation des packages
………………………………………………………
… 41
Les
fenêtres………………………………………………
…………………………………. 46
Mac OS
X……………………………………………………
…………………………. 51
Compilez et installez
………………………………………………………
……… .. 60
Somme mary
......................................................................................
.... .. 63
CHAPITRE
2_______________________________________ 65
Le mode interactif
………………………………………………………
…… 66
La première application
………………………………………………………
……… 71
Résumé
………………………………………………………
………………… .. …… 82
Adaptation et expansion
…………………………………………………… 84
Modules Node.js
………………………………………………………
………… ,,, 85
Approche modulaire
………………………………………………………
………… 85
Indice de stabilité
………………………………………………………
……………… .. 87
Modules disponibles
………………………………………………………
………… 89
Test d'affirmation
………………………………………………………
…………… 91
Tampon………………………………………………
……………………………………. 92
Processus enfant
………………………………………………………
……………,…. 93
Cluster
………………………………………………………
…………………………… 93
Console………………………………………………
…………………………………. 94
Crypto
………………………………………………………
…………………………… 95
Débogueur
………………………………………………………
………………………. 96
Datagramme
………………………………………………………
………………………. 96
DNS
………………………………………………………
……………………………… .. 96
domaine
………………………………………………………
…………………………… 98
Événements
………………………………………………………
…………………………… .. 99
Système de fichiers
………………………………………………………
…………………… 100
HTTP
………………………………………………………
…………………………… 101
HTTPS
………………………………………………………
…………………………. 101
Net
………………………………………………………
……………………………… .. 102
Os
………………………………………………………
………………………………… 102
Chaîne de requête
………………………………………………………
………………… 103
Readline
………………………………………………………
……………………… .. 105
REPL
………………………………………………………
……………………………. 106
Minuteries
………………………………………………………
………………………… .. 107
TLS
………………………………………………………
………………………………. 108
URL
………………………………………………………
……………………………… 109
VM
………………………………………………………
……………………………… .. 111
Modules de base
………………………………………………………
………………. 113
Objets globaux
………………………………………………………
………………. 113
Nom du fichier et du répertoire
………………………………………………………
114
Tampon
………………………………………………………
…………………………… 114
Exportations
………………………………………………………
……. …………………… 114
Processus
………………………………………………………
…………. ……………… 116
Utilitaire
………………………………………………………
……… .. ………………… .. 116
Événements…………………………………………
…………………..……………………. 117
OS
………………………………………………………
………………………………… 118
Processus……………………………………………
……………………………………. 123
Tampon
………………………………………………………
…………………………… 127
Chemin
………………………………………………
………………………… 129
Créez et intégrez vos propres classes
…………………… 131
Propres modules dans Node.js
……………………………… .. 138
Le module Modules
………………………………………………
.. 139
Le chargeur de module
………………………………………………
140
node_modules
………………………………………………
…………… 141
La fonctionnalité requise
……………………………………… .. 143
L' application Time Tracker
……………………………………… 145
NMP …………………………………….
…………………………………… .. 148
Rechercher des packages
……………………………………………
149
Installer les packages
………………………………………………
…. 150
Afficher les packages installés
………………………………… .. 155
Utiliser des packages
………………………………………………
… 156
Cendres asynchrones dans Node.js
…………………………… 162
Conventions
………………………………………………
……………… 163
API générales
………………………………………………
…………… .. 163
Traitement des erreurs
………………………………………………
167
Imprimer dans le rappel AsyncHooks
…………………… .. 168
asyncHook.enable ()
………………………………………………
…… 168
Rappels de crochet
………………………………………………
……… 169
Type de paramètre
………………………………………………
……. 170
Le paramètre triggerAsyncId
…………………………………… 171
La ressource de paramètre
……………………………………… .. 173
Un exemple de contexte asynchrone
……………………. 174
avant (asyncId)
………………………………………………
………… .. 177
après (asyncId)
………………………………………………
…………… 177
destroy (asyncId)
………………………………………………
………. 178
promiseResolve (asyncId)
……………………………………………
178
Suivi de l' exécution des promesses
………………………... 181
Embedded A PI (Embedder API) dans
JavaScript ….. 183
AsyncResource
………………………………………………
…………… 183
.
INTRODUCTION
«Node.js est de loin la bibliothèque JavaScript la plus utilisée. Il est utilisé
sur plus de 50% des sites Web. De nombreux frameworks, tels que
Backbone et Bootstrap de Twitter, sont construits au-dessus de node.js. Être
capable d'étendre et d'écrire des plugins pour node peut non seulement
gagner beaucoup de temps, mais aussi rendre le code beaucoup plus propre
et plus facile à maintenir. »

Qu'est-ce que Node.js?


Il existe de nombreuses définitions en ligne. Jetons un coup d'œil à
quelques-uns des plus populaires. Voici ce que dit la page d'accueil du
projet:

- Node.js® est un moteur d'exécution JavaScript basé sur le moteur


JavaScript V8 de Chrome.

Et voici ce que Stack Overflow a à offrir:

- Node.js est un runtime d'E / S asynchrone, non bloquant et basé sur


des événements, qui utilise le moteur JavaScript V8 de Google et la
bibliothèque libuv.

Hmmm, «basé sur les événements», «non bloquant», «E / S asynchrones» -


c'est beaucoup à digérer en une seule fois. Abordons donc cela sous un
angle différent et commençons par nous concentrer sur l'autre détail
mentionné dans les deux descriptions - le moteur JavaScript V8.

Node est construit sur le moteur JavaScript V8 de Google Chrome


Le moteur V8 est le moteur JavaScript open-source qui fonctionne dans
Google Chrome et d'autres navigateurs Web basés sur Chromium,
notamment Brave, Opera et Vivaldi. Il a été conçu avec les performances à
l'esprit et est responsable de la compilation de JavaScript directement en
code machine natif que votre ordinateur peut exécuter.

Cependant, lorsque nous disons que Node est construit sur le moteur V8,
nous ne voulons pas dire que les programmes Node sont exécutés dans un
navigateur. Ils ne le sont pas. Au contraire, le créateur de Node (Ryan Dahl)
a pris le moteur V8 et l'a amélioré avec diverses fonctionnalités, telles
qu'une API de système de fichiers, une bibliothèque HTTP et un certain
nombre de méthodes utilitaires liées au système d'exploitation.

Cela signifie que Node.js est un programme que nous pouvons utiliser pour
exécuter JavaScript sur nos ordinateurs. En d'autres termes, c'est un runtime
JavaScript.

Comment installer Node.js?


Dans cette section suivante, nous installerons Node et écrirons quelques
programmes simples. Nous examinerons également npm, un gestionnaire de
packages fourni avec Node.

Binaires de nœuds et gestionnaire de versions


De nombreux sites Web vous recommanderont de vous rendre sur la page
de téléchargement officielle de Node et de récupérer les binaires de Node
pour votre système. Bien que cela fonctionne, je vous suggère d'utiliser un
gestionnaire de version à la place. C'est un programme qui vous permet
d'installer plusieurs versions de Node et de basculer entre elles à volonté. Il
y a plusieurs avantages à utiliser un gestionnaire de versions. Par exemple,
il annule les problèmes d'autorisation potentiels lors de l'utilisation de Node
avec npm et vous permet de définir une version de Node pour chaque
projet.

Si vous avez envie de suivre la voie du gestionnaire de versions, veuillez


consulter notre conseil rapide: Installez plusieurs versions de Node.js en
utilisant nvm. Sinon, récupérez les binaires corrects pour votre système à
partir du lien ci-dessus et installez-les.

"Bonjour le monde!" la manière Node.js


Vous pouvez vérifier que Node est installé sur votre système en ouvrant un
terminal et en tapant node -v. Si tout s'est bien passé, vous devriez voir
quelque chose comme v12.14.1 affiché. Il s'agit de la version LTS actuelle
au moment de la rédaction.

Ensuite, créez un nouveau fichier hello.js et copiez le code suivant:

console.log ("Bonjour le monde!");

Cela utilise le module de console intégré de Node pour afficher un message


dans une fenêtre de terminal. Pour exécuter l'exemple, entrez la commande
suivante:

noeud hello.js

Faites le saut dans la programmation côté serveur avec une couverture


complète de PHP et MySQL.

Normalement RRP $ 11.95 Vôtre absolument gratuit


Si Node.js est configuré correctement, "Hello, World!" sera affiché.

Node.js a un excellent support pour JavaScript


moderne
Comme on peut le voir sur ce tableau de compatibilité, Node a un excellent
support pour ECMAScript 2015 (ES6) et au-delà. Comme vous ne ciblez
qu'un seul runtime (une version spécifique du moteur V8), cela signifie que
vous pouvez écrire votre JavaScript en utilisant la syntaxe la plus récente et
la plus moderne. Cela signifie également que vous n'avez généralement pas
à vous soucier des problèmes de compatibilité - comme vous le feriez si
vous écriviez du JavaScript qui fonctionnerait dans différents navigateurs.

Pour illustrer ce point, voici un deuxième programme qui utilise plusieurs


fonctionnalités JavaScript modernes, telles que les littéraux de modèle
étiquetés, la déstructuration d'objets et Array.prototype.flatMap ():

function upcase(strings, ...values) {


return values.map(name => name[0].toUpperCase() + name.slice(1))
.join(' ') + strings[2];
}

const person = {
first: 'brendan',
last: 'eich',
age: 56,
position: 'CEO of Brave Software',
};

const { first, last } = person;


const emoticon = [ ['┌', '('], ['˘', '⌣'], ['˘', ')', 'ʃ'] ];
console.log(
upcase`${first} ${last} is the creator of JavaScript! ` + emoticon.flat().join('')
);

Enregistrez ce code dans un fichier appelé index.js et exécutez-le depuis


votre terminal à l'aide de la commande node index.js. Vous devriez voir que
Brendan Eich est le créateur de JavaScript! ┌ (˘ ⌣ ˘) ʃ sortie vers la borne.
Présentation de npm, le gestionnaire de packages JavaScript

Comme je l'ai mentionné précédemment, Node est livré avec un


gestionnaire de packages appelé npm. Pour vérifier la version que vous
avez installée sur votre système, tapez npm -v.

En plus d'être le gestionnaire de packages pour JavaScript, npm est


également le plus grand registre de logiciels au monde. Il existe plus de 1
000 000 de packages de code JavaScript disponibles au téléchargement,
avec des milliards de téléchargements par semaine. Jetons un coup d'œil à la
façon dont nous utiliserions npm pour installer un package.

Installation d'un package à l'échelle mondiale


Ouvrez votre terminal et saisissez ce qui suit:

npm installer -g jshint

Cela installera le package jshint globalement sur votre système. Nous


pouvons l'utiliser pour lint le fichier index.js de l'exemple précédent:

jshint index.js
Vous devriez maintenant voir un certain nombre d'erreurs liées à ES6. Si
vous voulez les réparer, ajoutez / * jshint esversion: 6 * / en haut du fichier
index.js, relancez la commande et le linting devrait réussir.

Si vous souhaitez un rappel sur le peluchage, voir une comparaison des


outils de peluchage JavaScript.

Installer un package localement


Nous pouvons également installer des packages localement dans un projet,
par opposition à globalement, sur notre système. Créez un dossier de test et
ouvrez un terminal dans ce répertoire. Tapez ensuite ceci:

npm init -y

Cela créera et remplira automatiquement un fichier package.json dans le


même dossier. Ensuite, utilisez npm pour installer le package lodash et
enregistrez-le en tant que dépendance de projet:

npm install lodash --save

Créez un fichier nommé test.js et ajoutez ce qui suit:

const _ = require('lodash');

const arr = [0, 1, false, 2, '', 3];


console.log(_.compact(arr));

Enfin, exécutez le script à l'aide du nœud test.js. Vous devriez voir la sortie
[1, 2, 3] vers le terminal.
JavaScript est désormais omniprésent en tant que langage de
programmation. La marche triomphale de ce langage de script a commencé
avec l'intégration dans le navigateur web Netscape en 1995. Brendan Eich,
le développeur du langage alors appelé LiveScript, l'a développé pour
effectuer de petites tâches telles que la validation de formulaire directement
dans le navigateur. Depuis, le langage ne s'est répandu que via Internet
Explorer et est désormais disponible sur tous les navigateurs graphiques.
L'étape suivante était que les moteurs JavaScript étaient déclenchés à partir
des navigateurs et utilisés sous une forme différente, comme c'est le cas
avec le V8 -Engin du navigateur Chrome dans Node.js est le cas. Avec cette
approche, Node.js apporte Java Script au serveur. La plate-forme n'est pas
un nouveau développement radical, mais plutôt une collection de diverses
bibliothèques qui ont déjà fait leurs preuves dans la pratique. Si vous vous
êtes déjà demandé ce qu'il y avait derrière Node.js et pourquoi tant
d'entreprises utilisent maintenant même JavaScript côté serveur - zen, vous
êtes au bon endroit. Ce chapitre est destiné à vous donner un aperçu de la
création de Node.js et des concepts sous-jacents. Cependant, ce chapitre
n'est pas absolument nécessaire pour comprendre les chapitres suivants,
vous ne devriez donc pas vous intéresser aux optimisations du moteur
JavaScript qui permettent à Node.js de bien fonctionner ou aux
bibliothèques qui peuvent être utilisées en plus du moteur V8 Vous pouvez
également ignorez ce chapitre et commencez à installer la plate-forme
Node.js au chapitre 2, «Installation».
L'histoire de Node.js
Pour vous aider à mieux comprendre ce qu'est Node.js et à comprendre
comment certaines des décisions de développement ont été prises, vous
pouvez en savoir plus sur l'historique de la plate-forme ici. Le
développement relativement jeune de Node.js est directement lié à son
développeur, Ryan Dahl. Avant de travailler intensivement sur
l'informatique et le développement de Node.js, Ryan Dahl était doctorant en
mathématiques. Mais à un moment donné, il s'est avéré que les
mathématiques n'étaient pas la bonne chose pour lui, il a arrêté ses efforts et
est allé en Amérique du Sud. Avec un aller simple et très peu d'argent en
poche, il a essayé de se débrouiller avec des cours d'anglais. Pendant ce
temps, il a rencontré des développeurs Web qui ont créé des sites Web
dynamiques avec une première version de PHP. Il s'est rendu compte qu'il
était intéressé par la programmation de sites Web et, via PHP, il est
finalement arrivé à Ruby en tant que langage de programmation. Ryan Dahl
dit à propos de Ruby que c'est le langage avec la plus belle syntaxe, mais il
présente des inconvénients majeurs. Avec le framework Rails basé sur
Rubs, il a fait ses premiers pas majeurs dans le développement web.
Cependant, le résultat de ses expériences n'était qu'un site Web productif.
Ryan a rapidement reconnu le plus gros problème de Rails et du Ruby sous-
jacent: les sites Web étaient trop lents et le processeur de son ordinateur
fonctionnait à pleine capacité. Rails était incapable de traiter les demandes
concurrentes sans solutions de contournement, car le noyau sous-jacent
avec Ruby poursuivait une approche à un seul thread, c'est-à-dire qu'il ne
permettait l'exécution qu'une certaine partie de la logique du programme à
la fois et non comme dans les processus d'approche multi-threadés plusieurs
pièces en parallèle. La vraie inspiration est venue de Mongrel, un serveur
Web pour les applications basées sur Ruby. Contrairement aux serveurs
Web classiques, Mongrel répond aux demandes des utilisateurs et génère les
réponses de manière dynamique, sinon seules des pages HTML statiques
sont fournies. Du point de vue d'aujourd'hui, la tâche qui a conduit à la
création de Node.js est assez triviale. En 2005, Ryan Dahl cherchait un
moyen élégant d'implémenter une barre de progression pour les
téléchargements de fichiers. Avec les technologies disponibles à l'époque,
seules des solutions insatisfaisantes étaient possibles. Le protocole HTTP a
été utilisé pour transférer les fichiers pour les fichiers relativement petits et
le protocole FTP pour les fichiers plus volumineux. L'état du
téléchargement a été interrogé à l'aide d'une longue interrogation. Il s'agit
d'une technique dans laquelle le client envoie des demandes de longue
durée au serveur et le serveur utilise le canal ouvert pour les réponses. Une
première tentative de Ryan Dahl pour implémenter une barre de progression
trouvée dans Mongrel. Après avoir envoyé le fichier au serveur, il a vérifié
l'état du téléchargement à l'aide d'un grand nombre de requêtes Ajax et l'a
représenté graphiquement dans une barre de progression. Cependant,
l'implémentation de l'approche monothread de Ruby et le grand nombre de
requêtes ont été de nouvelles tentatives pour résoudre le problème de la
barre de progression, mais cette fois dans d'autres langages de
programmation. La mise en œuvre en C offrait une approche prometteuse.
Ici, Ryan Dahl ne s'est pas limité à un fil. Cependant, le langage C en tant
que langage de programmation pour le Web présente un inconvénient
majeur: il y a pas mal de développeurs qui sont enthousiasmés par ce
domaine d'application. Ryan Dahl a été confronté à ce problème et a
rapidement rejeté cette approche. La recherche d'un langage de
programmation approprié pour résoudre son problème s'est poursuivie et l'a
conduit vers des langages de programmation fonctionnels tels que Haskell.
L'approche de Haskell est basée sur des E / S non bloquantes, ce qui signifie
que toutes les opérations d'écriture et de lecture se déroulent de manière
asynchrone et ne bloquent pas l'exécution du programme. Cela permet au
langage de rester mono-thread à son cœur, et ne donne pas lieu aux
problèmes qui découlent de la programmation parallèle. Entre autres
choses, aucune ressource n'a besoin d'être synchronisée et aucun problème
n'est causé par l'exécution des threads parallèles. Cependant, Ryan Dahl
n'était toujours pas entièrement satisfait de cette solution et cherchait
d'autres options. Ryan Dahl a finalement trouvé la solution finale en janvier
2009 en utilisant Java Script. Ici, il est devenu clair pour lui que ce langage
de script pouvait répondre à toutes ses exigences. JavaScript était établi sur
le Web depuis des années, il disposait de moteurs puissants et d'un grand
nombre de programmeurs. C'est ainsi qu'au début de 2009, il a commencé à
travailler sur son implémentation pour JavaScript côté serveur, la naissance
de Node.js. Une autre raison en faveur de l' implémentation de la solution
en Java Script, selon Ryan Dahl, était le fait que les développeurs
JavaScript ne fournissaient pas ce domaine d'application. À cette époque, il
n'existait pas de serveur Web natif en JavaScript, les fichiers d'un système
de fichiers ne pouvaient pas être traités et il n'y avait pas d'implémentation
de sockets pour communiquer avec d'autres applications ou systèmes. Tous
ces points plaident en faveur de JavaScript comme base d'une plateforme
d'applications web interactives, après quoi aucune stipulation n'a été faite
dans ce domaine et par conséquent aucune erreur n'a été commise.
L'architecture de JavaScript parle également d'une telle implémentation.
L'approche des fonctions de haut niveau, c'est-à-dire des fonctions qui ne
sont pas liées à un objet et qui sont donc librement disponibles et peuvent
également être affectées à des variables, offre une grande flexibilité de
développement. En plus du moteur JavaScript chargé d'interpréter le code
JavaScript, Ryan Dahl a sélectionné d'autres bibliothèques et les a
regroupées sur une seule plateforme. Une fois tous les composants intégrés
et des exemples exécutables créés sur la nouvelle plate-forme Node.js, Ryan
Dahl avait besoin d'un moyen de présenter Node.js au public. Cela est
devenu nécessaire car ses ressources financières ont considérablement
diminué en raison du développement de Node.js et s'il ne pouvait pas
trouver de sponsors, il devrait arrêter de travailler sur Node.js. Il a choisi la
conférence JavaScript jsconf.eu à Berlin en novembre 2009 comme
plateforme de présentation. Ryan Dahl a tout mis sur une seule carte.

Si la présentation était un succès et qu'il trouvait des sponsors pour soutenir


son travail sur Node.js, il pourrait continuer son engagement, sinon, le
travail serait gratuit pendant près d'un an. Dans une conférence
passionnante, il a présenté Node.js au public et a montré comment créer un
serveur Web entièrement fonctionnel avec seulement quelques lignes de
code JavaScript. Comme autre exemple, il a apporté avec lui une
implémentation d'un serveur de chat IRC. Le code source de cette
démonstration était d'environ 400 lignes. À l'aide de cet exemple, il a
démontré l'architecture et donc les atouts de Node.js et en même temps l'a
rendu tangible pour le public. En réponse à sa présentation convaincante,
inJoyent a trouvé un sponsor pour Node.js. Joyent est un fournisseur de
logiciels et de services basé à San Francisco, proposant des solutions
d'hébergement et une infrastructure cloud. Fort de cet engagement, Joyent a
ajouté le logiciel open source Node.js à son portefeuille de produits et mis
Node.js à la disposition de ses clients dans le cadre de ses offres
d'hébergement. Ryan Dahl a été embauché par Joyent et à partir de là a
travaillé comme mainteneur à plein temps pour Node.js. Au début de 2012,
l'annonce de Ryan Dahl selon laquelle il se retirerait finalement du
développement actif après trois ans de travail sur Node.js a surpris Isaac
Schlueter. Comme un employé de RyanDahl chez Joyent, il est impliqué
dans le développement du noyau de Node.js et entre autres responsable du
développement du Node Package Manager. Il est désormais responsable de
la stabilisation, de la diffusion et de l'intégration des nouvelles
fonctionnalités.

Les avantages de Node.js


L'historique de développement de Node.js montre très clairement une
chose: le développement de Node.js est directement connecté à Internet.
Avec JavaScript comme base, vous pouvez utiliser des applications
implémentées dans Node.js pour obtenir des résultats visibles très
rapidement. En plus de la mise en œuvre initiale rapide, vous avez
également la possibilité de réagir très rapidement à l'évolution des besoins
tout en développant des applications Web. Puisque le noyau de Java Script
est largement normalisé par ECMAScript, JavaScript est une base fiable
avec laquelle des applications encore plus étendues peuvent être
implémentées. Les fonctionnalités linguistiques disponibles sont bien et
largement documentées à la fois en ligne et sous la forme de livres
spécialisés. De plus, de nombreux développeurs sont disponibles qui
connaissent JavaScript et sont capables d'implémenter des applications plus
volumineuses en utilisant ce langage. Étant donné que Node.js avec le
moteur V8 utilise le même moteur JavaScript que Google Chrome, toutes
les fonctionnalités du langage sont également disponibles ici, et les
développeurs familiarisés avec Java Script peuvent s'y habituer assez
rapidement pour intégrer la nouvelle plate-forme.
La longue histoire de JavaScript a produit un certain nombre de moteurs
hautes performances. Une des raisons de ce développement est que les
différents fabricants de navigateurs développaient constamment leurs
propres implémentations de moteurs Java Script et il y avait donc une
concurrence saine sur le marché pour exécuter JavaScript dans le
navigateur. Ce concours s'est traduit d'une part par le fait que JavaScript est
désormais interprété très rapidement, et d'autre part par l'accord des
constructeurs sur certaines normes.Node.js en tant que plateforme de
JavaScript côté serveur a été conçu comme un projet open source depuis le
début de son développement. Pour cette raison, une communauté active
s'est rapidement développée autour du cœur de la plateforme. Cela concerne
principalement l'utilisation de Node.js dans la pratique, mais aussi le
développement et la stabilisation de la plate-forme. Les ressources de
Node.js vont des didacticiels pour vous aider à démarrer à des articles sur
des sujets avancés tels que l'assurance qualité, le débogage ou la mise à
l'échelle. Le plus grand avantage d'un projet open source comme Node.js
est que l'information est disponible gratuitement et que les questions et
problèmes peuvent être résolus rapidement et avec compétence via un large
éventail de canaux de communication ou la communauté.

Domaines d'application de Node.js


Si vous n'avez pas beaucoup d'expérience avec Node.js, vous vous êtes
probablement déjà posé la question: dans quelles situations est-ce que
j'utilise réellement Node.js? Cette question peut rarement recevoir une
réponse claire et sans ambiguïté. En principe, l'utilisation de certaines
technologies dépend bien entendu du type de problème et des préférences
personnelles et du niveau de connaissance des développeurs. "Si vous avez
un marteau dans la main, tout ressemble à un clou", est un vieil adage qui
décrit très bien l'une des plus grosses erreurs que vous puissiez faire dans le
développement de logiciels. Ils élaborent une stratégie de solution et
recherchent ensuite un problème. Si vous commencez à développer une
application de cette manière, il est possible que vous vous appuyiez sur la
mauvaise technologie ou architecture, ce qui peut même conduire à l'échec
du projet à un moment ultérieur. La vraie difficulté est donc de choisir les
bons outils en début de projet. Que vous ayez parié sur le bon cheval ne
peut être vu que lorsque l'application se développe et que de nouvelles
demandes sont faites par les utilisateurs. En supposant cette hypothèse,
chaque application doit être implémentée avec Java et sans rencontrer de
problèmes, car presque tous les problèmes peuvent être résolus avec ce
langage. Cette hypothèse est également trompeuse, car le développement
d'une application Web avec Java n'est pas très banal et il n'y a pas tellement
de développeurs Java sur le marché pour pouvoir implémenter toutes les
applications Web avec eux. La bonne marche à suivre lors du démarrage
d'un projet est donc une analyse des exigences et de leur hiérarchisation. De
quoi parle exactement le projet? Quel budget est disponible pour cela? Dans
quels délais une première version doit-elle être livrée aux utilisateurs? Vous
devez vous poser ces questions et bien d'autres au début, puis utiliser ce
questionnaire pour poser les questions technologiques disponibles et
vérifier si elles répondent aux exigences les plus importantes. Pour une telle
évaluation technologique, vous devez absolument envisager au moins deux
solutions potentielles, mais mieux encore, pour vraiment utiliser la
meilleure stratégie de solution. Maintenant, vous allez sûrement demander
ce que tout cela a à voir avec Node.js. Node.js n'est en aucun cas le «Silver
Bullet», avec lequel vous pouvez résoudre tous les problèmes du monde. La
plate-forme ne remplace pas un serveur Web à part entière, et il est
également douteux que vous souhaitiez vous fier uniquement à Node.js lors
de la mise en œuvre d'une application complète et critique pour l'entreprise.
Avec son architecture, Node.js propose un certain nombre d'options qui le
distinguent des autres technologies. Node.js a été créé en tant que plate-
forme pour les applications Web dynamiques. C'est également là que
Node.js est utilisé, principalement en conjonction avec d'autres technologies
allant des bases de données aux grandes applications d'entreprise Java.
L'une des grandes forces de Node.js réside dans la mise en œuvre de
services Web légers. Node.js propose son propre module de communication
via HTTP, de sorte que des interfaces REST à part entière peuvent être
créées très rapidement. La communication avec les services Web est encore
plus facile. Vous pouvez également utiliser le module HTTTP ici. Une autre
force de Node.js est la possibilité de communiquer de manière
bidirectionnelle avec d'autres systèmes. Ce type de connexion n'est pas
seulement limité aux systèmes serveur, mais peut également avoir lieu avec
des systèmes clients tels que des navigateurs Web ou des applications
mobiles via la technologie Web. Cependant, vous pouvez non seulement
utiliser Node.js sur le Web. Avec le moteur JavaScript et une variété de
modules, Node.js peut également être utilisé pour implémenter des outils de
ligne de commande. Ceux-ci peuvent être publiés via le gestionnaire de
packages intégré à Node.js et ainsi mis à disposition d'autres personnes. Les
utilisations possibles de Node.js ne sont guère limitées.

Le cœur - le moteur V8
Pour que vous, en tant que développeur, puissiez évaluer si une technologie
peut être utilisée dans un projet, vous devez être suffisamment familiarisé
avec les spécifications de cette technologie. Les sections suivantes traitent
des éléments internes de Node.js et sont destinées à vous montrer de quels
composants la plate-forme est construite et comment vous pouvez l'utiliser
à l'avantage d'une application est le moteur JavaScript V8 développé par
Google. Pour plus d'informations, consultez la page du projet V8 à l'adresse
https://code.google.com/p/v8/. Le moteur JavaScript est responsable de
l'interprétation et de l'exécution du code source JavaScript. Pour JavaScript,
il n'y a pas qu'un seul moteur, mais les différents fabricants de navigateurs
s'appuient sur leur propre implémentation. L'un des problèmes avec Java
Script est que les moteurs individuels se comportent quelque peu
différemment. La standardisation selon ECMAScript tente de trouver un
dénominateur commun fiable, de sorte que vous, en tant que développeur
d'applications JavaScript, ayez moins à vous soucier. La concurrence des
moteurs JavaScript a conduit à un certain nombre de moteurs optimisés, qui
visent tous à interpréter le code JavaScript le plus rapidement possible. Au
fil du temps, certains moteurs se sont imposés sur le marché. Ceux-ci
incluent Chakra de Microsoft, JägerMonkey de Mozilla, Nitro d'Apple et le
moteur V8 de Google. Node.js utilise le moteur V8 de Google. Ce moteur
est développé par Google depuis 2006 principalement au Danemark en
collaboration avec l'université d'Aarhus. Le principal domaine d'application
du moteur est le navigateur Chrome de Google, où il est responsable de
l'interprétation et de l'exécution du code JavaScript. L'objectif du
développement d'un nouveau moteur JavaScript était d'améliorer
considérablement les performances d'interprétation de JavaScript, la
cinquième version de la norme ECMAScript ECMA-262. Le moteur V8
lui-même est écrit en C ++, fonctionne sur différentes plates-formes et est
disponible sous la licence BSD en tant que logiciel open source pour
chaque développeur pour sa propre utilisation et amélioration. Par exemple,
vous pouvez intégrer le moteur dans n'importe quelle application C ++.
Comme d'habitude en JavaScript, le code source n'est pas compilé avant
l'exécution, mais les fichiers avec le code source sont lus directement au
démarrage de l'application. Au démarrage de l'application, un nouveau
processus Node.js est lancé, où la première optimisation par le moteur V8 a
lieu. Le code source n'est pas interprété directement, mais d'abord traduit en
code machine, qui est ensuite exécuté. Cette technologie est connue sous le
nom de compilation juste à temps, ou JIT en abrégé, et est utilisée pour
augmenter la vitesse d'exécution de l'application Java Script. L'application
proprement dite est ensuite exécutée sur la base du code machine compilé.
En plus de la compilation juste à temps, le moteur V8 effectue également
d'autres optimisations. Entre autres choses, il s'agit d'un garbage collection
amélioré et d'une amélioration de l'accès aux propriétés des objets. Pour
toutes les optimisations effectuées par le moteur JavaScript, vous devez
noter que le code source est lu au début du processus et que les
modifications apportées aux fichiers n'ont donc aucun effet sur l'application
en cours d'exécution. Pour que vos modifications prennent effet, vous devez
terminer votre application et recommencer afin que les fichiers de code
source adaptés soient à nouveau lus.

Le modèle de mémoire
L'objectif du développement du moteur V8 était d'atteindre la vitesse la plus
élevée possible lors de l'exécution du code source JavaScript. Pour cette
raison, le modèle de mémoire a également été optimisé. Les soi-disant
TaggedPointers sont utilisés dans le moteur V8. Ce sont des références dans
la mémoire qui sont marquées comme telles d'une manière spéciale. Tous
les objets sont alignés sur 4 octets, ce qui signifie que 2 bits sont
disponibles pour le marquage des pointeurs. Un pointeur se termine
toujours dans le modèle de mémoire du moteur V8 à »01«, une valeur
entière normale à »0«. Cette mesure signifie que les valeurs entières
peuvent être distinguées très rapidement des références dans la mémoire, ce
qui présente un très grand avantage en termes de performances. Les
représentations d'objets du moteur V8 en mémoire se composent chacune
de trois mots de données. Le premier mot de données consiste en une
référence à la classe cachée de l'objet, sur laquelle vous en apprendrez plus
ci-dessous. Le deuxième mot de données est un pointeur vers les attributs,
c'est-à-dire les propriétés de l'objet. Le troisième mot de données fait
finalement référence aux éléments de l'objet. Ce sont les propriétés avec
une clé numérique. Cette structure prend en charge le moteur JavaScript
dans son travail et est optimisée de manière à ce que les éléments de la
mémoire soient accessibles très rapidement et qu'il y ait peu de temps
d'attente lors de la recherche d'objets.

Accès aux propriétés


Comme vous le savez probablement, JavaScript n'a pas de classes, le
modèle objet JavaScript est basé sur des prototypes. Dans les langages
basés sur des classes tels que Java ou PHP, les classes représentent le plan
des objets. Ces classes ne peuvent pas être modifiées lors de l'exécution.
Les prototypes en JavaScript sont cependant dynamiques. Cela signifie que
les propriétés et les méthodes peuvent être ajoutées et supprimées au
moment de l'exécution. Comme avec tous les autres langages qui
implémentent le paradigme de programmation orientée objet, les objets sont
représentés par leurs propriétés et leurs méthodes, où les propriétés
représentent l'état d'un objet et les méthodes utilisées pour interagir avec
l'objet. Dans une application, vous accédez généralement très souvent aux
propriétés des différents objets. En outre, les méthodes JavaScript ont
également des propriétés d'objets stockés avec une fonction. En JavaScript,
vous travaillez presque exclusivement avec des propriétés et des méthodes.
Par conséquent, l'accès à cela doit être très rapide.

Prototypes en JavaScript
JavaScript diffère des langages tels que C, Java ou PHP en ce qu'il ne suit pas une approche
basée sur les classes, mais s'appuie sur des prototypes tels que le languageSelf. En JavaScript,
chaque objet a généralement une propriété prototype et donc un prototype. Vous pouvez créer
des objets en JavaScript comme dans d'autres langages. Dans ce but, cependant, n'utilisez pas
de classes en relation avec le nouvel opérateur. Au lieu de cela, vous pouvez créer de nouveaux
objets de différentes manières. Entre autres choses, vous pouvez également utiliser des
fonctions constructeur ou la méthode Object.create . Ces méthodes ont en commun de créer un
objet et d'affecter le prototype. Le prototype est un objet dont un autre objet hérite de ses
propriétés. Une autre caractéristique des prototypes est qu'ils peuvent être modifiés au moment
de l'application et que vous pouvez ajouter de nouvelles propriétés et méthodes. En utilisant
des prototypes, vous pouvez créer une hiérarchie d'héritage dans Java Script. Voir Section
4.2.2, «Utilitaire», pour plus d'informations sur la façon dont Node.js peut vous aider avec
l'héritage basé sur des prototypes.

Les propriétés sont généralement accessibles dans un moteur JavaScript via


un répertoire dans la mémoire de travail. Si vous accédez à une propriété,
l'emplacement de la propriété respective est recherché dans ce répertoire,
après quoi la valeur est accessible. Imaginez maintenant une grande
application qui mappe sa logique métier en JavaScript côté client et dans
laquelle un grand nombre d'objets sont conservés en mémoire et
communiquent constamment entre eux. Ce type d'accès aux propriétés
devient rapidement un problème. Les développeurs du moteur V8 ont
reconnu cette vulnérabilité et ont développé une solution pour cela avec les
classes dites cachées. Le vrai problème avec JavaScript est que la structure
des objets n'est connue qu'au moment de l'exécution et non pendant le
processus de compilation, car JavaScript n'existe pas. Pour aggraver les
choses, il n'y a pas seulement un prototype dans la construction d'objets,
mais ils peuvent être dans une chaîne. Dans les langages classiques, la
structure des objets ne change pas au moment de l'application, les propriétés
des objets sont toujours au même endroit, ce qui accélère considérablement
l'accès. Une classe masquée n'est rien de plus qu'une description de l'endroit
où les propriétés individuelles d'un objet dans la mémoire peuvent être
trouvées. Pour cela, une classe masquée est affectée à chaque objet. Celui-ci
contient le décalage par rapport à l'emplacement dans l'objet où la propriété
respective est stockée. Dès que vous accédez à une propriété d'un objet, une
classe masquée est créée pour cette propriété et réutilisée à chaque accès
ultérieur. Pour un objet, il existe donc potentiellement une classe cachée
distincte pour chaque propriété.

Dans la liste, vous pouvez voir un exemple qui montre le fonctionnement


des classes cachées.

function person (firstname, lastname) {


this.firstname = firstname;
this.lastname = lastname;
}
var johnDoe = new person ("John", "Doe");

Dans l'exemple, vous créez une nouvelle fonction constructeur pour le


groupe d'objets personne. Ce constructeur a deux paramètres, le prénom et
le nom de la personne. Ces deux valeurs doivent être enregistrées dans les
propriétés prénom et nom de l'objet. Si un nouvel objet est créé avec ce
constructeur à l'aide du nouvel opérateur, une classe cachée initiale, classe
0, est d'abord créée. Cela ne contient pas encore de pointeurs vers des
propriétés. Si la première affectation, à savoir la mise en le premier nom, est
effectuée, une nouvelle classe cachée, classe 1, est créé à partir de la classe
0. Cela inclut maintenant une référence à la Spei cherstelle la propriété
prénom , par rapport au début de Namensraumsdes objet. En outre, une soi-
disant transition de classe est ajoutée à la classe 0, qui indique que la classe
1 doit être utilisée à la place de la classe 0 si la propriété firstname est
ajoutée. Le même processus a lieu lors de la deuxième affectation du nom
de famille. Une autre classe cachée, la classe 2, est créée en fonction de la
classe 1, qui contient alors à la fois le décalage pour les propriétés de
prénom et de nom , et une transition est ajoutée avec la note que la classe 2
doit être utilisée si la propriété nom de famille est utilisée. Si des propriétés
sont ajoutées indépendamment du constructeur et que cela se fait dans un
ordre différent, de nouvelles classes masquées sont créées. Lors de l'accès
initial aux propriétés d'un objet, l'utilisation de classes masquées n'entraîne
pas un avantage de vitesse. Tous les accès ultérieurs à la propriété de l'objet
se produisent alors plusieurs fois plus rapidement, car le moteur peut
utiliser directement la classe cachée de l'objet et celle-ci contient la
référence à l'emplacement de la propriété.

Génération de code machine


Comme vous le savez déjà, le moteur V8 n'interprète pas directement le
code source de l'application JavaScript, mais effectue une compilation juste
à temps en code machine natif afin d'augmenter la vitesse d'exécution.
Aucune optimisation n'est apportée au code source lors de cette
compilation.

Le code source écrit par le développeur est donc converti 1: 1. En plus de ce


compilateur juste-à-temps, le moteur V8 dispose d'un autre compilateur
capable d'optimiser le code machine. Pour décider quels fragments de code
optimiser, le moteur conserve une statistique interne sur le nombre d'appels
de fonction et la durée d' exécution de la fonction respective . Sur la base de
ces données, une décision est prise quant à savoir si le code machine d'une
fonction doit être optimisé ou non. Maintenant, vous vous posez la
question, pourquoi pas tout le code source de l'application est compilé avec
le deuxième, bien meilleur compilateur. Il y a une raison très simple à cela:
le compilateur qui n'effectue aucune optimisation est beaucoup plus rapide.
Étant donné que la compilation du code source a lieu juste à temps, ce
processus est très critique en termes de temps, car les temps d'attente
possibles peuvent avoir un impact direct sur l'utilisateur en raison d'un
processus de compilation trop long. Pour cette raison, seuls les codes
justifiant cet effort supplémentaire sont optimisés. Cette optimisation du
code machine a un effet particulièrement positif sur les applications plus
grandes et plus longues et sur celles dans lesquelles des fonctions sont
appelées plus d'une fois. Une autre optimisation effectuée par le moteur V8
comprend les classes cachées déjà décrites et la mise en cache interne. Une
fois l'application démarrée et le code machine généré, le moteur V8
recherche ou crée la classe masquée associée chaque fois qu'une propriété
est accédée. En tant qu'optimisation supplémentaire, le moteur suppose qu'à
l'avenir, les objets qui sont utilisés ici auront la même classe cachée et
modifieront le code machine en conséquence. La prochaine fois que vous
exécutez le code, la propriété est accessible directement et vous n'avez pas
besoin de rechercher d'abord la classe masquée associée. Si l'objet utilisé n'a
pas la même classe masquée, le moteur le détecte, supprime le code
machine précédemment généré et le remplace par la version corrigée. Cette
procédure pose un problème crucial: imaginez que vous avez un code dans
lequel deux objets différents avec des classes cachées différentes sont
toujours utilisés en alternance. Dans ce cas, l'optimisation avec la prédiction
de la classe cachée ne prendrait jamais effet à la prochaine exécution. Dans
ce cas, divers fragments de code sont utilisés, sur la base desquels
l'emplacement d'une propriété ne peut pas être trouvé aussi rapidement
qu'avec une seule classe cachée, mais dans ce cas, le code est plusieurs fois
plus rapide que sans l'optimisation, car ici principalement un très un petit
ensemble de classes masquées peut être sélectionné. Avec la génération du
code machine et des classes cachées en combinaison avec les mécanismes
de mise en cache, des possibilités sont créées qui sont connues des langages
basés sur les classes.

Collecte des ordures


Les optimisations décrites jusqu'à présent affectent principalement la
vitesse d'une application. Une autre caractéristique très importante est le
ramasse-miettes du moteur V8. Le garbage collection fait référence au
processus d'effacement de la zone de mémoire de l'application dans la
mémoire de travail. Les éléments qui ne sont plus utilisés sont supprimés de
la mémoire afin que l'espace libre soit à nouveau disponible pour
l'application. Si vous vous posez la question de savoir pourquoi un garbage
collector est requis en JavaScript, vous pouvez y répondre très facilement.
JavaScript était à l'origine destiné aux petites tâches sur les sites Web. Ces
sites Web et donc le JavaScript de cette page avaient une durée de vie très
courte jusqu'à ce que la page soit rechargée et que la mémoire contenant les
objets JavaScript soit complètement vidée. Plus le JavaScript est exécuté
sur une page et plus les tâches deviennent complexes, plus le risque que la
mémoire soit remplie d'objets qui ne sont plus nécessaires est grand. Si
vous supposez maintenant une application dans Node.js qui doit s'exécuter
pendant plusieurs jours, semaines ou même mois sans redémarrer le
processus, le problème devient clair. Le ramasse-miettes du moteur V8
possède un certain nombre de fonctionnalités qui lui permettent d'exécuter
ses tâches très rapidement et efficacement. Fondamentalement, lorsque le
garbage collector s'exécute, le moteur arrête complètement l'application et
continue dès que l'exécution est terminée. Ces pauses dans l'application sont
dans la plage de millisecondes à un chiffre, de sorte que l'utilisateur ne subit
normalement aucun effet négatif du garbage collector. Afin de maintenir
l'interruption du ramasse-miettes aussi courte que possible, la totalité de la
mémoire n'est pas nettoyée, mais seulement certaines parties de celle-ci. De
plus, le moteur V8 sait à tout moment où se trouvent dans la mémoire quels
objets et pointeurs se trouvent. Le moteur V8 divise la mémoire disponible
en deux zones, une pour stocker les objets et une autre zone dans laquelle
les informations sur les classes cachées et le code machine exécutable. Le
processus de récupération de place est relativement simple. Lorsqu'une
application est exécutée, des objets et des pointeurs sont créés dans la zone
éphémère de la mémoire principale du moteur V8. Si cette zone de mémoire
est pleine, elle est nettoyée. Les objets qui ne sont plus utilisés sont
supprimés et les objets qui sont encore nécessaires sont déplacés vers la
zone de longue durée. Avec ce mouvement, l'objet lui-même est déplacé
d'une part, et les pointeurs vers l'emplacement de l'objet sont corrigés
d'autre part. La division des zones de mémoire rend différents types de
garbage collection nécessaires. La variante la plus rapide se compose du
soi-disant Scavenge Collector. Ceci est très rapide et efficace et ne concerne
que la zone de courte durée. Il existe deux algorithmes de récupération de
place pour la zone de mémoire longue durée, tous deux basés sur le
marquage et le balayage. Toute la mémoire est recherchée et les éléments
qui ne sont plus nécessaires sont marqués et supprimés ultérieurement. Le
vrai problème avec cet algorithme est qu'il y a des lacunes dans la mémoire,
ce qui conduit à des problèmes sur le long terme d'une application. Pour
cette raison, il existe un deuxième algorithme qui recherche également dans
les éléments de la mémoire ceux qui ne sont plus nécessaires, les marque et
les supprime. La différence la plus importante entre les deux est que le
deuxième algorithme défragmente la mémoire, c'est-à-dire réorganise les
objets restants dans la mémoire afin que la mémoire ait alors le moins de
trous possible. Cette défragmentation ne peut avoir lieu que parce que V8
connaît tous les objets et pointeurs. Le processus de ramassage des ordures
présente un inconvénient pour tous les avantages: il coûte du temps. La
collection Scavenge est la plus rapide à environ 2 millisecondes. Ceci est
suivi par le mark-and-sweep sans optimisations avec 50 millisecondes et
enfin par le mark-and-sweep avec défragmentation avec une moyenne de
100 millisecondes. Dans les sections suivantes, vous en apprendrez plus sur
les éléments qui sont utilisés en plus du moteur V8 dans la plate-forme
Node.js.

Bibliothèques autour du moteur


Le moteur JavaScript seul ne constitue pas une plateforme. Des fonctions
supplémentaires sont nécessaires pour que Node.js puisse gérer toutes les
exigences telles que la gestion des événements, l'entrée et la sortie ou des
fonctions de support telles que la résolution DNS ou le cryptage. Celles-ci
sont implémentées à l'aide de bibliothèques supplémentaires. De
nombreuses tâches auxquelles une plate-forme comme Node.js est
confrontée ont déjà des solutions prêtes à l'emploi et bien établies, alors
Ryan Dahl a décidé de baser la plate-forme Node.js sur un certain nombre
de bibliothèques externes et sur les lacunes qui, de l'avis d'une solution
inexistante être suffisamment couvert par ses propres implémentations.
L'avantage de cette stratégie est que vous n'avez pas à réinventer les
solutions aux problèmes standards, mais que vous pouvez vous appuyer sur
des bibliothèques éprouvées. Un représentant éminent qui s'appuie
également sur cette stratégie est le système d'exploitation UNIX. La même
chose s'applique ici aux développeurs: concentrez-vous simplement sur le
problème réel, résolvez-le du mieux possible et utilisez tout ce qui existe
déjà. Cette philosophie est implémentée dans la plupart des programmes de
ligne de commande dans la zone UNIX. Une fois qu'une solution a fait ses
preuves, elle est également utilisée dans d'autres applications pour des
problèmes similaires. Cela présente à son tour l'avantage que les
améliorations de l'algorithme ne doivent être effectuées qu'en un point
central. La même chose s'applique aux corrections de bogues. Si une erreur
se produit dans la résolution DNS, elle sera corrigée une fois et la solution
fonctionnera dans tous les endroits où la bibliothèque est utilisée. Cela
conduit également au côté sombre de la médaille. Les bibliothèques sur
lesquelles repose la plateforme doivent être disponibles. Node.js résout ce
problème en s'appuyant uniquement sur un petit ensemble de bibliothèques
qui doivent être fournies par le système d'exploitation. Cependant, ces
dépendances sont constituées de fonctions de base telles que la bibliothèque
d'exécution GCC ou la bibliothèque C Standard. Les autres dépendances
telles que »zlib« ou »http_parser« sont incluses dans le code source.

Boucle d'événement
Le JavaScript côté client comporte de nombreux éléments d'une architecture
événementielle. La plupart des interactions de l'utilisateur provoquent des
événements auxquels les appels de fonction correspondants répondent. En
utilisant diverses fonctionnalités telles que des fonctions de première classe
et des fonctions anonymes dans JavaScript, vous pouvez implémenter des
applications entières basées sur une architecture événementielle. Piloté par
les événements signifie que les objets ne communiquent pas directement via
des appels de fonction, mais que des événements sont utilisés pour cette
communication. La programmation événementielle est principalement
utilisée pour contrôler le déroulement du programme. Contrairement à
l'approche classique, dans laquelle le code source linéaire est exécuté, les
fonctions sont exécutées ici lorsque certains événements se produisent. Un
petit exemple dans Listing illustre cette approche.

myObj.on ('myEvent', function (data) {


console.log (data);
});
myObj.emit ('myEvent', 'Hello World');

Vous pouvez utiliser la sur la méthode d'un objet que vous tirez de
events.EventEmitter pour définir la fonction avec laquelle vous souhaitez
réagir à l'événement respectif. Il s'agit d'un modèle dit de publication-
abonnement. Les objets peuvent s'inscrire auprès d'un émetteur
d'événements et sont ensuite notifiés lorsque l'événement se produit. Le
premier argument de la sur la méthode est le nom de l'événement en tant
que chaîne à répondre. Le deuxième argument consiste en une fonction de
rappel qui est exécutée dès que l'événement se produit. L'appel de fonction
de la sur la méthode ne fait que enregistrer la fonction de rappel la
première fois qu'il est exécuté. Plus tard dans le script wirdauf myObj la
emit méthode appelée. Cela garantit que toutes les fonctions de rappel
enregistrées par la sur la méthode sont exécutées. Ce qui fonctionne dans
cet exemple avec un objet auto-créé est utilisé par Node.js pour effectuer
diverses tâches asynchrones. Les fonctions de rappel ne sont cependant pas
exécutées en parallèle, mais séquentiellement. L' approche monothread de
Node.js crée le problème qu'une seule opération peut être effectuée à la fois.
En particulier, des opérations de lecture ou d'écriture chronophages
garantiraient que l'exécution entière de l'application serait bloquée. Pour
cette raison, toutes les opérations de lecture et d'écriture sont externalisées à
l'aide de la boucle d'événements. De cette manière, le thread disponible peut
être utilisé par le code de l'application. Dès qu'une requête est faite à une
ressource externe dans le code source, elle est transmise à la boucle
d'événements. Un rappel est enregistré pour la requête, qui la transmet au
système d'exploitation, Node.js reprend alors le contrôle et peut poursuivre
l'exécution de l'application. Dès que l'opération externe est terminée, le
résultat est renvoyé dans la boucle d'événements. Un événement se produit
et la boucle d'événements garantit que les fonctions de rappel associées sont
exécutées. La boucle d'événements originale utilisée dans Node.js est basée
sur libev, une bibliothèque écrite en C et pour des performances élevées et
un large éventail de fonctionnalités. libev s'appuie sur les approches de
libevent, mais a des performances supérieures à celles de divers documents
de référence. Même une version améliorée de libevent, libevent2, ne
correspond pas aux performances de libev. Pour des raisons de
compatibilité, la boucle d'événements a cependant été abstraite et une
meilleure portabilité vers d'autres plates-formes a été obtenue.
Entrée et sortie
La boucle d'événements seule en combinaison avec le moteur V8 permet
d'exécuter JavaScript, mais il n'y a toujours aucun moyen d'interagir avec le
système d'exploitation directement sous la forme d'opérations de lecture ou
d'écriture sur le système de fichiers. Lors de la mise en œuvre d'applications
côté serveur, l'accès au système de fichiers joue un rôle primordial, par
exemple, la configuration d'une application est souvent externalisée vers un
fichier de configuration distinct. Cette configuration doit être lue par
l'application à partir du système de fichiers. Mais aussi l'utilisation de
modèles dynamiques. Les valeurs remplies puis envoyées au client sont
généralement disponibles sous forme de fichiers séparés. Non seulement la
lecture, mais aussi l'écriture d'informations dans des fichiers est souvent une
exigence placée sur une application JavaScript côté serveur. La
journalisation au sein d'une application est également un domaine
d'utilisation fréquent pour l'accès en écriture au système de fichiers.
Différents types d'événements au sein de l'application sont enregistrés dans
un fichier journal. Selon l'endroit où l'application s'exécute, seules les
erreurs graves, les avertissements ou les informations d'exécution sont
écrits. L'accès en écriture est également utilisé pour conserver les
informations. Pendant l'exécution d'une application, des informations sont
générées, généralement via l'interaction des utilisateurs et divers calculs, qui
doivent être enregistrées pour une utilisation ultérieure. La bibliothèque C
libeio est utilisée dans Node.js pour ces tâches. Il garantit que les opérations
d'écriture et de lecture peuvent se dérouler de manière asynchrone et
fonctionne donc très étroitement avec la boucle d'événements. Cependant,
les fonctionnalités de libeio ne sont pas seulement limitées à l'accès en
lecture et en écriture au système de fichiers, mais offrent également
beaucoup plus d'options d'interaction avec le système de fichiers. Ces
options vont de la lecture des informations sur les fichiers, telles que la
taille, la date de création ou la date d'accès, à la gestion des répertoires,
c'est-à-dire la création ou la suppression, à la modification des droits
d'accès. Comme pour la boucle d'événements, cette bibliothèque lui
applique également pendant le processus de développement une couche
d'abstraction a été séparée de l'application réelle. Node.js fournit son propre
module, le module du système de fichiers, pour accéder au système de
fichiers. Les interfaces de libeio peuvent être adressées via ceci, ce qui en
fait un wrapper très léger autour de libeio.

Libuv
Les deux bibliothèques que vous avez apprises jusqu'à présent s'appliquent
à Linux.Node.js mais devraient devenir une plate-forme indépendante du
système d'exploitation, c'est pourquoi la bibliothèque libuv a été introduite
dans la version 0.6 de Node.js. Il est principalement utilisé pour résumer les
différences entre les différents systèmes d'exploitation. L'utilisation de libuv
permet à Node.js de s'exécuter sur les systèmes Windows. La structure sans
libuv, telle qu'elle était valable pour Node.js jusqu'à la version 0.6,
ressemble à ceci: Le noyau est le moteur V8, qui est complété par libev et
libeio avec la boucle d'événements et l'accès asynchrone au système de
fichiers. Avec libuv, ces deux bibliothèques ne sont plus directement
intégrées à la plateforme, mais sont abstraites. Pour que Node.js fonctionne
sous Windows, il est nécessaire de rendre les composants principaux
disponibles pour les plates-formes Windows. Le moteur V8 n'est pas un
problème ici, il fonctionne dans le navigateur Chrome depuis plusieurs
années sans problème sous Windows. La situation devient plus difficile
avec la boucle d'événements et les opérations de système de fichiers
asynchrones. Certains composants de libev devraient être réécrits lorsqu'ils
sont utilisés sous Windows. Libev est également basé sur des
implémentations natives du système d'exploitation de la fonction de
sélection , mais sous Windows IOCP est une variante optimisée pour le
système d'exploitation. Afin de ne pas avoir à créer différentes versions de
Node.js pour les différents systèmes d'exploitation, les développeurs ont
décidé d'ajouter une couche d'abstraction avec libuv qui permet d'utiliser
libev pour les systèmes Linux et IOCP pour Windows. Certains concepts de
base de Node.js ont été adaptés avec libuv. Par exemple, on ne parle plus
d'événements, mais d'opérations. Une opération est transmise au composant
libuv, dans libuv l'opération est transmise à l'infrastructure sous-jacente,
c'est-à-dire libev ou IOCP. Ainsi, l'interface de Node.js reste inchangée,
quel que soit le système d'exploitation utilisé. Libuv est responsable de la
gestion de toutes les opérations d'E / S asynchrones. Cela signifie que tous
les accès au système de fichiers, qu'il soit en lecture ou en écriture, sont
effectués via les interfaces libuv. Pour cela, libuv fournit les fonctions
uv_fs_ . Cependant, les temporisateurs, c'est-à-dire les appels dépendant du
temps et les connexions TCP et UDP asynchrones, fonctionnent également
via libuv. En plus de ces fonctionnalités de base, libuv gère également des
fonctionnalités complexes telles que la création, le frai, les processus
enfants et la planification des pools de threads, une abstraction qui permet
d'exécuter des tâches dans des threads séparés et des rappels y sont liés.
L'utilisation d'une couche d'abstraction comme libuv est un élément
important pour la diffusion ultérieure de Node.js et rend la plate-forme un
peu moins dépendante du système.

DNS
Les racines de Node.js se trouvent sur Internet, comme son histoire le
montre. Si vous vous déplacez sur Internet, vous rencontrerez rapidement le
problème de la résolution de noms . En fait, tous les serveurs sur Internet
sont adressés via leur adresse IP. Dans la version 4 du protocole Internet,
l'adresse est un nombre de 32 bits qui est représenté en quatre blocs de 8
bits chacun. Dans la sixième version du protocole, les adresses ont une
taille de 128 bits et sont divisées en huit blocs avec des nombres
hexadécimaux. Dans les cas les plus rares, vous souhaitez travailler
directement avec ces adresses cryptées, en particulier si l'attribution
dynamique est ajoutée via DHCP. La solution à cela est le système de noms
de domaine, ou DNS en abrégé. Le DNS est un service de résolution de
noms dans le réseau. Il garantit que les noms de domaine sont convertis en
adresses IP. Il existe également l'option de résolution inverse, dans laquelle
une adresse IP est traduite en nom de domaine. Si vous connectez un
service Web dans votre application Node.js ou que vous souhaitez lire un
site Web, le DNS est également utilisé ici. En interne, Node.js ne prend pas
en charge la résolution de nom elle-même, mais transfère les requêtes
respectives à la bibliothèque C-Ares. Ceci s'applique à toutes les méthodes
du module dns à l' exception de dns.lookup , qui repose sur la fonction
getaddrinfo du système d' exploitation . Cette exception est due au fait que
getaddrinfo est plus constant dans ses réponses que la bibliothèque C-Ares,
qui à son tour est beaucoup plus performante que getaddrinfo .
1.5.5Crypto Le composant crypto de la plate-forme Node.js vous offre
diverses options de cryptage pour le développement. Ce composant est
basé sur OpenSSL. Cela signifie que ce logiciel doit être installé sur votre
système afin de crypter les données. Avec le module crypto, vous pouvez
crypter des données avec différents algorithmes ainsi que créer des
signatures numériques au sein de votre application. L'ensemble du système
est basé sur des clés privées et publiques. Comme son nom l'indique, la clé
privée n'est destinée qu'à vous et à votre application. La clé publique est
disponible pour vos partenaires de communication. Si le contenu doit
maintenant être chiffré, cela se fait avec la clé publique. Les données ne
peuvent alors être déchiffrées qu'avec votre clé privée. Il en va de même
pour la signature numérique des données. Votre clé privée est utilisée ici
pour générer une telle signature. Le destinataire d'un message peut alors
utiliser la signature et votre clé publique pour déterminer si le message
provient de vous et est inchangé.

Zlib
Lors du développement d'applications Web, en tant que développeur, vous
devez toujours penser aux ressources de vos utilisateurs et à votre propre
environnement serveur. Par exemple, la bande passante disponible ou la
mémoire libre pour les données peut signifier une limitation. Dans ce cas, le
composant Zlib existe dans la plate-forme Node.js. Avec leur aide, les
données peuvent être compressées et décompressées lorsque vous souhaitez
les traiter. Les deux algorithmes Deflate et Gzip sont disponibles pour la
compression de données. Les données utilisées comme entrée pour les
algorithmes sont traitées comme des flux par Node.js. Node.js n'implémente
pas les algorithmes de compression lui-même, mais s'appuie à la place sur
le Zlib établi et transmet les requêtes. Le module zlib de Node.js est juste
un wrapper léger pour le Zlib et garantit que les flux d'entrée et de sortie
sont gérés correctement.

Analyseur HTTP
En tant que plate-forme pour les applications Web, Node.js doit non
seulement gérer les flux, les données compressées et le cryptage, mais
également le protocole HTTP. L'analyse du protocole HTTP étant une
procédure très complexe, l'analyseur HTTP, qui prend en charge cette tâche,
a été externalisé vers un projet séparé et est désormais intégré par la
plateforme Node.js. Comme les autres bibliothèques externes, l'analyseur
HTTP est écrit en C et sert d'outil performant pour lire les requêtes et les
réponses du protocole HTTP. Pour vous en tant que développeur, cela
signifie que vous pouvez utiliser l'analyseur HTTP, par exemple, pour lire
vous-même les différentes informations de l'en-tête HTTP ou le texte du
message. Le principal objectif de développement de Node.js est de fournir
une plate-forme haute performance pour les applications Web. Pour
répondre à cette exigence, Node.js s'appuie sur une approche modulaire.
Cela permet l'intégration de bibliothèques externes telles que la libuv déjà
décrite ou le HTTP-Par-ser. L'approche modulaire est poursuivie par les
modules internes de la plateforme Node.js et s'étend aux extensions que
vous créez pour votre propre application. Au cours de ce livre, vous
apprendrez à connaître les différentes possibilités et technologies que la
plate-forme Node.js vous offre pour développer vos propres applications.
Cela commence par une introduction au système de modules de Node.js.

Sommaire
Dans ce chapitre, vous avez appris comment Node.js est structuré et quels
avantages vous obtenez de cette structure. Vous avez également appris
quelques faits sur l'historique de développement de la plateforme. Dans le
chapitre suivant, vous apprendrez comment installer Node.js sur votre
système et comment vous pouvez tester les fonctionnalités de cette
installation.
CHAPITRE 1
Installation

L'homme élargit le chemin et non le chemin


élargit l'homme. - Confucius

Les composants de Node.js ont été développés en C ++. Cela signifie que la
plate-forme entière est fondamentalement relativement indépendante du
système d'exploitation sur lequel elle s'exécute. Cette indépendance de
plate-forme signifie que vous pouvez installer Node.js sur des systèmes
UNIX tels que Linux ou Mac OS X ainsi que sur Windows. Node.js a été
initialement développé pour être installé et utilisé sur les systèmes UNIX.
Vous pouvez toujours déterminer cette origine car certaines fonctionnalités
ne sont pas disponibles sous Windows. Par exemple, diverses fonctions du
module de processus ne sont pas disponibles. Vous pouvez observer une
autre différence dans le module fs , qui fournit la fonctionnalité de système
de fichiers pour Node.js. La fonctionnalité de montre actuellement encore
instable est basée sur les interfaces fournies par le système d'exploitation et
se comporte donc quelque peu différemment sur les différents systèmes. En
résumé, on peut dire que Node.js fonctionne de manière stable et fiable sur
les trois plates-formes mentionnées. Lorsque vous utilisez les différentes
fonctionnalités, en tant que développeur, vous devez toujours consulter la
documentation de l'API à l'adresse http://nodejs.org/api/ pour vous assurer
que les fonctionnalités respectives sont également disponibles sur votre
système cible de la manière attendue.En ce qui concerne la gestion des
versions, Node .js suit l'approche classique. Cela signifie qu'un numéro de
version de Node.js se compose de trois parties: la version majeure, la
version mineure et le niveau du correctif. Le nom d'un package Node.js, tel
qu'il est disponible sur le site Web Node.js, se compose comme suit: node-v
<major>. <mineur>. <patch>, suivi principalement d'informations sur le
système d'exploitation et l'architecture cible. Par exemple, pour un système
Linux avec un processeur 64 bits, cela conduit au nom suivant: node-
v0.10.9-linux-x64.tar.gz. Une augmentation de la version majeure signifie
que dans notre cas, il y a eu de sérieux changements à Node.js et il ne peut
être garanti que les applications existantes peuvent être exécutées sans
ajustements importants. L'indication de la version mineure a deux
significations: Premièrement, une augmentation de ce numéro de version
indique que Node.js a des améliorations et améliorations supplémentaires,
et deuxièmement, les numéros de version signifient qu'il s'agit d'une version
stable de Node.js. Une version mineure étrange signifie que vous utilisez la
branche développeur de Node.js. Le niveau du correctif est augmenté assez
souvent, il indique seulement que la version utilisée contient les plus petites
mises à jour et corrections de bogues. Selon les explications précédentes,
encore assez théoriques, les sections suivantes traitent de l'installation de la
plateforme Node.js. À la fin de ce chapitre, vous devriez avoir une
installation fonctionnelle de Node.js installée sur votre système, que vous
utilisiez Linux, Mac OS X ou Windows. Tout au long de ce chapitre, vous
serez guidé étape par étape tout au long du processus d'installation.
L'installation des packages pour votre système d'exploitation respectif est
principalement traitée. Vous apprendrez également comment compiler et
installer le code source sur votre système.

Installation de packages
Le moyen le plus simple d'installer Node.js sur votre système consiste à
utiliser les packages existants pour votre système. L'avantage de ceci est
que vous pouvez utiliser le gestionnaire de paquets de votre système, qui
effectue la plupart du travail pour vous pendant l'installation. Vous n'avez
pas à vous soucier de la résolution des dépendances ici et pouvez donc
installer Node.js sur votre système en quelques lignes sur la ligne de
commande ou en quelques clics, selon le système d'exploitation que vous
utilisez. Node.js est un projet open source et est donc disponible
gratuitement sur le site http://nodejs.org/download/. Ici, vous pouvez
télécharger les packages pour différents systèmes d'exploitation et
architectures informatiques sur votre ordinateur en utilisant les liens
respectifs. La figure montre le tableau des différentes versions disponibles
au téléchargement.

Les sections suivantes traitent de l'installation de packages pour un système


d'exploitation spécifique. Il suffit généralement de lire la section appropriée
pour votre système, puis de passer au chapitre 3, «Un premier exemple». Si
vous souhaitez compiler et installer Node.js à partir du code source, vous
pouvez continuer directement avec la Section 2.2, «Compilation et
installation», dans laquelle ce processus est décrit en détail. 2.1.1Linux
Tout d'abord, dans les sections suivantes, vous lirez comment installer
Node.js sur un système Linux. Ici, vous avez deux options pour installer
Node.js. La première consiste à installer les binaires Linux, que vous
pouvez télécharger sur http://nodejs.org. La deuxième variante est
l'utilisation du gestionnaire de packages du système d'exploitation. Dans la
première variante de l'installation, les différentes distributions ne diffèrent
pas, car le paquet binaire Linux contient déjà les fichiers exécutables et le
paquet est seulement décompressé et correctement intégré dans le système
doit devenir. Selon la norme de hiérarchie du système de fichiers pour les
systèmes UNIX, le répertoire / opt sert de conteneur pour des logiciels
supplémentaires, ce répertoire convient donc comme emplacement de
stockage pour les binaires Node.jsLinux. L'installation des packages est
décrite dans le Listing 2.1.
$ cd / home / <username> / Downloads
$ wget http://nodejs.org/dist/v0.10.9/node-v0.10.9-linux-x64.tar.gz--2012-
11-03 01: 21: 34-- http://nodejs.org /dist/v0.10.9/node-v0.10.9-linux-
x64.tar.gzResolving nodejs.org (nodejs.org) ... 165.225.133.150 ...
$ cd / opt $ sudo tar xvzf /home/<username>/Downloads/node-v0.10.9-
linux-x64.tar.gz
[sudo] password for <username>: node-v0.10.9-linux-x64 / ...
$ sudo ln -s node-v0.10.9-linux-x64 nodejs
$
vous montre comment télécharger le package avec les binaires
Node.jsLinux sans interface utilisateur graphique. L' outil de ligne de
commande wget est utilisé pour cela. Il télécharge le package à partir du
serveur Web http://nodejs.org, puis le décompresse dans le répertoire / opt.
Pour pouvoir installer le logiciel dans ce répertoire, vous avez besoin d'une
autorisation root, ce que vous pouvez faire avec la commande sudo . Dans
la dernière étape, un lien symbolique avec le nom nodejs est créé sur le
répertoire, afin que vous vous épargniez davantage de paperasse et évitez
les erreurs lors de l'écriture du nom complet du répertoire. À ce stade, vous
pouvez déjà utiliser Node.js sur la ligne de commande si vous adressez le
fichier de nœud exécutable avec sa spécification de chemin absolu ou
relatif. Cependant, cela signifie à son tour qu'en fonction de l'emplacement
de stockage, vous devez entrer une commande disproportionnellement
longue à chaque fois que vous l'appelez, avec laquelle les erreurs se glissent
facilement. Le but est maintenant d'appeler Node.js directement en entrant
la commande node , ce que vous pouvez facilement réaliser en incluant le
répertoire bin dans le chemin de recherche du système dans l'installation de
Node.js. Le listing 2.2 vous montre les lignes de commande nécessaires
pour étendre le chemin de recherche en conséquence.
PATH = $ PATH: / opt / nodejs / bin
export PATH
Après avoir entré les deux lignes de Listing sur votre ligne de commande,
vous pouvez utiliser Node.js. Le seul problème maintenant est que vous
devez saisir à nouveau ces commandes pour chaque session shell, car
l'extension du chemin de recherche n'est pas persistante. Cela est résolu en
incluant ces lignes dans l'un des fichiers de configuration du système. Dans
ce cas, puisque vous modifiez une variable d'environnement, le fichier / etc
/ profile est recommandé. Ajoutez simplement les deux lignes à la fin du
fichier, et Node.js est disponible sur la ligne de commande chaque fois que
vous vous connectez au système. La deuxième variante d'installation de
Node.js sous les systèmes Linux dépend du gestionnaire de packages de la
distribution respective. Ce qui suit montre comment installer Node.js sur un
système Ubuntu en quelques étapes seulement.
sudo apt-get install nodejs

La commande du Listing 2.3 utilise la version qui se trouve dans les


référentiels standard. Si vous installez Node.js de cette manière, vous avez
l'avantage que le logiciel est mis à jour automatiquement dès qu'une
nouvelle version est disponible dans le référentiel. L'inconvénient de cette
variante de l'installation est que les versions sont mises à jour très lentement
et que la version actuelle est donc rarement disponible. Il existe également
une solution aux inconvénients de ce type d'installation. Tout ce que vous
avez à faire est d'intégrer un référentiel supplémentaire. De plus, la version
actuelle de Node.js est disponible sous forme de package et peut être mise à
jour automatiquement si une nouvelle version est disponible. Le Listing2.4
vous montre les étapes individuelles que vous devez effectuer pour intégrer
le référentiel et installer Node.js à partir de celui-ci.

sudo apt-get install python-software-properties


sudo add-apt-repository ppa.chris-lea / node.js
sudo apt-get update
sudo apt-get install nodejs npm
Comme pour la plupart des opérations liées à la gestion des packages, vous
avez également besoin des autorisations root ici, ce qui est plus facile à
obtenir à l'aide de la commande sudo . Un inconvénient est l'installation de
Node.js via le gestionnaire de packages interne au système: vous n'avez
qu'une seule version de Node.js disponible. Si vous souhaitez tester votre
application sous différentes versions de Node.js, il vous suffit d'utiliser
différentes versions des binaires Linux de Node.js ou de la compiler
Différentes versions de Node.js à partir des fichiers source eux-mêmes.
Vous pouvez découvrir comment faire cela dans Section 2.2, «Compilation
et installation». Une fois que vous avez terminé ces étapes avec succès,
vous disposez d'une installation entièrement fonctionnelle de Node.js sur
votre système et vous pouvez commencer à développer vos propres
applications. Mais comment savoir si l'installation a fonctionné et si vous
utilisez la dernière version de Node.js? Le moyen le plus simple de le savoir
est de voir la version de votre installation Node.js. Le listing 2.5 vous
montre comment appeler Node.js pour voir les informations de version.
$ node –v
v0.10.9

Si vous voyez le numéro de version correct, cela signifie que l'installation a


réussi et que vous pouvez maintenant utiliser Node.js. Les sections
suivantes traitent de l'installation de la plate-forme Node.js sur d'autres
systèmes. Vous pouvez également sauter ceci et aller directement au
chapitre 3, «Un premier exemple», et aux premiers exemples pratiques
présentés ici sur Node.js. Si vous souhaitez à nouveau supprimer la plate-
forme Node.js de votre système, en fonction de la façon dont vous avez
installé Node.js, vous pouvez le faire facilement. Le moyen le plus simple
de supprimer les binaires Linux. Lors de l'installation, vous avez
décompressé une archive tar compressée. Dès que vous supprimez ce
répertoire extrait, Node.js est supprimé de votre système. La suppression
d'une installation Node.js qui a été effectuée à l'aide du gestionnaire de
paquets est également assez facile, comme indiqué dans l'extrait 2.6.
$ apt-get remove --purge nodejs
$ apt-get clean

La commande apt-get avec l' option remove garantit que l'installation de


Node.js sur votre système est supprimée. Avec --purge, des fichiers de
configuration possibles sont également créés lors de l'installation,
supprimés du système. La commande suivante, apt-get avec l' option
clean , est chargée de vider le cache de paquets et de libérer l'espace de
stockage utilisé. Les packages téléchargés pour l'installation se trouvent
dans le cache des packages. De cette façon, Node.js peut être complètement
supprimé du système.

les fenêtres
À l'origine, Node.js n'était disponible que sous Linux. Si vous vouliez
l'installer sous Windows, vous n'aviez pas d'autre choix que d'utiliser
Cygwin pour l'exécuter. Vous pouvez trouver ce projet à l'URL
http://www.cygwin.com/. Cygwin a fourni un environnement similaire à
Linux sous Windows pour exécuter le logiciel Linux ici. Avec la version
0.6, beaucoup de choses se sont passées concernant le support des
différentes plates-formes. L'introduction de la bibliothèque libuv, dont vous
avez pris connaissance dans la section 1.5.3, et donc l'abstraction de libev et
libeio, a permis d'exécuter Node.js nativement sous Windows, et sans
aucune solution de contournement supplémentaire ni logiciel
supplémentaire. Vous pouvez maintenant télécharger un package binaire
exécutable à partir de Node.js ainsi qu'un package .msi pour installer
Node.js à partir de la page de téléchargement Node.js. Node.js peut
fonctionner sur presque toutes les plates-formes Windows. La prise en
charge va de Windows2000 à Windows 8 pour les systèmes de bureau.
Node.js peut également être installé sur les systèmes serveur Windows.
Node.js est également disponible sur la plateforme cloud Microsoft Azure,
de sorte que les applications cloud avec Node.js sont également possibles.
Le moyen le plus simple d'exécuter Node.js sous Windows consiste à
utiliser le package binaire. Il vous suffit de le télécharger et de l'utiliser sans
autre installation. Node.js peut alors être démarré de deux manières
différentes, soit en double-cliquant sur le fichier node.exe, soit via la ligne
de commande. Le Listing 2.7 montre comment vous pouvez vérifier si
Node.js fonctionne sur votre système. Ici, on suppose que Filenode.exe se
trouve directement sur votre disque dur. Vous pouvez également enregistrer
le fichier dans n'importe quel répertoire.
C: \> node.exe –v
v0.10.9

L'utilisation de la version binaire de Node.js sous Windows présente des


inconvénients majeurs. Vous ne pouvez donc pas démarrer Node.js sur la
ligne de commande uniquement avec le nœud de commande . Pour ce
faire, vous devez développer manuellement le chemin de recherche du
système ou placer le fichier dans un répertoire qui est déjà inclus dans le
chemin de recherche. Un autre inconvénient de cette variante est que vous
ne pouvez utiliser la plate-forme Node.js qu'avec le fichier binaire, mais pas
le Node Package Manager, en bref: NPM. Vous pouvez le trouver sur
https://npmjs.org/. Vous pouvez également en savoir plus sur le gestionnaire
de paquets de Node.js. dans Section 4.4, «NPM». Vous pouvez éviter ces
inconvénients en utilisant la deuxième façon d'exécuter Node.js sous
Windows. En plus d'utiliser le fichier binaire node.exe, vous avez
également la possibilité d'installer Node.js sur votre système avec un
package .msi. Vous serez guidé tout au long de l'installation en quelques
étapes et pourrez ensuite utiliser Node.js sur votre système. Après avoir
double-cliqué sur le package du programme d'installation Node.js, le
programme d'installation interactif est lancé et vous êtes dans la fenêtre de
bienvenue, comme indiqué sur la figure.
Le bouton Suivant vous amène à la deuxième étape de l'installation. Vous
êtes ici présenté avec les informations de licence pour Node.js, que vous
devez accepter en cochant J'accepte les termes du contrat de licence.
Comme le montre la figure 2.3, vous avez la possibilité d'imprimer les
informations de licence, de revenir à la première étape ou d'accepter les
conditions de licence. Vous pouvez également annuler le processus
d'installation à tout moment à l'aide du bouton Annuler. Dès que vous avez
coché la case, vous pouvez démarrer l'installation proprement dite de
Node.js avec le bouton Suivant. Ici, les fichiers nécessaires sont copiés aux
bons endroits du système et le logiciel est enregistré afin que vous puissiez
ensuite utiliser Node.js sur votre système
Dès que toutes les tâches nécessaires pour que vous puissiez exécuter
Node.js sous Windows sont effectuées, l'affichage passe à la dernière étape
de l'installation. Ici, vous pouvez terminer l'installation de Node.js en
utilisant le bouton Terminer, comme le montre la figure 2.5.

Une fois la fenêtre de configuration fermée, vous pouvez ouvrir la fenêtre


de saisie (cmd.exe) et vérifier que l'installation de Node.js sur votre système
war.Zu réussit, exécutez comme décrit dans l'extrait 2.8, le nœud de
commande avec le - v option pour afficher les informations de version.
C: \> nœud - v
v0.10.9

Lors de l'installation avec le package .msi, veuillez noter que Node.js est
désormais disponible à l'échelle du système sur la ligne de commande et
que vous n'avez pas besoin d' ajuster les variables d'environnement. Vous
pouvez maintenant commencer à implémenter votre première application
avec Node.js. Si à tout moment vous souhaitez supprimer Node.js de votre
système, ce n'est pas non plus un problème. Selon la façon dont vous avez
procédé à l'installation, vous pouvez choisir l'une des deux options pour
supprimer Node.js de votre système Windows. Si vous définissez les
binaires Windows de Node.j, il vous suffit de supprimer le fichier node.exe
de votre système. Si vous avez installé Node.js via le package .msi sur votre
système, vous pouvez utiliser Windows Software Management pour
supprimer Node.js. Vous pouvez accéder au Panneau de configuration dans
Windows 8 via l'Explorateur Windows en sélectionnant Ordinateur sur la
gauche et l'élément de menu Ordinateur, puis en cliquant sur Panneau de
configuration. Vous pouvez y obtenir une vue d'ensemble via le lien
Désinstaller le programme sous l'élément Programmes, dans lequel vous
devez sélectionner le programme Désinstaller sous Programmes et
fonctions pour obtenir une liste de tous les composants logiciels installés
sur votre système. Il y a une entrée dans cette liste appelée Node.js.
Sélectionnez ceci, puis cliquez sur Désinstaller, supprimez Node.js de votre
système. Le reste du chapitre traite de l'installation de Node.js sur Mac OS
X et de la compilation de Node.js à partir des fichiers source. Si vous
voulez commencer à développer directement avec Node.js, vous pouvez
continuer avec le chapitre 3, "Un premier exemple".

Mac OS X
Pour Mac OS X, comme pour Windows, vous pouvez télécharger un
package binaire et un package d'installation pour l'installation. Le moyen le
plus simple d'exécuter Node.js sur Mac OS X consiste à utiliser le package
binaire. Le paquet se présente sous la forme d'une archive tar compressée et
il vous suffit de le décompresser sur la ligne de commande, comme vous
pouvez également le voir dans le Listing 2.9.
$ tar xvzf node-v0.10.9-darwin-x64.tar.gz
$ cd node-v0.10.9-darwin-x64
$ bin / node - v
v0.10.9

Comme le montre la liste, Node.js peut être utilisé directement après le


déballage. Avec l'option -v, vous pouvez afficher les informations de
version et vérifier s'il s'agit de la bonne version et si Node.js fonctionne en
principe. L'inconvénient de l'installation du package binaire est que Node.js
n'est pas disponible à l'échelle du système sur la ligne de commande. Ce
problème est résolu en utilisant le programme d'installation. L'installation
démarre en double-cliquant sur le fichier pkg téléchargé. Vous serez ensuite
guidé à travers un processus interactif en plusieurs étapes qui se traduira par
une installation fonctionnelle de Node.js. La figure 2.6 montre la première
étape de l'installation, dans laquelle vous êtes informé que Node.js et NPM
sont installés dans le répertoire / usr / local / bin. Cliquez sur Continuer
pour continuer l'installation.
Dans l'étape suivante de l'installation, les conditions de licence de Node.js
sont présentées. Comme le montre la figure 2.7, vous avez la possibilité de
choisir différentes langues dans lesquelles les informations pertinentes sont
affichées. Vous pouvez également imprimer les termes de la licence ou les
enregistrer sur votre système.
Au fur et à mesure de la progression de l'installation, vous pouvez utiliser le
bouton Revenir pour revenir à l'étape d'installation précédente. Après avoir
cliqué sur Continuer, il vous sera demandé dans une fenêtre contextuelle
distincte si vous acceptez les termes de la licence et continuez l'installation.
Vous avez ici le choix soit d'accepter, cela se fait en cliquant sur le bouton
Accepter, et de continuer le processus d'installation avec lui ou de ne pas
accepter et d'annuler l'installation que vous souhaitez installer sur votre
ordinateur. Pour ce faire, cliquez sur Installer pour tous les utilisateurs de
cet ordinateur pour rendre Node.js disponible à l'échelle du système. La
figure montre cette étape de l'installation
Ici, vous recevrez également une indication de l'espace supplémentaire qui
sera utilisé après l'installation de Node.js. En cliquant sur Continuer, vous
passerez à l'étape suivante, où vous pourrez ajuster l'emplacement de
Node.js comme indiqué dans l'image. Confirmez en cliquant sur Installer
que vous acceptez le placement de Node.js sur votre système. Vous devez
maintenant entrer votre nom d'utilisateur et le mot de passe correspondant
pour que le logiciel puisse être installé correctement sur votre système. Dès
que vous avez saisi et confirmé ces informations, l'installation proprement
dite de Node.js commence et les fichiers sont copiés du package
d'installation dans le système. À partir de ce moment, vous ne pouvez plus
revenir en arrière via GoBack .
Une
fois que tous les fichiers ont été copiés, l'installation est terminée et vous
recevrez un bref résumé, comme le montre la figure 2.10.
Vous allez maintenant découvrir où Node.js et NPM ont été installés et quel
répertoire vous devez inclure dans votre variable PATH afin de pouvoir
utiliser Node.js sur la ligne de commande avec la commande node sans
spécifier le chemin complet. Par défaut, le répertoire / usr / local / bin est
dans le chemin de recherche du système, comme vous pouvez le voir dans
la liste.

$ echo $ PATH
/ usr / bin: / bin: / usr / sbin: / sbin: / usr / local / bin: / usr / X11 / bin

Si vous avez suivi les étapes pour installer Node.js comme décrit, vous
pouvez maintenant utiliser la plateforme. Pour vous assurer que la version
actuelle a vraiment été installée et que Node.js fonctionne correctement,
vous pouvez afficher les informations de version sur la ligne de commande.
Le Listing 2.11 montre comment faire cela.

$ node - v
v0.10.9

Dans le cas où vous souhaitez supprimer Node.js de votre système, vous


pouvez supprimer le répertoire précédemment extrait si vous utilisez le
package binaire. Si vous avez installé Node.js via le programme
d'installation, vous pouvez également supprimer Node.js de votre système.
Dans ce cas, utilisez le programme d'installation de pkg pour consigner les
fichiers copiés sur votre système. Les informations se trouvent dans / var /
db / receipts / et se trouvent dans les fichiers org.nodejs.node.npm.pkg.bom
et org.nodejs.pkg.bom. L'extension de fichier.bom signifie "Nomenclature",
ce qui signifie liste de pièces. L'emplacement des fichiers par rapport à
l'emplacement de l'installation est enregistré dans ces fichiers. Étant donné
que toutes les informations, telles que la liste des fichiers et l'emplacement
de l'installation, sont au format binaire, pkgutil est un outil que vous
pouvez utiliser pour générer les informations. pkgutil fonctionne avec les
noms de package. Le nom de votre package Node.js est org.nodejs.pkg .
Comme le montre le Listing 2.12, les méta-informations peuvent être
affichées avec l' option --pkg-info .

$ pkgutil --pkg-info org.nodejs.pkg


package-id: org.nodejs.pkg
version: 1.0
volume: / location: usr / local
install-time: 1352148814
Comme le montre la liste, vous avez installé Node.js sur le volume / sous le
chemin usr / local. Ce chemin est le préfixe de la liste de fichiers que vous
pouvez obtenir à partir du fichier .bom. La liste montre comment faire cela.

$ pkgutil --lsbom org.nodejs.pkg


../bin
./bin/node
./bin/node-waf
./bin/npm
./include
./include/node
Dans les versions précédentes, l' option --unlink était disponible pour
pkgutil pour supprimer complètement un package. Dans les versions plus
récentes, cette option a été supprimée car la suppression d'un package peut
affecter d'autres logiciels installés sur votre système. Pour cette raison, une
extrême prudence est requise si vous souhaitez supprimer un logiciel qui a
été installé avec le programme d'installation de pkg. Dans le cas le plus
simple, vous supprimez les fichiers installés manuellement ou créez un
script shell qui itère sur la liste de fichiers et supprime les fichiers. Si vous
avez supprimé les fichiers du package, vous pouvez supprimer les
informations du package avec pkgutil . Le Listing 2.14 vous montre la
ligne de commande requise pour cela.

$ pkgutil --forget org.nodejs.pkg

Il existe de nombreux avantages à installer Node.js à partir d'un package


pré-construit. Surtout, l'installation est simple et vous n'avez pas à prendre
en compte de dépendances. Il est également possible de supprimer ces
packages du système. En plus de cette variante de l'installation, une autre
option est disponible: vous pouvez télécharger le code source depuis
Node.js et le compiler vous-même et l'installer sur le système. Les sections
suivantes décrivent comment passer des fichiers source à une version
exécutable de Node.js. Après avoir suivi les étapes d'installation
individuelles, vous disposez maintenant d'une version exécutable de
Node.js avec laquelle vous pouvez développer vos propres applications.
Dans le chapitre 3, «Un premier exemple», en fonction de votre installation,
vous serez guidé étape par étape pour programmer votre première
application sous Node.js. Le reste de ce chapitre explique comment
compiler et installer manuellement Node.js à partir du code source. Si ce
n'est pas une option pour vous, vous pouvez passer directement au chapitre
3.

Compiler et installer
Dans cette section, vous apprendrez comment ne pas exécuter Node.js à
l'aide de packages binaires ou en l'installant avec un programme
d'installation pour votre système, mais comment créer une installation
personnalisée à partir des fichiers source de votre système. Ci-dessous, vous
apprendrez comment compiler Node.js sur un système Linux. Pour cela,
une installation standard d'un bureau Ubuntu en version 12.04 LTS est
supposée. La première étape de l'installation est que vous devez télécharger
le code source à partir de Node.js. Ceci est disponible sur nodejs.org dans la
zone de téléchargement en tant qu'archive tar compressée. Avant de pouvoir
commencer à compiler Node.js, vous devez vous assurer que vous disposez
d'un compilateur. Par défaut, ce n'est pas le cas avec la version de bureau
d'Ubuntu, mais vous pouvez installer le compilateur plus tard à l'aide du
gestionnaire de paquets du système. Le Listing 2.15 montre la ligne de
commande requise pour cela.
$ sudo apt-get install g ++

Une fois cette condition préalable remplie, vous pouvez extraire le package
de code source, comme vous pouvez le voir dans la liste, et basculer vers le
répertoire résultant.
$ tar xvzf node-v0.10.9.tar.gz
$ cd node-v0.10.9
La première étape du processus de compilation proprement dit consiste à
créer un makefile. Ce fichier est utilisé ultérieurement par la commande
make comme base pour la traduction de Node.js. Cependant, vous ne devez
pas créer le fichier Make manuellement, le programme configure existe
pour cela. Des informations supplémentaires relatives à l'installation
peuvent être transmises à cette commande, par exemple les options --
without-npm pour éviter d'installer le gestionnaire de packages de Node.js,
ou --without-ssl pour installer Node.js sans SSL à construire. Il existe
également la possibilité d'intégrer diverses bibliothèques telles que V8,
OpenSSL ou zlib en tant que bibliothèques partagées au lieu de les lier
statiquement. Avec l'option --dest-cpu = vous pouvez choisir l'architecture
cible, les valeurs possibles ici sont pauvres , ia32 et x64 . Vous pouvez
également sélectionner le système d'exploitation pour lequel Node.js doit
être construit. Dans ce cas, vous pouvez passer l'option --dest-os = à win ,
mac ou linux , entre autres. Une option importante pour configure est --
prefix . Cela spécifie l'emplacement où Node.js doit être installé. Si vous
n'utilisez pas cette option, le standard / usr / local est utilisé. Par rapport à ce
chemin, tous les fichiers de Node.js sont copiés sur le système. Vous pouvez
utiliser cette option pour garder l'option ouverte pour installer plusieurs
versions de Node.js sur votre système. Avec la commande ./configure--help,
vous obtenez une liste de toutes les options de configuration disponibles, y
compris une brève explication. La liste montre les prochaines étapes du
processus.
$ ./configure --prefix = / opt / node / node-v0.10.9
{'target_defaults': ...
$ make
python tools / gyp_node -f make
... $ sudo make install
make -C out BUILDTYPE = Release V = 1
...
Comme déjà mentionné, la première commande de la liste, configure , est
utilisée pour créer le makefile pour Node.js. L'option prefix = / opt / node /
node-v0.10.9 USAGE-pour faire cela afin que Node.js s'installe dans un
répertoire séparé. Ces informations sont enregistrées dans le makefile. La
commande suivante, make , s'appuie sur les informations du Makefile,
recherche la première cible et construit le projet en fonction des
informations présentes, dans votre cas Node.js. Le but de cette étape du
processus est d'obtenir une version exécutable de Node.js, qui se trouve
cependant toujours dans le répertoire dans lequel vous vous trouvez
actuellement, c'est-à-dire dans le code source décompressé. La dernière
commande, makeinstall , garantit enfin que les fichiers compilés sont
copiés au bon endroit dans le système. Pour cette raison, vous devez
également exécuter makeinstall avec les privilèges root, car un utilisateur ne
devrait normalement pas avoir accès en écriture à / opt, votre cible
d'installation actuelle. Après ces étapes, vous devez créer un nouveau
répertoire sur votre système dans le répertoire / opt. noeud de dessin peut
voir. Votre Node.js. est maintenant dans ceci Vous pouvez tester cela en
exécutant la commande node avec l' option -v dans le sous-répertoire
node-v0.10.9 / bin. Vous recevrez le numéro de version de votre installation
Node.js en sortie. Si ce test a fonctionné, vous pouvez supprimer le
répertoire contenant le code source extrait de votre système, car vous n'avez
plus besoin des deux. Comme avec les packages binaires sous Linux, cette
variante d'installation présente également le problème que vous ne pouvez
pas exécuter Node.js à l'échelle du système à partir de la ligne de
commande, mais devez toujours spécifier le chemin d'accès au fichier
exécutable en entier. La section suivante de ce chapitre est consacrée à ce
problème. Avec l'installation dans le répertoire / opt, vous avez la possibilité
d'exécuter plusieurs versions de Node.js en parallèle sur votre système. Si
vous souhaitez développer une application qui devrait fonctionner sur
différentes versions de Node.js et que vous souhaitez tester cela, vous
pouvez le faire. Par exemple, vous pouvez exécuter une version de 0.6, une
de 0.8 et une de 0.10. Normalement, cependant, vous souhaitez
probablement avoir la dernière version de Node.jsglobal disponible sur
votre système. Le moyen le plus simple et le plus rapide de le faire est
d'avoir un lien symbolique vers la version de Node.js que vous souhaitez
avoir globalement disponible et d'inclure ce lien symbolique dans le chemin
de recherche de votre système. Cette procédure vous permet de changer la
version de Node.js en ajustant ce lien. Le listing 2.18 montre comment créer
le lien.
$ ln -s /opt/node/node-v0.10.9 / opt / node / node

Comme dernière étape, vous devez développer le chemin de recherche avec


une entrée dans le fichier / etc / profile, comme vous pouvez le voir dans
l'extrait 2.19.

PATH = $ PATH: / opt / node / node / bin


export PATH

Vous avez maintenant une installation fonctionnelle de Node.js et vous


pouvez le tester facilement en entrant le noeud de commande avec l'option
-v sur la ligne de commande. La sortie est le numéro de version de
l'installation de Node.js. Vous pouvez maintenant commencer à développer
vos propres applications avec Node.js. Le chapitre 3, "Un premier
exemple", vous donne une première introduction au développement avec
Node.js et montre pas à pas l'implémentation d'une première application.

Sommaire
Au cours de ce chapitre, vous avez vu à quel point il est facile d'installer
Node.js sur votre système. Peu importe que vous exécutiez un système
Windows, Linux ou Mac OS X. Il existe plusieurs façons d'installer Node.js
sur votre système. Les variantes vont de la simple installation des packages
binaires, qu'il vous suffit de décompresser sur votre système, à la
compilation et à l'installation du code source de Node.js. En fonction de la
variante d'installation que vous avez choisie, vous pouvez également
supprimer le logiciel installé de votre système. Dans le chapitre suivant,
vous verrez comment vous pouvez développer une première application
avec Node.js en fonction de votre installation.
.
CHAPITRE 2
Un premier exemple
Si nous nous efforçons de trouver l'inconnu, alors nous serons courageux,
meilleurs et plus actifs que ceux qui pensent que l'inconnu ne peut être
trouvé. - Plato Si vous êtes arrivé ici, vous devriez déjà avoir une
installation fonctionnelle de la plate-forme node .js sur votre système. Pour
les exemples suivants, Node.js est utilisé sur la ligne de commande d'un
système Linux. Cependant, les exemples fonctionnent de la même manière
sous Windows et Mac OS X. Vous pouvez utiliser Node.js de deux
manières différentes. D'une part, il y a un shell interactif et d'autre part, il
existe un mode dans lequel au lieu d'une interaction de l'utilisateur, un
fichier avec le code source JavaScript est passé et doit être exécuté.

Le mode interactif
Tout d'abord, en savoir plus sur le mode interactif de Node.js. Vous pouvez
y parvenir, comme vous pouvez le voir dans le Listing 3.1, en entrant le
noeud de commande sur la ligne de commande.
$ node>
En mode interactif, vous pouvez directement saisir et exécuter du code
JavaScript sur la ligne de commande. Ce type d'interface utilisateur est
appelé REPL. L'acronyme signifie Read-Eval-Print Loop et signifie que les
commandes dos sont lues sur la ligne de commande, puis évaluées, et le
résultat est ensuite sorti sur la ligne de commande. Ce mode n'est pas
destiné à implémenter et exécuter des applications complètes. Au lieu de
cela, cette interface Node.js est utilisée pour tester le comportement et la
fonctionnalité des extraits de code individuels. La liste vous montre
comment émettre des commandes dans Node.js REPL
$ node>
console.log ( "Hello world!");
Hello World!
Undefined
>

Les commandes JavaScript se terminent également dans Node.js REPL par


un point-virgule. Un saut de ligne met fin à l'entrée de la commande en
cours et envoie la commande au moteur JavaScript. console.log avec
l'argument HalloWelt! est évalué et le résultat HalloWelt! est affiché sur la
ligne de commande. Comme vous pouvez le voir dans l'extrait 3.2, à côté
du Hello World! la valeur non définie est également sortie. En effet, la
valeur de retour de la fonction console.log est affichée, dans ce cas indéfinie
. En plus de l'exécution des sorties, vous pouvez exécuter toutes les
commandes JavaScript dos disponibles dans NPL.js dans le REPL.
L'exemple de la liste illustre cela.
> function greet (name) {
console.log ( "Hello" + name);
}; greet ("world");
Hello World
Undefined
>

Dans le Listing 3.3, vous pouvez voir comment définir une fonction dans
Node.js REPL, qui reçoit un nom en paramètre, et comment elle est sortie
sur la console pendant la fonction. Après la définition, la fonction greet est
appelée avec l'argument world comme nom. La sortie se compose de
HalloWelt et indéfini . Si vous souhaitez exécuter diverses commandes
dans Node.js REPL qui se construisent les unes sur les autres, vous pouvez
facilement le faire. Par exemple, si vous définissez des fonctions ou
effectuez une affectation de variables, celles-ci sont conservées même après
l'évaluation de la ligne de commande. Vous pouvez voir comment ce fait
fonctionne réellement dans Listing.
$ node
> var myVar = "Hello world!";
Undefined
> console.log (myVar);
Hello World!
Undefined
>
Dans l'exemple du Listing 3.4, vous attribuez une valeur à la variable
myVar . Cette variable sera utilisée dans l'instruction suivante de la sortie.
L'une des fonctionnalités les plus importantes de Node.js REPL est la saisie
semi-automatique. Vous pouvez utiliser cette fonctionnalité en tapant des
lettres sur la ligne de commande et en appuyant sur la touche Tab. Node.js
montre les ajouts disponibles. Une autre caractéristique à mentionner est les
commandes multi-lignes. Comme vous pouvez le voir dans le Listing 3.3, le
code de fonction n'est pas entré sur une seule ligne, mais sur plusieurs
lignes. Une commande incomplète est indiquée par trois points au lieu du
signe supérieur à comme invite de commande. Les commandes multilignes
peuvent être atteintes, par exemple, via des blocs de code incomplets ou un
opérateur plus pour le calcul ou la concaténation de chaînes à la fin de la
ligne. L'une des particularités de Node.js REPL est qu'en plus du jeu de
commandes JavaScript, il vous donne également quelques commandes
supplémentaires pour contrôler les offres REPL. La commande dos
commence toujours par un point et ne doit pas nécessairement se terminer
par un point-virgule. Le tableau 3.1 vous présente un aperçu de ces
commandes.

.BREAK Met fin à l'entrée actuelle.


.break est particulièrement utile pour les commandes multilignes.
.Clear alias sur .break
.exit Terminé le REPL Node.js.
Aidez- y à partir d'une liste de commandes disponibles.
.load Charge une session enregistrée dans le REPL actuel.
.save Enregistre les commandes de la session en cours dans un fichier.

Il existe deux façons de quitter le REPL. Vous pouvez utiliser la commande


.exit pour fermer le REPL Node.js. Alternativement, ils peuvent la
combinaison de touches (Ctrl) + (D) utiliser ce que le processus
beendet.Die est la deuxième variante de la combinaison de touches (Ctrl) +
(C) dont vous avez besoin zweimalbetätigen ce que le signal SIGINT au
Node.js processus envoie et termine cela. Ce type de signal est utilisé pour
contrôler les processus de l'extérieur, par exemple pour y mettre fin. Les
commandes .break et .clear sont utilisées lorsque la ligne de commande est
bloquée par une entrée incorrecte . Le listing 3.5 montre un cas d'utilisation
de ces commandes.

> console.log ( "Hello" + name ");


... .break
>

Dans l'exemple de Listing, le nom de la variable est incorrectement suivi


d'un guillemet double, ce qui signifie qu'après l'envoi de la commande, elle
n'est pas évaluée, mais qu'une ligne d'entrée supplémentaire est rendue
disponible, vous pouvez terminer l'entrée actuelle avec le .break et entrez à
nouveau votre commande. Le REPL Node.js vous offre la possibilité de
naviguer dans l'historique des dernières commandes. Avec cette
fonctionnalité, vous n'avez pas à saisir à nouveau votre commande, mais
vous pouvez utiliser les touches (½) et (¼) pour récupérer la ligne de
commande correspondante, la corriger et la renvoyer, au cas où vous
souhaiteriez effectuer des expériences approfondies dans le REPL ou les
résultats que vous souhaitez enregistrer, .save et .load sont deux
commandes que vous pouvez utiliser pour enregistrer les commandes
précédemment émises dans un fichier ou pour charger un fichier avec des
instructions JavaScript dans le REPL actuel.
> console.log ( "Hello world!");
Hello World!
Undefined
> .save myShell.js
Session saved to: myShell.js
> .load myShell.js
> console.log ( "Hello world!");
Hello World!
Undefined
>

Le Listing 3.6 montre comment vous pouvez utiliser .load et .save . Pour
illustrer le déploiement, exécutez la commande console.log au début. La
session en cours est ensuite enregistrée dans le fichier myShell.js. Ce fichier
contient alors la ligne de commande telle que vous l'avez entrée dans le
REPL, mais pas la sortie associée. Dans l'étape suivante, charger ce fichier
de retour dans la session avec l' .load instruction. Le fichier est lu ligne
par ligne, chaque commande est exécutée et les sorties associées sont
affichées. Vous pouvez également utiliser denBefehl .load à un point de
départ spécifique pour préparer un essai. Pour cela, vous pouvez formuler
une série de commandes dans un fichier, par exemple pour définir des
variables ou des fonctions dont vous avez besoin au cours d'une session
dans Node.js REPL. Comme d'habitude en JavaScript, Node.js REPL offre
également un contexte global, au début certaines variables sont déjà
enregistrées, ce qui vous facilite la tâche en tant que développeur. L' objet
de processus est à votre disposition avec lequel vous pouvez lire des méta-
informations sur le processus Node.js en cours, comme le numéro de
version. Vous pouvez également charger des fonctionnalités
supplémentaires à l'aide de require . La fonctionnalité exacte de ces
fonctionnalités sera discutée plus en détail au cours de ce livre. Dans la
portée globale de Node.js REPL, la variable _ est une autre particularité.
Cette variable contient toujours la valeur de la dernière commande. Par
exemple, si vous exécutez la commande console.log , _ contient la valeur
non définie . Si vous appelez une méthode ou une méthode avec une valeur
de retour telle que process.uptime () , _ contient la valeur respective. Avec
Node.js REPL comme outil, vous pouvez facilement tester le code source et
voir de manière interactive comment la plate-forme Node.js se comporte
dans certaines situations. Le REPL Node.js n'est pas adapté aux
applications étendues. Dans ce cas, une autre façon d'exécuter Node.js est
utilisée. Vous en apprendrez plus à ce sujet dans les sections suivantes.

La première application
Si vous créez des applications avec Node.js, le code source de cette
application est disponible dans un ou plusieurs fichiers. Celles-ci sont
transmises à Node.js lorsque l'application est lancée en tant qu'option sur la
ligne de commande et lue et exécutée par le processus. Le fichier d'entrée
contient uniquement du code source JavaScript valide. Le Listing3.7 vous
montre comment exécuter une application avec Node.js.
$ node server.js
Hello World!
$

Le fichier server.js contient uniquement la ligne console.log ("HalloWelt!")


. L'avantage de ce type d'exécution est que vous pouvez démarrer
l'application aussi souvent que vous le souhaitez et qu'il vous suffit
d'exécuter la ligne de commande du Listing 3.7. Vous pouvez également
facilement exécuter le code source sur un autre système ou l'application en
open source. Rendre le logiciel disponible à d'autres utilisateurs. L'édition
de HalloWelt! Cependant, il ne représente pas encore une application.
Avec Node.j, cependant, vous avez la possibilité de créer des applications
Web dynamiques et n'avez pas besoin d'un serveur Web séparé pour cela,
car avec le module http, Node.js vous offre la possibilité de créer votre
propre serveur Web. Dans les sections suivantes, vous passerez pas à pas
par l'exemple classique d'une application Node.js: un serveur Web très
léger. Cela devrait être en mesure d'accepter les demandes des navigateurs
et de répondre avec une réponse HTTTP correcte et la sortie de la chaîne
de caractères Hello, ichbineinNode.jsWebser -ver . Vous commencez avec
un cadre de base et vous le développez jusqu'à ce que l'application réponde
aux exigences. Le Listing 3.8 vous montre la structure de base de
l'application. Vous devez enregistrer ce code dans un fichier séparé appelé
webserver.js.
var http = require ('http');
http.createServer () .listen (8080, '127.0.0.1');
console.log ( 'Web server is running.');

En fait, un moteur JavaScript comme V8 n'a pas la capacité de simplement


fournir un serveur Web. Pour cette raison, il existe des modules pour
Node.js qui étendent les fonctionnalités de la plate-forme Node.js. Dans cet
exemple, vous avez besoin de la fonctionnalité d'un serveur Web. Node.js a
son propre module à cet effet et pour résoudre d'autres tâches liées à HTTP.
La fonctionnalité des différents modules de Node.js vous est
automatiquement disponible. En tant que développeur, vous n'avez qu'à
charger les modules dont vous avez besoin pour votre application avant de
les utiliser. Les modules et autres fichiers sont chargés dans Node.js à l'aide
de la fonction require . Dans ce cas, la valeur de retour se compose de l'
objet http , dont vous aurez besoin pour continuer à exécuter le serveur
Web. Vous enregistrez cet objet pour une utilisation ultérieure dans une
variable. En plus d'un serveur, vous pouvez utiliser le module http pour
créer un client pour interroger d'autres serveurs Web. Pour votre application
serveur Web, vous n'avez besoin que du serveur. Ceci est créé par la
méthode createServer de l' objet http . La valeur de retour de cette méthode
est le serveur HTTP, qui vous est disponible en tant qu'objet. L'objet serveur
nouvellement créé n'a actuellement aucune fonctionnalité et aucune
connexion vers l'extérieur n'est ouverte. L'étape suivante consiste à ouvrir
cette connexion vers les clients afin qu'ils puissent se connecter au serveur
et récupérer les données. Avec la méthode d' écoute , le serveur vous offre
la possibilité de spécifier un port et une adresse IP que vos utilisateurs
peuvent utiliser pour se connecter au serveur. Les arguments de la méthode
listen consistent en la spécification du numéro de port TCP à utiliser et
l'adresse IP à laquelle le serveur doit se lier. Le numéro de port est spécifié
sous la forme d'un entier, qui doit être compris entre 0 et 65535. Il y a deux
choses à considérer lors du choix du port pour votre serveur Web: Le port
utilisé ne doit pas déjà être occupé par une autre application, et il ne doit
pas être la plage des ports système entre 0 et 1023. Si vous utilisez un port
de 1024, vous pouvez exécuter votre script Node.js en tant qu'utilisateur
normal, pour les ports inférieurs pour lesquels vous avez besoin des droits
d'administrateur. Vous devez toujours effectuer des tests et des exemples en
tant qu'utilisateur normal, car en tant qu'administrateur, vous disposez de
beaucoup plus d'autorisations et pouvez sérieusement endommager le
système. En plus de spécifier le numéro de port, vous devez également
spécifier l'adresse IP à laquelle le serveur Web doit être lié. Toutes les
adresses système sont disponibles ici. Dans le cas de votre exemple, vous
devez utiliser l'adresse de l'interface de bouclage locale 127.0.0.1 comme
chaîne JavaScript. Il est disponible sur tous les systèmes et n'ouvre aucune
connexion vers l'extérieur, et aucune connexion réseau n'est requise. Tenter
d'utiliser Node.js sur votre système n'entraîne aucune faille de sécurité, et
vous pouvez toujours vous connecter au serveur Web avec le navigateur de
votre système pour tester la fonctionnalité. L'appel de la méthode d' écoute
du serveur HTTP s'ouvre à côté de la définition de l'adresse et du port et
garantit que le serveur attend les demandes entrantes. La dernière ligne du
script est à titre informatif uniquement et devrait vous montrer sur la ligne
de commande que le serveur Web a été démarré correctement, car Node.js
ne produit rien sans cette ligne. Enregistrez le script, dans le cas de cet
exemple sous le nom webserver.js, vous pouvez exécuter le serveur Web sur
votre système et tester déjà le résultat. La liste vous montre à quoi
ressemble le résultat du test.

$ node webserver.js
Web server is running.

Le noeud de commande avec le fichier qui contient le code source du


serveur Web en option entraîne le démarrage d'un processus Node.js qui se
connecte à la combinaison d'adresse et de port spécifiée et attend les
connexions entrantes qu'il sert. La ligne de commande est bloquée par
l'exécution du script et vous ne pouvez pas faire d'autres entrées ici. En
raison de l'architecture de Node.js, qui est basée sur le principe
événementiel, le script du serveur Web crée très peu de charge, car Node.js
ne bloque pas lorsqu'il n'a rien à faire. Si vous souhaitez annuler le script,
vous pouvez le faire avec la combinaison de touches (Ctrl) + (C) et vous
obtiendrez à nouveau une invite de commande. Vous pouvez maintenant
tester le serveur Web avec votre navigateur en utilisant la ligne d'adresse
http dans votre navigateur Entrez: // localhost: 8080. La figure 3.1 montre le
résultat de ce test.

Le problème maintenant est que votre serveur Web est lié à la bonne
adresse et au bon port, mais n'a aucune logique pour traiter les demandes
entrantes. Cela signifie principalement que vous n'obtenez aucune sortie
pendant le test et, si vous laissez la fenêtre de votre navigateur ouverte
assez longtemps, vous obtenez une erreur de temporisation. Pour cette
raison, vous insérerez le code source à l'étape suivante, ce qui garantit que
les demandes entrantes sont traitées de manière significative. Le serveur
Web que vous créez ici dans Node.js diffère considérablement dans
certaines caractéristiques des autres implémentations dans les langages de
script dynamiques tels que PHP. Chaque demande est traitée séparément et
le code source nécessaire est lu. Avec Node.js, le code de l'application est lu
une fois puis reste dans la mémoire de travail. L'application s'exécute en
continu. C'est là qu'entre en jeu un aspect important de Node.js: le
traitement asynchrone des tâches. Le serveur Web répond aux événements,
dans ce cas les requêtes des clients. Pour cela, une fonction est définie, un
callback qui est exécuté dès qu'une requête arrive. Bien que ce code soit
défini dans un bloc comme dans d'autres langages, le code source
responsable du traitement des requêtes n'est exécuté que lorsqu'une telle
requête arrive. Dans la liste, vous pouvez voir le code source étendu de la
liste. Cette version du serveur Web peut alors traiter correctement les
demandes.
var http = require ('http');
http.createServer (function (request, response) {
response.writeHead (200, {'content-type': 'text / plain; charset = utf-8'});
response.write ('Hello'); response.end ('World \ n');
})
.lists (8080, '127.0.0.1');
console.log ( 'Web server is running.');

La seule adaptation de l'exemple du Listing 3.8 a lieu en appelant la


méthode cre-ateServer . Ici, Node.js reçoit le rappel, qui spécifie ce qui doit
se passer lorsque la demande d'un client atteint le serveur. Dans cet exemple
simple, saisissez Siezuerst uniquement la chaîne Hello World à partir du
navigateur du client. Pour obtenir cette sortie, examinez d'abord la structure
de la fonction de rappel. Cela a deux paramètres, une requête et un objet de
réponse. Comme vous pouvez déjà le voir à partir du nom, ils représentent
chacun la demande du client et la réponse du serveur. Dans cet exemple,
vous ignorez d'abord les demandes du client et vous vous concentrez sur la
réponse du serveur. Dans la première étape, les informations d'en-tête
HTTP sont préparées, qui seront ensuite renvoyées au client. Cela se fait à
l'aide de la méthode writeHead . Le premier argument de cette fonction est
un nombre qui représente le code d'état HTTP. Le second est un objet qui
contient l'en-tête HTTP réel. Les valeurs clés de l'objet, comme dans
l'exemple la valeur content-type, doivent être écrites en minuscules
conformément à la convention. Dans l'exemple, vous pouvez voir la
spécification du type de contenu, qui dans ce cas est défini sur text / plain
pour indiquer au client que la réponse du serveur contient uniquement du
texte. Comme certains navigateurs tels que ceux qui passent des messages
d'erreur Firefox lorsque le codage des caractères indiqué n'est pas correct, le
type de contenu des informations est charset = utf-8 développé pour
signaler à demBrowser que le corps HTTP en UTF-8 est encodé. -Réponse
visible, le corps HTTP, en utilisant la méthode d' écriture . Lorsque cette
méthode est appelée, des fragments de la réponse, appelés fragments, sont
envoyés. Vous pouvez appeler cette méthode plusieurs fois de suite, ce qui
conduit à la jonction des pièces individuelles. Cependant, vous devez vous
assurer que l'en-tête HTTP correct est toujours envoyé avec writeHead
avant d'appeler write . Si vous ne pas appeler la tête en écriture méthode,
le serveur HTTP envoie implicitement Node.js un en- tête HTTP avec le
code d'état 200 et un type de contenu text / plain , de sorte que même une
réponse sans la spécification explicite des informations d' en- tête est valide.
L'appel de write garantit que des parties de la réponse sont envoyées au
client. Dans ce cas, cependant, le client ne sait pas quand le serveur a fini
d'envoyer la réponse. En tant que développeur, vous devez le faire en
utilisant la méthode end de l'objet de réponse . Vous pouvez éventuellement
entrer une chaîne de caractères comme argument. Dans ce cas, end se
comporte comme write , envoie le bloc spécifié au client, puis termine la
réponse. La méthode d' écriture a deux autres caractéristiques qui méritent
d'être mentionnées. D'une part, vous pouvez non seulement transmettre des
chaînes de caractères comme arguments, mais également des objets
tampons. Un objet tampon se compose de données binaires qui facilitent
grandement la diffusion des données. Cette classe d'objets est
principalement utilisée lors de l'utilisation de flux. La deuxième
caractéristique consiste en la spécification du codage de la chaîne de
caractères. Vous pouvez effectuer cette spécification en utilisant le
deuxième paramètre de la méthode d' écriture . Ceci est facultatif et
Node.js utilise utf-8 comme encodage par défaut s'il est omis. Les autres
valeurs possibles ici sont utf16le , ascii ou hex . Le codage UTF-8 est
autorisé dans cet exemple, il n'est donc pas nécessaire de spécifier un
codage de caractères pour cette raison, donc pour que l'exemple fonctionne
correctement, vous devez vous assurer que vous redémarrez le serveur Web
pour le code source personnalisé à partir de Node.js est lu correctement.
Pour cela, la meilleure chose à faire est de terminer l'instance du premier
exemple toujours en cours d'exécution à l'aide de la combinaison de touches
(Ctrl) + (C) et de redémarrer le serveur Web en appelant à nouveau la
commande node avec le nom du fichier de votre code source. Le résultat de
l'exemple est illustré à la figure. Dans cet exemple, vous avez vu comment
il est possible avec seulement quelques lignes de code JavaScript de créer
un serveur Web fonctionnel qui répond à la demande d'un client avec une
réponse HTTP correcte. En réalité, cependant, vous devez rarement gérer
les réponses des serveurs Web en texte brut. Vous développez maintenant
l'exemple en ce que le serveur répond par une réponse en HTML, comme le
ferait un serveur Web normal. La liste vous montre les ajustements à faire
pour cela.

var http = require ('http');


http.createServer (function (request, response) {
response.writeHead (200, {'content-type': 'text / html; charset = utf-8'});
var body = ' <! DOCTYPE html>' +
'<html>' +
'<head>' +
'<meta charset = "utf-8">' +
'<title> Node.js Demo </title>' +
'</head>' +
'<body>' +
'<h1 style = " color: green "> Hello World </h1>' + '</body>' + '</html>';
response.end (body);
} ) .lists (8080, '127.0.0.1');
console.log ( 'Web server is running.');

Les seuls changements que vous devez apporter au code source de


l'exemple sont l'ajustement du type de contenu, qui n'est plus text / plain ,
mais text / html , et l'appel à écrire est omis, et le corps HTTP devient com
-plett envoyé en utilisant la méthode end . La valeur transmise à la méthode
end contient une chaîne HTML qui reflète la structure du site Web à
afficher. Comme cette chaîne de caractères est assez étendue, il est
préférable de la déplacer vers le corps de la variable séparé et de la
transmettre lors de l'appel de la méthode end . Une fois que vous avez
effectué ces modifications, tout ce que vous avez à faire est de redémarrer le
processus Node.js dans lequel votre serveur Web est en cours d'exécution et
les modifications prendront effet. Si vous rechargez maintenant la page
dans votre navigateur, vous devriez voir un résultat similaire à celui de
l'illustration.
Jusqu'à présent, vous avez beaucoup traité de l'objet de réponse, c'est-à-dire
de la réponse au client. Il est maintenant temps d'examiner de plus près
l'objet de la requête, c'est-à-dire la requête réelle. Cet objet offre une
possibilité avec laquelle le client peut communiquer avec le serveur. Dans
les applications Web classiques, les informations sont envoyées depuis le
navigateur à l'aide des méthodes HTTP GET et POST . Cela se fait
généralement à l'aide de formulaires ou de paramètres encodés dans l'URL.
Vous allez maintenant développer à nouveau l'exemple et afficher une
chaîne de caractères spécifiée par l'utilisateur dans l'URL de la page livrée.
Pour que l'exemple ne devienne pas trop confus, utilisez le code source du
Listing 3.8 comme base et fournissez la réponse en texte brut au lieu de
HTML. Le code source modifié peut être trouvé dans l'extrait 3.12 et
ensuite les explications correspondantes pour les changements.
var http = require ('http');
var url = require ('url');
http.createServer (function (request, response) {response.writeHead (200,
{'content-type': 'text / plain;
charset = utf-8 '});
var urlString = url.parse (request.url, true);
var body = 'Hello' + urlString.query.name;
response.end (body);
} ) .lists (8080, '127.0.0.1');
console.log ( 'Web server is running.');

L'adaptation la plus importante du code source est que vous lisez l'URL
demandée par le client dans le code source et que vous en écrivez des
parties dans la réponse. L'objet de requête contient les informations que
l'URL l'utilisateur a spécifiées dans son navigateur de la propriété url . En
supposant que l'utilisateur a entré l'URL http: // localhost: 8080 /? Nom =
visiteur dans la ligne d'adresse de son navigateur, la propriété url de l'objet
de requête contient la valeur /? Nom = visiteur . Votre objectif est
maintenant de sortir la chaîne Bonjour visiteur . Pour ce faire, la chaîne,
dans ce cas visiteurs , doit être extraite de la propriété url . Vous pouvez le
faire d'une part en fractionnant la chaîne avec la fonction de fractionnement
au signe égal et en utilisant le deuxième élément du tableau résultant.
Cependant, cette variante ne fonctionne que tant que l'utilisateur ne passe
qu'un seul paramètre dans l'URL ou est au sommet de plusieurs paramètres.
Une meilleure façon de traiter avec des URL est d'utiliser le module Node.js
URL . Entre autres choses, cela vous donne la possibilité d'analyser les
URL et de les décomposer en leurs composants individuels. Tout ce que
vous avez à faire est d'inclure le module url et d' appeler la méthode d'
analyse sur l'objet retourné avec la propriété url de l'objet request comme
argument. Cela conduit à la ligne de code suivante: varurl = require ('url')
.parse (request.url, true) . La variable url contient alors un objet qui
contient les différentes parties de l'URL demandée. Entre autres choses, il
existe une propriété de requête qui contient les paramètres GET
individuels. Dans ce cas, le nombre et l'ordre des paramètres dans l'URL
n'ont plus d'importance, puisque vous pouvez accéder à la valeur via le nom
du paramètre, nom dans ce cas. Avec url.query .name vous pouvez alors
accéder à la chaîne de caractères que l'utilisateur a spécifiée dans la ligne
d'adresse de son navigateur. Vous disposez désormais de tous les
composants nécessaires pour atteindre votre objectif. Une fois que vous
avez apporté les modifications au code source et redémarré le serveur Web,
vous pouvez tester le résultat en appelant à nouveau la page. La figure 3.4
montre le résultat que vous obtenez lorsque vous accédez à http: //
localhost: 8080 /? Nom = utilisateur.

Sommaire
Dans ce chapitre, vous avez appris à créer des applications Web simples
avec Node.js avec seulement quelques lignes de code source et même à
réagir aux entrées de l'utilisateur. Dans les chapitres suivants, vous aurez un
aperçu plus approfondi de la structure de Node.js, du concept de module et
du gestionnaire de paquets Node.js.
.

CHAPITRE 3
Adaptation et expansion

Rien au monde n'est distribué aussi


équitablement que l'esprit. Parce que tout le
monde est convaincu qu'il en a assez.
- René Descartes

Après avoir expérimenté une petite section des possibilités de Node.js en


action dans le chapitre précédent, ce chapitre entre plus en détail et vous
montre comment vous pouvez utiliser la plateforme Node.js pour créer vos
propres applications. Vous en apprendrez également plus sur l'arrière-plan
du système de modules Node.js et comment la fonctionnalité de Node.js est
étendue par des packages externes.

Modules Node.js
Dans le chapitre précédent, vous avez utilisé deux modules différents, le
module http et le module URL . Ces modules fournissent des
fonctionnalités ou des interfaces supplémentaires et fréquemment utilisées
aux bibliothèques principales de Node.js. Les sections suivantes traitent en
détail du système de modules de Node.js et des possibilités qui en
découlent.

Approche modulaire
Le cœur de la plate-forme Node.js se compose d'une collection de
différentes bibliothèques, qui sont gérées séparément et finalement
rassemblées dans Node.js. Node.js suit également une approche similaire
dans son système de modules. La plupart des modules individuels sont
développés indépendamment les uns des autres, mais sont disponibles sur la
plateforme et peuvent être combinés selon les besoins. Les modules font
partie intégrante de la plateforme Node.js et sont donc compilés directement
dans le fichier binaire. Ils sont donc à votre disposition à tout moment. Vous
n'avez pas non plus la possibilité d'exclure certains modules pendant le
processus de compilation. Les modules Node.js sont développés en
JavaScript lui-même. Cela signifie que bien que le cœur de la plate-forme
soit en C, les composants restants sont développés dans le langage de la
plate-forme, c'est-à-dire inJavaScript. Dans l'architecture de Node.js,
comme le montre la figure, vous vous déplacez dans la partie supérieure de
ce chapitre, c'est à dire dans la bibliothèque standard de Node.js. Cela
signifie que les modules Node.js sont disponibles dans le code source et que
vous pouvez également les adapter à vos besoins si nécessaire, et tout ce
dont vous avez besoin est une solide connaissance de JavaScript. Les
fichiers des modules se trouvent dans le répertoire lib du package de code
source de Node.js.

Comme vous l'avez vu au chapitre 3, les modules Node.js sont très faciles à
intégrer en utilisant la fonction require . La fonctionnalité est rendue
disponible via la valeur de retour. Dans la plupart des cas, il s'agit d'un objet
dont les méthodes peuvent être utilisées directement. Le listing 4.1 vous
montre comment utiliser le module du système de fichiers pour lire le
fichier /tmp/nodejs.txt.
var fs = require ('fs');
fs.readFile ("/tmp/nodejs.txt", function (err, content)
{
if (err) {throw err;
}
console.log ( content.toString ());
});
Dans l'exemple du Listing 4.1, chargez le module du système de fichiers
dans la première ligne en utilisant la commande require ('fs') . La valeur de
retour de cette fonction est un objet qui vous fournit une interface pour
diverses opérations du système de fichiers. Entre autres, il y a la méthode
readFile , que vous utilisez dans ce cas pour lire un fichier et afficher son
contenu sur la ligne de commande, mais comment savoir quels modules
sont disponibles, à quoi ils servent et sous quel nom vous pouvez charger
les modules? Les modules de Node.js sont très bien documentés dans la
documentation API de la plateforme Node.js. Vous pouvez les joindre à
l'adresse http://nodejs.org/api/. Une alternative à cela est disponible si vous
avez téléchargé le code source à partir de Node.js. Dans le répertoire doc, il
y a un sous-répertoire api dans lequel toute la documentation API de
Node.js est disponible hors ligne. Vous pouvez consulter cette
documentation via le fichier index.html dans ce répertoire. Le contenu
correspond à celui du site Web Node.js, mais est spécifique à la version
dans le package de code source. Cela signifie que vous devriez vous référer
à cette documentation si vous développez pour une ancienne version de
Node.js ou si vous avez besoin d'informations sur l'API d'un ancien
Node.js.

Indice de stabilité
Une question fréquemment posée est de savoir si Node.js peut être utilisé
dans les entreprises. Cette question ne peut recevoir une réponse claire et
sans ambiguïté. A travers le développement de la plateforme et les
tentatives de rendre Node.js plus stable et performant, la tendance va
néanmoins dans le sens de répondre à la question par un oui. Le fait
d'utiliser ou non une technologie dépend de divers facteurs, notamment la
nature du problème, l'environnement dans lequel la solution doit être
utilisée et notamment les technologies Entwicklungsstandder utilisées. Une
situation similaire à celle de la question de l'utilisabilité de l'ensemble de la
plateforme Node.js se pose également avec les modules de Node.js. Étant
donné que les modules ont été développés indépendamment, faites-les
chacun à des stades de développement différents, ce qui se reflète dans la
stabilité des modules. Les modules qui ont été développés pendant plusieurs
années et qui ont déjà fait leurs preuves à plusieurs reprises dans la pratique
sont, bien entendu, plus stables et plus fiables que les modules qui ne sont
entrés sur la plate-forme que dans l'une des dernières versions. Les
développeurs de Node.js sont conscients de ce problème et ont développé
ce que l'on appelle l'indice de stabilité. C'est un nombre que vous pouvez
utiliser pour déterminer si un module est si mature que vous pouvez
l'utiliser dans votre application sans problème majeur, ou si vous devriez
plutôt attendre pour l'utiliser et passer à d'autres alternatives. Le tableau 4.1
vous fournit une liste des numéros d'indice de stabilité existants.

L'indice de stabilité «obsolète» signifie que la fonction marquée avec cet


indice de stabilité ne doit plus être utilisée. La méthode de pompage du
module util est un exemple de fonctionnalité obsolète . Dans la
documentation de Node.js, une alternative est donnée pour chaque
fonctionnalité marquée comme "obsolète", que vous devriez utiliser à la
place. Les modules expérimentaux signifient pour vous en tant que
développeur que vous pouvez utiliser la fonctionnalité, mais vous devez
tester la fonctionnalité de manière approfondie. Dans le processus de
développement ultérieur de Node.js, il ne peut pas être garanti qu'il n'y aura
pas de modifications aux interfaces. Cela signifie que lorsque Node.js est
mis à jour, vous devez faire attention aux endroits où vous utilisez ces
fonctionnalités. Les fonctionnalités expérimentales sont, par exemple, le
domaine ou le module Cluster . Les modules Node.js, répertoriés comme
«instables», peuvent être utilisés dans votre application sans craindre de ne
pas être disponibles dans une version ultérieure. Cependant, vous devez
faire preuve de prudence lorsque vous utilisez ces modules pour des mises à
jour et testez les points correspondants de manière approfondie. Des
exemples de modules instables incluent Stream ou Crypto . La plupart des
modules principaux de Node.js sont marqués de l'indice de stabilité 3, c'est-
à-dire «stable». Cet index signifie que vous pouvez utiliser ces modules de
manière productive dans les applications. Les interfaces restent stables
même après les mises à jour. Vous pouvez être assuré que le poste dans
votre candidature continuera à fonctionner même après une mise à jour. Les
modules stables sont, par exemple, FileSystem , Net ou HTTP . L' indice
de stabilité «API gelé» indique qu'il est peu probable que l'interface
utilisateur du module ou la signature des différentes méthodes du module
change dans le futur. Des exemples de modules marqués de cette manière
sont le système d'exploitation ou les événements . Le dernier indice de
stabilité, "verrouillé", signifie que les modules ne sont plus modifiés. Les
minuteries ou utilitaires en sont des exemples . L' indice de stabilité vous
montre en tant que développeur si vous devez tenir compte des
changements dans les modules respectifs. Dans ce cas, les changements
signifient principalement que la signature des méthodes peut changer, en
particulier le nombre et la dénomination des paramètres. Cependant, la
valeur de retour peut également être ajustée. Si vous utilisez un module
soumis à de telles modifications, des problèmes dans votre application
surviendront inévitablement, que vous devrez corriger par des ajustements
afin de continuer à utiliser l'application sans erreur.

Modules disponibles
Node.js est livré avec un certain nombre de modules de base. Dans cette
section, vous en apprendrez plus sur les modules individuels et leurs
domaines d'application. Le tableau vous donne un premier aperçu des
modules existants et où ils sont utilisés.

Assert un cadre de test intégré


module tampon pour la gestion des données brutes binaires
child_process Gestion des processus enfants
gestion des processus de cluster pour les processeurs multicœurs
fonctionnalité consoleconsole en JavaScript
crypto- connexions sécurisées et cryptage
moyen de débogage pour l' analyse d' exécution des applications
communication de dgram sur UDP
résolution de noms DNS sous Node.js
domaine Collection d'exceptions et d'erreurs d'un groupe d'opérations
événements Module de base pour les objets générant des événements
opérations du système de fichiers fs
Client et serveur HTTP http
Client et serveur HTTPS https
module chargeur de module de Node.js
composants client et serveur net pour les flux réseau
os Lire les informations sur le système d'exploitation
chemin Traitement des informations de chemin
encodage punycode et décodage des chaînes punycode
chaîne de requête Création et analyse des chaînes de requête URL
readline Lire des informations sur un flux comme l'entrée standard
repl shell interactif Node.js
flux de données inscriptibles et lisibles
string_decoder Convertit les objets tampons en chaînes
minuteries fonctions dépendant du temps
communication cryptée tls via des flux de données
tty couche intermédiaire pour adressage standard I - Sortie
fonctionnalité d' URL pour traiter les URL
util fonctions auxiliaires
environnement d'exécution vm pour le code JavaScript
possibilité zlib de compresser et décompresser les données

Vous en apprendrez plus sur les modules individuels ci-dessous. De petits


exemples de code devraient vous aider à comprendre l'application
spécifique.
Test d'assertion
Il existe un certain nombre de frameworks pour JavaScript que vous pouvez
utiliser pour créer des tests unitaires pour votre application. Presque chaque
framework JavaScript est livré avec sa propre interprétation d'un framework
de test. Cependant, cette diversité n'existe pas seulement du côté client dans
le navigateur Web, il existe également plusieurs approches pour Node.js
avec lesquelles des sous-tests peuvent être créés. Cependant, la variante la
plus simple consiste à utiliser le module assert de Node.js, avec lequel vous
pouvez créer des tests unitaires à part entière, comme vous pouvez le voir
dans Listing en utilisant un exemple spécifique.
var assert = require ('assert');
var greaterThan = function ( a, b) {
return a> b;
}
assert.ok (greaterThan (2,3), '2 is not greater than 3');

Dans l'exemple, vous définissez une fonction qui renvoie true si le premier
argument est supérieur au second, sinon le résultat est false . Cette valeur
de retour peut être vérifiée avec la méthode ok de l' objet assert en passant
l'appel de fonction ou la valeur de retour comme premier argument. Dans le
cas de l'exemple, vous vous attendez à ce que le test échoue car 2 n'est pas
supérieur à 3. Si un test échoue, une exception AssertionError est levée et
le message que vous avez transmis à la méthode ok en tant que deuxième
argument s'affiche.

Tampon
Sur Internet, les flux d'octets sont un moyen établi de transfert de données,
ce qui est déjà reflété dans l' application / flux d'octets de type MIME , qui
est utilisé lorsque des fichiers dont le format est inconnu sont transmis.
Dans Node.js, les flux d'octets sont principalement utilisés dans le domaine
de la communication réseau et pour les opérations du système de fichiers.
La classe tampon est dans Node.js alsglobale classe disponible et ne dispose
pas sur nécessitent intégré werden.In Listing 4.3 voir la représentation d'un
objet tampon.
<Buffer 48 61 6c 6c 6f 20 57 65 6c 74 0a>

Vous pouvez générer ce type d'affichage, par exemple, en affichant le


résultat d'une opération de système de fichiers sur la console, comme vous
pouvez le voir dans la liste.

var fs = require ('fs');


fs.readFile ("/tmp/nodejs.txt", function (err, content) {
if (Buffer.isBuffer (content)) {
console.log (content);
}});

Dans cet exemple, vous pouvez voir une autre fonctionnalité de la classe
Buf-fer avec la méthode isBuffer . Il peut être utilisé pour vérifier si un
objet spécifique est réellement un objet tampon.

Processus enfant
Une caractéristique centrale de Node.js est l'approche monothread, qui est
chargée de s'assurer que tout le code de l'application est exécuté dans un
thread Node.js. Cependant, dans Node.js, vous avez la possibilité de
démarrer des processus enfants indépendants. D'une part, il peut s'agir de
commandes normales, dont la sortie sera disponible plus tard, et d'autre
part, de processus Node.js séparés qui peuvent être utilisés pour sous-traiter
des opérations intensives en calcul. Côté client, il existe une option en
HTML5 avec la fonction de travail Web pour externaliser les opérations
gourmandes en calculs. Au chapitre 7, »Programmation asynchrone«, vous
apprendrez en détail quand et comment vous pouvez utiliser le module
ChildProcess dans votre application.
Grappe
Le module de cluster est un module Node.js assez récent. Il a été intégré
dans la version 0.6 de Node.js et a subi de nombreux changements et
optimisations depuis. Cette évolution reflète également l'indice de stabilité
«expérimental» de ce module. Le module de cluster prend en compte le
fait que les ordinateurs modernes ont non seulement un cœur de processeur,
mais plusieurs. Cependant, vous ne pouvez pas facilement utiliser cette
infrastructure avec Node.js, car le code de l'application est connu pour
s'exécuter dans un seul thread. Le module de cluster garantit qu'une série
de processus de travail est démarrée, sur laquelle la charge de travail de
l'application est répartie. Ce module s'appuie directement sur le module
ChildProcess pour démarrer les processus enfants et leur permettre de
communiquer entre eux . L'équilibrage de charge des processus est effectué
par le système d'exploitation lui-même, de sorte que vous n'ayez pas à vous
en soucier. Cependant, l'utilisation de ce module influence l'architecture de
votre application, car vous devez décider à quel moment quelles parties de
l'application doivent être externalisées du processus principal. Vous devez
également gérer vous-même les processus enfants, ce n'est pas fait par
Node.js. Pour un aperçu détaillé de ce module, vous devriez jeter un œil au
chapitre 7, «Programmation asynchrone», où vous pouvez en savoir plus
sur l'utilisation et les fonctionnalités du module de cluster à l' aide d'un
exemple.

Console
Vous avez utilisé certaines des fonctionnalités de ce module plus
fréquemment tout au long de ce livre. Le module Console fournit l' objet
console globale , que vous pouvez utiliser pour générer des informations,
par exemple. Pour la non-reproduction, la sortie standard est au-dessus de
console.log ou console.info ainsi que l'erreur standard sur Console.Error
ou console.warn pour la disponibilité vérifiée-gung. L'API des commandes
de la console correspond à celle qui est également utilisée dans les
navigateurs Web standard. Pendant le développement, ce qui est très utile
pour mesurer les temps de débit, les fonctions console.time et
console.timeEnd sont disponibles , qui vous fournissent une sorte de
chronomètre, avec lequel vous pouvez mesurer une certaine période de
temps au sein d'une application. console.time console.time ('example');
var result = 0;
for ( vari = 1; i <= 1000; i ++) {
result + = i;
}
console.log ( 'Sum:' + result);
console.timeEnd ('example');

La liste mesure le temps nécessaire pour additionner les nombres de 1 à


1000 et afficher le résultat sur la sortie standard. La période de temps
requise est ensuite affichée avec l' exemple d' étiquette sur l'édition
standard.

Crypto
Dans les applications Web, en tant que développeur, vous devez toujours
gérer des données confidentielles dont vous êtes responsable de la
transmission et du stockage en toute sécurité. Un traitement sécurisé des
données est également possible sous Node.js, qui ne doit pas être rendu
accessible à toutes les personnes ayant accès à l'application ou au serveur.
Basé sur OpenSSL, le module Crypto fournit des interfaces avec lesquelles
vous pouvez crypter des données et créer des signatures ou des hachages.
L'exemple du Listing 4.6 montre comment vous pouvez facilement créer le
hachage MD5 d'une chaîne de caractères.
var crypto = require ('crypto');
var md5 = crypto.createHash ('md5');
md5.update ('Hello world');
console.log (md5.digest ('hex'));
Dans la liste, vous créez un nouvel objet de hachage à l'aide du module
Crypto et de la méthode createHash . Vous passez l'algorithme souhaité
comme argument à cette méthode. Les valeurs possibles ici incluent sha1 et
md5 . Vous utilisez ce dernier dans cet exemple pour former un hachage
sur la chaîne de caractères HalloWelt . À l'étape suivante, les données sont
écrites dans l'objet de hachage à l'aide de la méthode de mise à jour . La
méthode digest est en dernier lieu responsable du calcul de la valeur de
hachage et des retours. Si vous appelez cette méthode sans arguments, le
hachage est codé en binaire. Cependant, il est possible d'influencer le type
de codage de sortie avec des arguments. Dans l'exemple, vous avez utilisé
la valeur hex pour générer un hachage hexadécimal. La sortie correspond à
la valeur que vous obtenez par défaut à partir de l' outil de ligne de
commande md5 .

Débogueur
Node.js a des fonctionnalités étendues pour le débogage des applications.
La particularité de ce débogueur est que vous pouvez utiliser le débogueur à
la fois localement sur l'ordinateur sur lequel vous exécutez votre application
Node.js et via une connexion TCP depuis un ordinateur distant. Cette
fonctionnalité permet de faire fonctionner le débogueur depuis la ligne de
commande avec une série de commandes. Une autre variante de la façon
dont vous pouvez utiliser le débogueur est de le contrôler via votre
environnement de développement . Pour le débogueur Node.js, il existe des
plugins pour Eclipse, Webstorm et d'autres environnements de
développement.
Datagramme
En plus de la communication via des sockets TCP ou des fichiers de
sockets, qui est effectuée par le module Net , la communication peut
également être effectuée à l'aide du protocole UDP. La différence est que
UDP est un protocole très léger, non orienté connexion. Vous ne pouvez pas
utiliser ce protocole pour vous assurer qu'il n'y a pas de perte de données
sur la connexion entre le serveur et le client. Une connexion UDP est
principalement utilisée pour les données en temps réel non critiques, dans
lesquelles la perte de certains paquets de données n'a aucun effet négatif sur
l'application.

DNS
Lors du développement d'applications Web, il est souvent nécessaire de
communiquer avec d'autres systèmes. La communication au niveau du
protocole a lieu avec un adressage unique via une combinaison d'adresse IP
et

Numéro de port à la place. Dans la plupart des cas, cependant, il est plus
judicieux dans une application d'utiliser des noms d'hôte plutôt que des
adresses, car les adresses attribuées dynamiquement peuvent changer
fréquemment, mais le nom d'hôte reste le même dans la plupart des cas. Le
système de noms de domaine, ou DNS en abrégé, se charge de la résolution
des noms d'hôte en adresses IP. Node.js dispose d'un module spécialisé dans
la résolution de noms. Ce module gère non seulement la résolution des
noms d'hôte, mais peut également lire différents types d'enregistrements de
données à partir d'un domaine, tels que les enregistrements MX pour
l'adresse du serveur de messagerie. Dans la liste, vous pouvez voir comment
vous pouvez utiliser Node.js pour résoudre l'adresse d'un domaine.
var dns = require ('dns');
dns.resolve ('www.google.de', function (err, addrs) {
addrs.forEach (function (record) {
console.log ('www.google.de is' + record);});
});

Toutes les fonctionnalités du module DNS fonctionnent de manière


asynchrone. Cela signifie que vous attribuez à chaque méthode une fonction
de rappel comme argument, qui est appelée dès que le résultat de la requête
du serveur DNS est disponible. Toutes les méthodes, à l'exception de
dns.lookup , sont basées sur la bibliothèque C-Ares. Surtout avec un plus
grand nombre de résolutions DNS, c'est considérablement plus rapide que le
getaddrinfo interne . Dans l'exemple du Listing 4.7, le nom www.google.de
doit être résolu en utilisant la méthode de résolution . S'il y a une réponse
du serveur DNS, la fonction de rappel est appelée avec deux arguments. Le
premier argument, comme d'habitude avec Node.j, est un objet qui est
utilisé si une erreur s'est produite pendant la résolution. Le deuxième
argument est un tableau d'adresses IP que le serveur DNS a trouvé pour le
nom demandé. La méthode de résolution autorise un deuxième argument
facultatif avant la fonction de rappel, ce qui vous permet de spécifier les
types d'enregistrements que vous souhaitez obtenir. La valeur par défaut ici
est A pour les adresses IPV4.

domaine
Le module Domaine est utilisé pour résumer les erreurs qui se produisent
lors de l'utilisation d' EventEmitters . Cette fonctionnalité n'est que depuis
la version 0.8 de Node.jsBestandteil la plate-forme et est actuellement
encore une fonctionnalité expérimentale d'aide geführt.Die fonctionnalité de
ce module sur le point d'attraper toutes les erreurs dans une section
spécifique dans une application et d'empêcher ainsi l'application se termine.
Le listing 4.8 illustre cela.

ar fs = require ('fs'),
domain = require ('domain'),
emitter = new (require ('events' ) .EventEmitter ) ();
var fsDomain = domain.create ();
fsDomain.on ('error', function (err) {
console.log ( 'An error occured in Domain');
console.log (err);
});
fsDomain.run ( function () {
fs.readFile ('/ tmp / doesNotExist', function (err, data) {
if (err) {throw err;
}
console.log (data);
});
});
fsDomain.run ( function ( ) {
emitter.emit ('error', {message: 'EventEmitter error Event emitted'})
;});

Lors de l'utilisation du module de domaine , un domaine est d'abord créé


sous la forme d'un objet. Cet objet forme plus tard le contexte pour
l'exécution du code source, à partir duquel les erreurs potentielles doivent
être détectées. Ce domaine est créé à l'aide de la méthode create du module
domain . La valeur de retour, l' objet de domaine , représente le contexte
d'exécution. Dans le domaine objet que vous pouvez maintenant utiliser la
sur méthode pour enregistrer les fonctions de rappel qui sont exécutées dès
qu'une erreur se produit. Ces erreurs peuvent être à la fois des événements
d' erreur d'un EventEmitter et des exceptions. Une condition préalable au
fonctionnement du domaine est que ni les événements d' erreur ni les
exceptions ne soient interceptés et traités, ce qui entraînerait normalement
l'arrêt de l'application. Enfin, vous devez encapsuler le bloc de code à
exécuter dans une fonction et le passer en argument à la méthode run du
domaine que vous venez de créer. Ce bloc de code est évalué et exécuté en
appelant la méthode run .

Événements
Node.js est basé sur une architecture qui prend en charge le développement
événementiel. L'utilisation de la boucle d'événements seule garantit que les
opérations d'E / S sont externalisées à partir du thread d'application central.
Le module Events fournit une classe EventEmitter , qui doit servir de base
à tous les objets pouvant déclencher des événements. Le serveur du module
http , par exemple, hérite de la classe EventEmitter afin d'assurer la bonne
gestion des événements. Dans le cas d'une connexion entrante, la demande
d' événement est déclenchée, à laquelle est liée la fonction RequestListener
, qui a été définie lors de la création du serveur. Un exemple très simple qui
illustre l' utilisation de la classe EventEmitter est présenté dans la liste.
var myEvent = new (require ('events' ) .EventEmitter ) ();
myEvent.on ('event', function (data) {
console.log (data);
});
myEvent.emit ('event', 'Hello World');

Dans l'exemple, vous pouvez voir qu'un nouvel objet de la classe


EventEmitter est créé et qu'un écouteur pour l'événement avec le nom
event lui est lié. L'événement est déclenché avec la méthode emit , ce qui
signifie que la fonction de rappel précédemment définie est exécutée et que
les données d'événement, dans ce cas la chaîne HelloWorld , sont sorties.
Vous en apprendrez plus sur EventEmitter et ses fonctionnalités plus loin
dans ce chapitre.

Système de fichiers
Le module FileSystem est un module très important de la plateforme
Node.js. Il contrôle tous les accès, en lecture et en écriture, au système de
fichiers. Vous avez déjà vu l'utilisation de ce module au début de ce chapitre
dans l'extrait 4.1. Contrairement au module DNS , dans lequel toutes les
méthodes ne fonctionnent que de manière asynchrone, c'est-à-dire avec
rappel, le module FileSystem a une contrepartie synchrone pour chaque
opération asynchrone. Dans le cas d'une opération synchrone, la méthode
est juste un appel avec une certaine valeur de retour. Il n'est pas nécessaire
de définir ici une fonction de rappel, le contexte de la fonction courante
n'est pas laissé et le script s'exécute de manière synchrone, instruction par
instruction. Il convient toutefois de noter que les opérations du système de
fichiers bloquent l'exécution du script dans ce cas. Cela signifie que
l'instruction suivante ne peut pas être exécutée tant que l'opération du
système de fichiers n'est pas terminée. Pour plus d'informations sur
l'utilisation du module FileSystem , reportez-vous au chapitre 5,
«Utilisation des fichiers», qui traite uniquement de cette rubrique.

HTTP
Le serveur Web classique dans Node.js est le module http disponible Le
module gestellt.Dieses, cependant, offre non seulement le composant
serveur, mais vous pouvez également l'utiliser pour créer un client HTTP et
interroger le serveur Web. Dans l'exemple d'introduction du chapitre 3, "Un
premier exemple", le composant serveur a déjà été examiné en détail. Le
chapitre 6, "Communication", traite en détail des options de communication
de Node.js et ici, entre autres, des fonctionnalités du module http .

HTTPS
Le module https va également dans une direction similaire au module
crypto . Il garantit que les données confidentielles sont cryptées et
déplacées entre le client et le serveur. L'implémentation sécurisée de HTTP
dans Node.js est un module distinct qui dérive de parties du module TLS
et a des interfaces très similaires au module http . Le module https est
également examiné plus en détail au chapitre 6 et ses utilisations possibles
sont illustrées à l'aide d'exemples spécifiques. Modules Le système de
modules Node.js lui-même est également implémenté en tant que module. Il
permet de définir les modules et de les charger. Des fonctions d'aide
supplémentaires sont également disponibles. La fonctionnalité du module
est d'une grande importance dans les applications Node.js, car elle permet
de subdiviser le code source d'une application en parties plus petites et de
rendre une application plus maintenable. Vous avez utilisé le système de
modules à plusieurs reprises au cours de ce livre. Chaque appel à la
fonction require représente une utilisation du module Module. Au cours
de ce chapitre, vous en apprendrez plus sur ce module, ses interfaces et
comment vous pouvez utiliser cette fonctionnalité pour votre propre
application.

Net
La communication est un sujet important dans les applications Web
modernes. Ceux-ci consistent souvent en plusieurs systèmes qui doivent
échanger des informations entre eux. L'éventail des types et protocoles de
communication est large. Le module Net vous offre un certain nombre
d'interfaces avec lesquelles vous pouvez communiquer via des connexions
TCP et des sockets UNIX, dans le rôle de serveur et de client. Dans le
chapitre 6, vous apprendrez comment utiliser ce module pour envoyer des
données sur le réseau ou localement entre différents processus.

Os
Ce qu'est le navigateur pour JavaScript côté client est le système
d'exploitation pour JavaScript côté serveur. D'abord et avant tout un
environnement qui offre un certain nombre d'interfaces avec lesquelles vous
pouvez interagir. Comme dans le navigateur, il existe certaines différences
entre les différents systèmes d'exploitation et architectures informatiques
qui peuvent influencer le développement des applications. Le module OS
vous permet d'interroger certains paramètres de structure du système
d'exploitation, tels que le nom d'hôte ou le type et la version du système,
puis d'influencer l'exécution de l'application. Au cours de ce chapitre, vous
en apprendrez plus sur ce module et verrez comment les différentes
fonctionnalités fonctionnent à l'aide d'exemples pratiques. Path Node.js est
relativement indépendant du système d'exploitation sous-jacent. Cependant,
cela ne s'applique qu'à certaines limites. Les différences entre les systèmes
UNIX et Windows sont particulièrement visibles dans le domaine de l'accès
au système de fichiers. Le module Path est disponible pour vous aider à
résoudre ce problème et d'autres problèmes de formulation et d'analyse des
noms de chemin. Cela vous permet également de gérer plus facilement les
chemins absolus et relatifs. Dans la Section 4.2, «Modules de base», vous
apprendrez à utiliser les chemins dans les applications Node.js à l'aide de
divers exemples.
Punycode Punycode est utilisé pour convertir des chaînes Unicode au
format ASCII, et Punycode peut être utilisé dans les deux sens, c'est-à-dire
à la fois d'Unicode à ASCII et d'ASCII à Unicode. Punycode est né de la
nécessité d'autoriser les noms de domaine avec des caractères spéciaux, qui,
en revanche, n'autorisent pas le DNS. Punycode a créé une solution de
contournement qui rend cela possible. Node.js s'appuie sur un convertisseur
Punycode réellement indépendant, qui fait partie intégrante du système de
modules Node.js depuis la version 0.6.2. Les caractéristiques les plus
importantes de ce module sont les différentes méthodes d'encodage et de
décodage des chaînes. Le Listing 4.10 montre l'utilisation des deux
variantes.
var punycode = require ('punycode'),
decoded = ' ', encoded = '-mfb6xb1226bstb4a3n9oaf';
console.log ( punycode.encode (decoded));
console.log ( punycode.decode (encoded));

Chaîne de requête
Les sites Web sont adressés via leur URL. En plus de diverses informations
telles que le nom d'hôte et le numéro de port, HTTP permet également la
spécification d'une soi-disant chaîne de requête. Ceci est normalement
utilisé pour transmettre les paramètres au serveur. La chaîne de requête se
trouve ci-dessous dans le chemin de l'URL et en est séparée par un point
d'interrogation. La chaîne de requête se compose de paires clé-valeur
séparées les unes des autres par des caractères & . Les clés et les valeurs
sont séparées les unes des autres par des signes = . La gestion des chaînes
de requête, qu'il s'agisse de codage ou de décodage, est une tâche
fréquemment récurrente qui est considérablement simplifiée par le module
QueryString .
var querystring = require ('querystring'),
string = 'search = nodejs & page = 1',
obj = {search: "nodejs", page: "1"};
console.log ( querystring.stringify (obj));
console.log ( querystring.parse (string));
La liste montre l'utilisation de la méthode stringify , qui peut être utilisée
pour convertir un objet en chaîne de requête. Les paires clé-valeur sont
formées et connectées avec des caractères & . La méthode d' analyse est
utilisée pour traduire une chaîne de requête en une structure d'objet que
vous pouvez continuer à utiliser dans votre application et dans laquelle vous
pouvez accéder aux différents composants de la chaîne de requête à l'aide
des valeurs de clé. Avec les deux méthodes, vous pouvez transférer le
séparateur dans les paires clé-valeur ainsi que le séparateur entre les paires
clé-valeur individuelles et ainsi écraser les normes. Un problème persiste
lors de l'analyse des QueryStrings. Une chaîne de requête fait généralement
partie d'une URL entière, vous devez l'extraire en tant que telle avant de
pouvoir utiliser le module QueryString pour la traiter davantage. Node.js
vous propose une combinaison du module URL et du module QueryString
. La méthode d' analyse du module URL accepte un deuxième argument
facultatif, qui garantit que la méthode d' analyse du module QueryString
est appelée afin d'analyser la chaîne de requête d'une URL dans le même
appel de fonction et de la renvoyer sous forme de tableau dans le retour
valeur .

Readline
Avec Node.js, vous pouvez non seulement implémenter des applications
Web, mais également des applications qui fonctionnent sur un serveur
indépendamment des clients du navigateur. Dans de tels cas, cependant, il
est parfois nécessaire de fournir une interface avec laquelle un utilisateur
peut également contrôler ces types d'applications. Il existe deux principaux
canaux de communication disponibles sur la ligne de commande: l'entrée et
la sortie standard. Vous pouvez l'utiliser pour accepter l'entrée de
l'utilisateur ou pour afficher des informations à l'utilisateur. Les outils de
ligne de commande écrits en Node.js peuvent également être utilisés dans le
domaine des applications Web. C'est notamment le cas de l'installation et de
la configuration.
var readline = require ('readline'),
rl = readline.createInterface ({
input: process.stdin ,
output: process.stdout });
rl.write ('*** Node.js command line *** \ n');
rl.question ('$>', function (command) {
rl.write (command + '\ n'); rl.close ();}
);

L'exemple du Listing 4.12 montre comment vous pouvez utiliser le module


Readline pour interroger les entrées utilisateur de votre application sur la
ligne de commande afin qu'il puisse être utilisé dans votre application.
L'initialisation n'est pas un problème. Il vous suffit de créer une nouvelle
interface et de définir les canaux d'entrée et de sortie. Dans le cas de
l'exemple, il s'agit de l'entrée et de la sortie standard. Après l'initialisation,
vous pouvez utiliser l'interface pour afficher des informations sur la ligne de
commande à l'aide de la méthode write ou pour interroger des entrées à
l'aide de la méthode question . La méthode de question fonctionne de
manière asynchrone. Cela signifie que le premier argument est imprimé sur
la ligne de commande lorsque la méthode est appelée. Le script attend
ensuite l'entrée de l'utilisateur. Lorsque cela a terminé l'entrée, la fonction
de rappel, qui a été définie dans le deuxième argument, est appelée avec la
valeur d'entrée. Lorsque vous utilisez le module Readline , vous devez
vous assurer de fermer l'interface créée avec close afin que le script puisse
se terminer correctement.
REPL
REPL signifie Read-Eval-Print Loop et représente le shell interactif
Node.js. Dans le chapitre 3, "Un premier exemple", vous avez déjà reçu un
aperçu détaillé des fonctionnalités du module REPL . En plus des
fonctionnalités interactives qui y sont présentées, vous pouvez également
démarrer le shell interactif dans un script Node.js normal. La méthode start
existe à cet effet. L'exemple suivant dans la liste montre comment un shell
peut être démarré avec une invite définie par l'utilisateur.

var repl = require ('repl');


repl.start ({prompt: 'NODE>',
input: process.stdin ,
output: process.stdout
});

La méthode start accepte un objet de configuration qui peut être utilisé


pour influencer le comportement du shell. Les options vont des clés d'
entrée et de sortie , que vous utilisez pour spécifier à partir de quoi
l'entrée doit être lue et où la sortie doit être écrite, à l' invite , que vous
utilisez pour spécifier à quoi devrait ressembler l'invite, et à eval , que
vous utilisez pour taper une fonction définie par l'utilisateur pour exécuter
les commandes entrées. Stream Le module Stream représente une
interface abstraite pour les flux de données lisibles et inscriptibles dans
Node.js et sert ainsi de base au module Net , par exemple. Le module
Stream peut être utilisé pour les connexions TCP ainsi que pour les
composants client et serveur de sockets de domaine UNIX avec lesquels
vous pouvez ensuite communiquer entre applications, mais également entre
différents systèmes. Exemples qui illustrent la fonctionnalité du module de
flux veranschaulichenund plus d'informations générales sur la
communication via les flux findenSie dans le chapitre 6. Décodeur de
chaîne Le module Décodeur de chaîne sert un objet tampon à une chaîne à
wandeln.Zu cette fin, ce module la classe Décodeur de chaîne Lors de la
création un objet de cette classe, vous pouvez transmettre l'encodage de la
chaîne au constructeur. Si aucune valeur n'est transmise ici, l'encodage est
UTF-8 par défaut. Vous pouvez ensuite utiliser la méthode write pour
convertir un objet tampon en une chaîne qui est ensuite renvoyée.
L'exemple de la liste illustre ce flux de travail.
var Decoder = require ('string_decoder' ) .StringDecoder ,
Buffer = require ('buffer' ) .Buffer ,
decoder = new decoder ('utf-8'),
buffer = new buffer ( 'Hello World');
console.log ( decoder.write (buffer)
);

Minuteries
Comme vous l'avez déjà vu avec la fonctionnalité de la console , certaines
fonctionnalités déjà connues de l'environnement du navigateur ont été
portées sur Node.js. Cela s'applique également aux fonctions dépendant du
temps qui contrôlent les délais et les intervalles. Tout d'abord, vous
apprendrez à connaître la fonctionnalité de délai d'expiration à l'aide d'un
court exemple. Le Listing 4.15 montre comment vous pouvez utiliser les
fonctions correspondantes.
var callback = function (string) {
console.log ( 'Hello' + string);
}
var timeout = setTimeout ( callback, 5000, 'World');
// clearTimeout (timeout);

L'exemple montre que vous pouvez utiliser la fonction setTimeout pour


exécuter une fonction après un certain laps de temps. Le premier argument
que vous passez à cette fonction est la fonction de rappel qui doit être
exécutée. Le deuxième argument est la durée, en millisecondes, à attendre
avant que la fonction soit exécutée. Vous avez également la possibilité d'
ajouter autant d'arguments supplémentaires à la fonction setTimeout . Ceux-
ci sont transmis à la fonction de rappel lorsqu'ils sont appelés, comme c'est
le cas dans l'exemple de Listing avec la chaîne de caractères World . Vous
pouvez annuler le délai d'expiration avec la fonction clearTimeout . Cela
signifie que la fonction de rappel n'est pas exécutée. Pour pouvoir annuler
un délai d'expiration, vous avez besoin de son identifiant. Vous recevez ceci
comme valeur de retour de la fonction setTimeout . Si vous supprimez les
deux barres obliques devant la dernière ligne de l'exemple, le délai
d'expiration est annulé et vous ne recevez aucune sortie. Il y a des situations
dans lesquelles un timeout seul ne vous suffit pas, mais vous devez appeler
la même fonction plusieurs fois de suite aux mêmes intervalles de temps.
Au lieu de basculer plusieurs délais dans une ligne, vous pouvez utiliser la
fonction setInterval dans ces cas. Elle se comporte comme la fonction
setTimeout , les signatures des fonctions sont les mêmes. La seule
différence est que la fonction de rappel n'est pas appelée une seule fois,
mais jusqu'à ce que l'exécution soit interrompue avec clearInterval .

TLS
Le module TLS est un outil que vous pouvez utiliser pour utiliser des
connexions cryptées pour le transfert de données. Le module TLS est basé
sur d'autres modules que vous avez déjà brièvement connus. D'une part, le
Crypto module est utilisé pour des tâches de cryptage, le flux module
fournit les interfaces pour les flux de données, et le net module forme la
base d'une structure de serveur sécurisé. TTY Vous pouvez déjà voir
l'utilisation du module TTY au cours de ce chapitre à l'aide d'exemples. Ce
module fournit des flux lisibles et inscriptibles pour les terminaux. Cela
signifie que vous obtenez un contact indirect avec ce module lorsque vous
utilisez le REPL. Vous utiliserez rarement ce module directement. En
pratique, cela signifie que process.stdin , l' entrée standard et
process.stdout , la sortie standard , sont des flux du module TTY . Vous
pouvez facilement savoir si les deux variables proviennent vraiment de ce
module en exécutant le code de Listing.
$ node
> process.stdout .isTTY
True
> process.stdin .isTTYtrue
>

La propriété isTTY a la valeur true si les classes du module TTY sont


utilisées.

URL
Le module URL a déjà été mentionné et a déjà été utilisé dans certains
exemples. Dans le cas le plus simple, vous utilisez la méthode parse pour
traduire une URL en un objet, dans lequel vous pouvez accéder aux
différentes parties de l'URL via les différentes propriétés.
var url = require ('url'),
string = 'http://www.google.de/search?q=node.js';
console.log ( url.parse (string)
);

Le résultat dans la liste est un objet, où vous entre autres, le proto-col http
, l'hôte www.google.de , le chemin d'accès / recherche ou chaîne de
requête q = node.js accéder à können.Die deuxième fonctionnalité de l'
URL - Module, la méthode de format , est utilisée pour vous donner le
chemin du retour, c'est à dire pour générer une URL valide à partir d'un
objet.

var url = require ('url'),


obj = {protocol: 'http',
host: 'www.google.de',
pathname: '/ search',
search: 'q = node.js'
}
console.log ( url.format (obj)
);

vous montre certaines des propriétés disponibles que vous pouvez utiliser
pour générer une URL valide. La troisième et dernière fonctionnalité du
module URL consiste en la méthode de résolution . Avec cela, une URL
peut être créée. Pour cela, la méthode prend deux arguments, une URL de
base et un chemin relatif. La valeur de retour se compose de l'URL
composite. La composition non seulement les chaînes sont enchaînées, mais
également certains caractères sont évalués. Par exemple, deux points
signifient qu'un niveau du chemin doit être réduit. Le Listing 4.19 illustre
cela.

require ('url ') from = 'http://de.eurosport.yahoo.com/fussball/',


to = '.. / ice hockey /';
var resolved = url.resolve (from, to)
; console.log (resolved);

Le résultat de la liste est la chaîne http://de.eurosport.yahoo.com/eis-


hockey/. Utilitaires Le module Ultilities combine diverses fonctionnalités
qui sont souvent utilisées dans le processus de développement. Cela inclut
des méthodes de formatage et de sortie, mais aussi des méthodes qui vous
permettent, par exemple, d'hériter plus facilement dans les applications
Node.js. Ces méthodes et d'autres du module Utilitaires sont abordées plus
en détail plus loin dans ce chapitre et leur fonctionnalité est expliquée à
l'aide d'exemples concrets.
VM
Le module VM vous permet d'évaluer et d'exécuter du code JavaScript.
Contrairement à la fonction eval , que JavaScript vous fournit directement,
il y a ici une délimitation du contexte, de sorte que l'exécution peut faire
moins de dégâts. Le module VM contient diverses méthodes avec
lesquelles le code peut être évalué et exécuté. Cependant, vous ne pouvez
que compiler le code, enregistrer le résultat et l'exécuter ultérieurement. Il
existe au total trois méthodes différentes qui diffèrent dans le contexte
d'exécution respectif. runInThisContext exécute le code JavaScript, le
contexte local en dehors de la machine virtuelle ne peut pas être modifié,
mais il ne peut pas non plus être lu. Vous pouvez utiliser la méthode
runInNewContext pour définir un contexte d' exécution dans lequel le
code source doit être exécuté. Cela signifie que vous pouvez initialiser un
environnement pour l'exécution avec certaines variables. Enfin, la troisième
méthode, runInContext , vous permet de fournir un contexte dans lequel le
script doit être exécuté. Vous pouvez créer ce contexte à l'aide de la
méthode createContext du module VM . Les trois méthodes VM
acceptent un argument de nom de fichier facultatif . Cependant, cela n'est
pas utilisé pour stocker le code source compilé ou le résultat dans un fichier,
mais n'est utilisé que dans les traces de pile pour signaler que le code source
qui est exécuté dans une machine virtuelle n'appartient pas réellement au
fichier dans lequel la machine virtuelle est défini.
var vm = require ('vm'),
context = {
firstname: 'John',
lastname: 'Doe'},
myContext = vm.createContext (context),
firstname = 'Chuck',
lastname = 'Norris',
script = 'firstname = "Mickey"';
vm.runInContext (script, myContext);
console.log ( 'Local:', firstname, lastname);
console.log ( 'VM:', myContext.firstname, myContext.lastname);

Dans l'exemple de Listing, le code JavaScript est exécuté dans un contexte


nouvellement défini. Dans ce contexte, les variables prénom et nom se
voient déjà attribuer les valeurs John et Doe . Le code source à exécuter
attribue une nouvelle valeur à firstname . Pour indiquer clairement
qu'aucun accès externe ne peut avoir lieu dans une VM, les variables
firstname et last-name ont également été définies en dehors de la VM.
Utilisez la méthode runInContext pour exécuter le code source. Enfin,
vous pouvez voir les résultats du script si vous sortez les variables à l'aide
de console.log . Vous accédez au contexte de la VM via la variable
myContext , la valeur de retour de la méthode createContext .

Modules de base
Vous avez déjà appris que les différents modules de la plateforme Node.js
sont plus ou moins indépendants les uns des autres. Cependant, il existe
certains modules sur lesquels d'autres modules sont basés. D'autres modules
fournissent uniquement des fonctionnalités spéciales. Vous en apprendrez
plus sur ces modules de base ci-dessous.

Objets globaux
Si vous souhaitez utiliser des fonctionnalités supplémentaires sous la forme
de modules Node.js dans votre application, vous devez normalement
intégrer le module avec la fonction require . Vous pouvez accéder aux
fonctionnalités respectives via la valeur de retour de cette fonction. Certains
objets et fonctions sont si souvent nécessaires que les développeurs de
Node.js ont décidé de les rendre disponibles directement dans le contexte
global. Dans ce cas, vous n'avez pas besoin d'intégrer un module avant
utilisation. Les fonctions et objets globaux sont disponibles dans un
contexte global. Ce contexte est comparable au contexte de fenêtre du
navigateur, mais il faut noter que chaque module a son propre contexte
global. La liste suivante contient toutes les fonctions et objets globaux dans
Node.js.

Nom du fichier et du répertoire


__Filename et __dirname sont deux variables très utiles lors du
développement d'applications . Comme le suggèrent les noms de ces
variables , les deux contiennent des informations sur l'emplacement du
fichier où le code source du script en cours d'exécution est stocké. La
chaîne de __filename est le chemin absolu et le nom de fichier du script.
__dirname est juste le chemin. Lorsque vous utilisez le shell interactif,
assurez-vous que ni __filename ni __dirname ne sont définis, car il n'y a
pas de script dans ce cas. En plus de ces deux variables, il existe une autre
fonction dans le contexte global que vous avez utilisée plusieurs fois au
cours de ce livre, la fonction require . Il est utilisé pour charger des
modules.

Tampon
La classe Buffer est également disponible globalement, car vous avez très
souvent affaire à ce type d'objet dans Node.js. Vous pouvez voir l'utilisation
de cette fonctionnalité dans la section sur le module ZLIB de ce chapitre,
par exemple, dans laquelle la fonction gonfler reçoit une chaîne de
caractères compressée comme objet tampon pour le déballage. Un objet de
cette classe peut être créé facilement et il n'est pas nécessaire de charger le
module tampon au préalable. console Une autre fonctionnalité que vous
connaissez déjà à partir du JavaScript côté client grâce à laquelle vous en
apprenez déjà plus dans ce chapitre objet global est disponible, également
appelée. Nous parlons de l' objet console , qui est principalement utilisé
pour la sortie sur la ligne de commande et pour mesurer les temps
d'exécution lors du développement.

Exportations
La création de vos propres modules est également très courante lorsque
vous travaillez avec Node.js, pour lequel Node.js vous fournit l' objet
exports . Cependant, cet objet n'existe pas dans le contexte global. Il existe
un objet Exportations distinct pour chaque module que vous créez. Il est
utilisé pour rendre la fonctionnalité d'un module accessible à l'extérieur. L'
objet exports fait partie du module Modules et est complètement nommé
module.exports , où les deux notations ont la même fonctionnalité. La liste
montre l'utilisation de l' objet exports sous la forme d'un validateur d'e-
mail, que vous pouvez enregistrer, par exemple, dans le fichier validator.js.
Vous pouvez utiliser cette fonction dans votre application en tapant la ligne
require ('validator.js'). Courriel ('test@test.de'); intégrer dans votre
application. Il est vérifié si la chaîne test@test.de contient une adresse e-
mail valide.
exports.email = function (email) {
var regex = / ^ ([a-z0-9_ \ .- ] +) @ ([\ da-z \ .-] +) \. ([az \.] {2,6}) $ /,
result = regex.exec (email);
if (result) {
return true;
}
return false;
};

Dans ce chapitre, vous allez créer vos propres modules et la plication


USAGE du module Modules plus en détail. L' objet d' exportation
kennenlernen.Das n'est pas la seule fonctionnalité fournie par le module -
Modulglobal disponible. L' objet module lui-même est également
disponible sans appel préalable à require . Tout comme l' objet exports , il
s'agit d'un objet qui existe séparément pour chaque module et qui n'est pas
disponible globalement pour tout le code source d'une application.

Processus
Lors du développement d'applications, les informations du processus
Node.js actuel sont souvent consultées. Pour cette raison, le module
Process - qui fournit simplement ces informations est également disponible
dans le monde entier. De la même manière, les méthodes de ce module
peuvent être utilisées pour contrôler le processus. De plus amples
informations sur l'utilisation des fonctionnalités de ce module sont
disponibles plus loin dans ce chapitre. Vous pouvez utiliser le chargeur de
module Node.js principalement en utilisant la fonctionnalité requise . Ceci
est également disponible dans le monde entier. Dans les sections suivantes,
vous en apprendrez plus sur la façon dont vous pouvez charger des
modules, mais aussi comment vous pouvez influencer le comportement du
chargeur de module. Les fonctions de temporisation et d' intervalle déjà
décrites sont utilisées assez souvent. Pour cette raison, comme dans le
navigateur, elles sont disponibles sous forme de fonctions globales.

Utilitaire
Le module utilitaire contient de nombreuses méthodes utiles que vous
pouvez utiliser lors du développement de votre application. Une fonction
qui manque à de nombreux développeurs qui viennent d'autres langages de
programmation est la fonction connue de C, printf . Le module utilitaire
vous offre une fonctionnalité similaire avec la fonction de formatage .
Votre utilisation démontre votre annonce.
var util = require ('util'),
string = util.format ('Hello% s', 'World');
util.log (string);

La inherits méthode est un bon exemple de la façon dont l' environnement


de la plate - forme Node.js JavaScript tire ihrenVorteil d'un uniforme,
contrairement zumclientseitigen JavaScript dans lequel plusieurs moteurs
JavaScript dans les versions différentes et avec des caractéristiques
différentes utilisées support kommen.So Node.js la norme ECMAScript
dans la version 5 La spécification complète de cette norme peut être trouvée
à http://www.ecma-international.org/publications/standards/Ecma-262.htm.
Diverses fonctionnalités de celui-ci sont utilisées pour l'héritage. Par
exemple, un clone du prototype de la classe parente est créé et la
configuration de la propriété constructeur est modifiée de sorte que
l'itération sur les propriétés d'un objet exclut le constructeur. Toute la
logique de la méthode hérite comprend onze lignes de code source, ce qui
est très peu comparé au JavaScript côté client, dans lequel diverses
solutions de contournement sont utilisées pour prendre en charge le
navigateur.

Événements
Au cours de ce chapitre, vous avez déjà un bref aperçu du module
Evénements . Étant donné que la plate-forme Node.js s'appuie souvent sur
des événements lors de la communication entre objets, il est logique
d'utiliser cette forme d'architecture lors de l'implémentation de vos propres
fonctionnalités. En plus de la simple utilisation du module Evénements ,
comme vous pouvez le voir dans le Listing 4.9, il existe d'autres méthodes
que vous pouvez utiliser pour mieux contrôler les événements et leur
gestion. Up-elle vous avez seulement l'utilisation des méthodes émettent
pour la mise Eventsund sur vu pour réagir aux événements. La première
méthode garantit qu'une fonction de rappel enregistre et émet est appelée
chaque fois que l'événement spécifié est déclenché. Avec la méthode once ,
vous avez la possibilité d'exécuter la fonction de rappel uniquement la
première fois que l'événement est déclenché. Vous pouvez également
supprimer des écouteurs d'événements précédemment enregistrés. Vous
pouvez le faire pour un écouteur spécial à l'aide de la méthode
removeListener ou pour tous les écouteurs d'un événement spécifique à
l'aide de removeAllListeners . La liste vous montre une combinaison de ces
méthodes. Nous utilisons également la méthode des écouteurs , que vous
pouvez utiliser pour savoir quels écouteurs sont liés à un événement
spécifique.
var emitter = new (require ('events' ) .EventEmitter ) ();
var callback = function () {
console.log ( 'Once ping event');
};
emitter.once ('ping', callback);
emitter.on ('ping', function () {console.log ('On ping event');
} ); console.log (emitter.listeners ('ping'));
mitter.removeListener ('ping', callback);
console.log ( emitter.listeners ('ping'));

La base de l'exemple est une copie de l' objet EventEmitter . Dans la


première étape, deux écouteurs sont liés à l' événement ping . Pour la
démonstration, vous obtenez un tableau d'écouteurs liés en appelant la
méthode des écouteurs avec la chaîne ping . Ensuite, l'écouteur, qui n'est
exécuté que la première fois, est supprimé. Même après cette opération,
vous sortez à nouveau les écouteurs liés pour clarifier l'effet. En résumé, on
peut dire que le module Événements fournit les fonctionnalités dont vous
avez besoin chaque fois que vous devez gérer des événements dans votre
application. La classe EventEmitter doit donc servir de base à toutes les
fonctionnalités basées sur des événements, car cela introduira une interface
uniforme pour la gestion des événements dans votre application.

OS
Le module OS est également d'une importance capitale pour votre
application. Surtout, il existe des options pour interroger les paramètres du
système d'exploitation. Vous pouvez maintenant l'utiliser pour générer un
petit aperçu des paramètres de structure de votre système dans un autre
exemple. Cet aperçu est destiné à afficher le nom d'hôte, des informations
sur le type de système d'exploitation, l'architecture de l'ordinateur et le
nombre de processeurs. De plus, la disponibilité, la mémoire de travail libre
et la charge de calcul doivent être affichées. Étant donné que ces
informations sont assez dynamiques, l'affichage doit être mis à jour à
intervalles réguliers.

var os = require ('os');

var monitor = function () {


this.hostname = os.hostname ();
this.sysInfo = 'ona' + os.type () + '' + os.platform () + '' + os.arch ()
+ 'System with' + os.cpus () .length
+ 'CPUs '; this .totalmem = os.totalmem () / 1048576
+ 'MB';
this.uptime ;
this.freemem ;
this.load ;
}
Monitor.prototype.setUptime = function () {
var seconds = os.uptime ();

var hours = Math.floor (seconds / 3600),


minutes = Math.floor ((seconds - hours * 3600) / 60),
seconds = (seconds - hours * 3600 - minutes * 60);
this.uptime = hours + ':' + minutes + ':' + seconds;

}
Monitor.prototype.setFreemem = function () {
this.freemem = this.formatNumber (os.freemem () / 1048576);
}
Monitor.prototype.setLoad = function () {
this.load = this.formatNumber (os.loadavg () [0]);
}
Monitor.prototype.formatNumber = function (number) {
return Math.round (number * 100) / 100;
}
Monitor.prototype.clearScreen = function () {
for ( var i = 0; i <process.stdout.rows; i ++) {
console.log ('\ r \ n');
}
}
Monitor.prototype.update = function () {
this.setUptime ();
this.setFreemem ();
this.setLoad ();
return this;
}
Monitor.prototype.output = function () {
this.clearScreen ();
console.log ( this.hostname );
console.log ( this.sysInfo );
console.log ('Uptime:' + this.uptime );
var free = this.freemem ;
var total = this.totalmem ;
console.log ( 'Freemem:' + free + 'MB of' + total + 'MB');
console.log ( 'Load:' + this.load);
}
var sysMon = new Monitor ( );
setInterval ( function ( ) {
sysMon.update ( ) .output ()}, 500);

La classe Monitor constitue la base de l'exemple du Listing 4.28. Il est


chargé d'encapsuler toutes les informations, de mettre à jour les données sur
demande et de les afficher. Dans la fonction constructeur Monitor, vous
définissez les propriétés requises. Certaines de ces propriétés sont statiques
et peuvent recevoir des valeurs correspondantes dans le constructeur. Cela
inclut, par exemple, le nom d'hôte, les informations système et la taille de la
mémoire. Les méthodes de la classe sont définies comme des propriétés du
prototype par Monitor . Les interfaces externes que l'utilisateur doit utiliser
sont la mise à jour méthode pour mettre à jour les données dynamiques et
la sortie procédé pour délivrer en sortie les informations sur la console.
Les informations dynamiques qui doivent être lues à chaque mise à jour
sont constituées du temps de fonctionnement du système, de la mémoire
actuellement libre et de la charge du système. Les informations enregistrées
dans les propriétés de l'instance du moniteur sont lues à partir du système à
l'aide des méthodes setUptime , setFreemem et setLoad . Veuillez noter que
vous devez afficher le temps de disponibilité au format «heures: minutes:
secondes», la mémoire de travail libre en mégaoctets et la charge arrondie à
deux décimales. Dans votre cas, ces tâches sont également effectuées par
les méthodes qui lisent les informations. Pour mettre en forme les nombres,
créez la fonction formatNumber, qui arrondit les nombres à deux
décimales. Les informations sont affichées dans la méthode de sortie , qui
lit les propriétés de l' instance de moniteur et les sort sur la sortie standard.
Pour tester la fonctionnalité du code source, il vous suffit d'instancier la
classe Monitor et d'utiliser cet objet pour mettre à jour - et appeler des
méthodes de sortie . Cependant, l'une des conditions était que les
informations affichées soient mises à jour. Pour cette raison, d'une part ,
vous devez vous assurer de la sortie méthode que l'écran est effacé, que
vous pouvez réaliser avec les auxiliaires fonction CLEARSCREEN , et
d'autre part avec la fonction setInterval que vous avez à appeler les
méthodes mise à jour et sortie à intervalles réguliers. Vous avez ainsi créé
un moniteur système très léger qui peut encore être étendu avec les
fonctionnalités du module OS . Il est également possible d'obtenir des
informations supplémentaires sur le système à partir du système de fichiers
et d'autres outils système et de les intégrer également dans le moniteur
système . Une présentation graphique des informations affichées est
également envisageable.

Processus
Lorsque le module OS vous fournit des informations au niveau du
système, l' objet Processus fonctionne à un niveau supérieur. Cet objet
forme l'interface avec le processus Node.js en cours d'exécution.
Contrairement à OS est processus pas un module Node.js à part entière
dont le code source dans lib est le répertoire de fichier Node.jsals
JavaScript est disponible, mais un objet à l' abstraction
undProzesssteuerung qui a fourni par Node.js directement disponibles
wird.Im Dans le dernier exemple , le moniteur système du Listing 4.28,
vous avez déjà utilisé l' objet de processus pour effacer l'écran. Le listing
4.29 montre cette partie du code source.
var clearScreen = function () {
for ( var i = 0; i <process.stdout.rows; i ++) {
console.log ('\ r \ n');
}
}

Dans cet exemple, la propriété d'objet de processus stdout for available


about you können.Neben exemple, lisez le nombre de colonnes de la sortie
standard de la console que vous pouvez sur les caractéristiques stderr et
stdin access auchauf standard error, and standard input. Outre la possibilité
d'accéder directement à la sortie et à l'entrée, l' objet de processus vous
offre également une interface que vous pouvez utiliser pour terminer le
processus en cours. La méthode standard pour terminer une application, en
plus du traitement de toutes les commandes, après quoi le processus Node.js
est automatiquement terminé, consiste à utiliser la méthode exit de l' objet
processus . Cette méthode accepte un argument qui est utilisé comme code
d'état et est normalement renvoyé au processus parent, la console système.
$ node
> process.exit (42);
$ echo $?
42

L'exemple du Listing 4.30 vous montre comment vous pouvez également


utiliser process.exit dans le shell Node.js. Avec echo $? vous pouvez
interroger la valeur de retour de la dernière application sur le shell UNIX.
Une valeur de retour de 0 signifie que l'application a été exécutée avec
succès et s'est terminée sans erreur. Une valeur différente de 0 signifie
qu'une erreur s'est produite lors de l'exécution. Vous pouvez utiliser la
valeur que vous renvoyez pour indiquer la raison de la résiliation, afin
qu'elle puisse servir de type de code d'erreur. L'effet de la méthode d'
abandon est une étape plus drastique. Il est utilisé pour annuler une
candidature. Il n'est donc pas terminé de manière régulière et contrôlée.
$ node
> process.abort ();
Abort trap: 6
$ echo $?
134
Comme vous pouvez le voir dans le Listing 4.31, une application Node.js se
comporte fondamentalement différemment si elle est arrêtée en appelant la
méthode abort . D'une part, vous recevez la sortie système Aborttrap : 6 ,
qui indique que l'application a été abandonnée par un signal d' abandon et
n'a pas été interceptée par l'application. De plus, la valeur de retour de
l'application est automatiquement définie sur la valeur 134 . Cela indique
également que l'application a été annulée. Le troisième moyen et de loin le
plus puissant de mettre fin à une application est d'utiliser la méthode kill .
Vous pouvez utiliser cette méthode non seulement pour mettre fin à la
propre application, mais pour tout processus de votre système, si
l'utilisateur sous lequel l'application Node.js est exécutée, possède les
droits. Des fonctionnalités comme celle-ci sont l'une des raisons pour
lesquelles une application Node.js ne doit pas être exécutée par un
utilisateur administrateur. La méthode kill prend deux arguments, le
premier se compose de l'ID de processus auquel un signal spécifique doit
être envoyé. Le deuxième argument est le signal que vous souhaitez
envoyer. Si le deuxième argument n'est pas spécifié, la demande de fin de
processus est envoyée avec SIGTERM par défaut.
$ node
> process.kill (process.pid, 'SIGKILL');
Killed: 9
$ echo $?
137

L'exemple du Listing 4.32 vous montre deux cas dans lesquels vous devez
utiliser l' objet process . D'une part, il s'agit de la méthode kill déjà
mentionnée pour envoyer un signal à un processus, et d'autre part, de la
propriété pid de l' objet process , qui contient l'ID du processus Node.js
actuel auquel vous font référence dans ce cas veulent envoyer le signal. En
supposant que l'exemple de processus ne peut plus être terminé par
SIGTERM , dans ce cas, vous avez besoin de SIGKILL comme signal qui
ne peut pas être intercepté par le processus lui-même, mais qui est à la place
envoyé directement au noyau, qui se charge de terminer le processus.
Cependant, cela signifie également que le processus n'a pas d'autre option
pour conserver les données qu'il peut avoir en mémoire sur le disque dur.
Semblable à la fin avec la méthode abort , le système définit
automatiquement une valeur de retour de 137 lorsque le kill avec
SIGKILL se produit et la chaîne Killed: 9 est sortie. Le nombre 9 représente
la représentation entière de SIGKILL et 15 celle de SIGTERM . L'
objet de processus est assez vaste si l'on considère sa gamme de fonctions.
En plus des propriétés déjà présentées, que vous pouvez utiliser pour
accéder à l'entrée et à la sortie ou à l'ID de processus, argv et env sont
deux structures de données très précieuses qui sont très susceptibles d'être
utilisées dans le développement d'outils de ligne de commande. La propriété
argv vous propose un tableau JavaScript dans lequel les différentes parties
de l'appel de ligne de commande de l'application actuelle sont stockées. En
supposant que vous démarrez votre application avec la ligne de commande
nodeserver.js - env = debug , argv contient trois éléments. Le premier est la
commande de noeud elle-même, le second est le chemin absolu et le nom
du fichier JavaScript, et le troisième élément est l'option spécifiée --env =
debug . De cette façon, vous pouvez rendre votre application configurable
à l'aide des options de ligne de commande. env fournit, comme son nom
l'indique, les variables d'environnement du processus Node.js actuel. Les
informations incluent, par exemple, le nom de l'utilisateur, la variable PATH
ou le répertoire personnel de l'utilisateur. L' objet de processus vous donne
également la possibilité d'afficher la version de Node.js lui-même et
certaines bibliothèques centrales. Vous pouvez obtenir les informations de
version exactes de Node.js via process.version . En plus de la version de
Node.js, process.ver-sions vous donne également les informations
pertinentes sur http_parser, le moteur V8, Ares, libuv, zlib et openssl.
Cependant, l' objet de processus vous permet non seulement de lire des
informations ou le processus, mais également d'affecter le processus en
cours d'exécution. Notez que les méthodes suivantes ne sont pas disponibles
sous Windows. Il est possible d'utiliser process.setuid pour changer
l'utilisateur sous lequel le processus en cours s'exécute. Cependant, pour
changer d'utilisateur, vous avez besoin de l'autorisation pour changer
d'utilisateur, sinon vous recevrez un message d'erreur. Vous pouvez obtenir
l'ID utilisateur actuellement défini à l'aide de la méthode process.getuid . La
même chose que pour l'ID utilisateur s'applique également à l'ID de groupe
avec les méthodes pro-cess.setgid et process.getgid .

Tampon
Le module tampon est que vous avez déjà rencontré plusieurs fois au cours
de ce livre. Il est utilisé à la fois lors de la lecture de fichiers, mais peut
également être utilisé pour écrire des données dans un fichier. Lorsque les
données doivent être empaquetées avec le module ZLIB , les objets Buffer
sont utilisés pour encapsuler les données dans des flux d'octets et pour les
utiliser en relation avec des flux de données. Un objet tampon a plusieurs
caractéristiques importantes: Le tampon a une taille fixe et ne peut pas être
modifié après sa création. Le codage des caractères des données contenues
peut également être spécifié. Vous disposez de plusieurs options pour créer
un objet tampon. Un objet tampon est créé à l' aide de certaines méthodes
telles que fs.readFile . Cependant, vous pouvez également créer un tel objet
explicitement en utilisant le constructeur de la classe Buffer . Un nombre
peut être passé au constructeur. Cela générera un tampon vide avec le
nombre d'octets spécifié. Une autre façon de le créer est de passer un
tableau d'octets au constructeur qui composent le contenu de l'objet tampon.
La troisième et dernière option consiste à spécifier une chaîne de caractères
et un codage facultatif.
var myBuffer = new Buffer ('Hello World'),
yourBuffer = new Buffer (11);
myBuffer.write ('World Hello World');
var length = myBuffer.length;
console.log (myBuffer.toString ());
myBuffer.copy (votreBuffer);
console.log (Buffer.concat ([myBuffer, yourBuffer]). toString ());

L'exemple du Listing 4.33 montre certaines des méthodes du module


tampon et donc certaines des options dont vous disposez lorsque vous
interagissez avec des objets tampons. Si vous créez un objet tampon, vous
avez la possibilité d'écrire de nouvelles données dans le tampon. Comme
déjà mentionné, cependant, vous devez noter que l'objet a une limite
supérieure fixe. Dans l'exemple, cette limite supérieure pour l' objet
myBuffer est de onze caractères. Maintenant, si vous essayez d'écrire une
chaîne plus longue dans l'objet en utilisant la méthode d' écriture , seuls les
onze premiers caractères seront acceptés. Tout ce qui dépasse ce nombre
maximum de caractères est ignoré. Si vous deviez simplement écrire Earth
dans la mémoire tampon au lieu de la chaîne WorldHelloWorld , cette
opération écrasera les cinq premiers caractères du tampon afin que le
contenu soit alors EarthHello . La propriété length spécifie le nombre de
caractères que l'objet tampon peut contenir. Dans l'exemple, la longueur des
deux objets tampons est de onze caractères. Si vous sortez un objet tampon
directement via console.log ou une autre méthode de sortie, vous obtenez
la représentation interne de l'objet. Si vous souhaitez lire la chaîne de
caractères qui contient un tampon, vous pouvez le faire en appelant la
méthode toString de l'objet. La valeur de retour se compose de la chaîne de
caractères correspondante. La méthode de copie vous donne également la
possibilité de copier le contenu d'un objet tampon dans un autre. Encore une
fois, vous devez noter que la longueur de l'objet tampon dans lequel vous
souhaitez copier détermine la capacité. Dans ce cas, la méthode de copie se
comporte comme la méthode d' écriture : les valeurs qui dépassent la
capacité maximale sont coupées. Si le contenu de l'objet cible est plus long
que celui de la source, les caractères restants de l'objet cible restent. La
méthode concat vous permet éventuellement de créer des eingroßes de
plusieurs objets buffer objets buffer par les objets Buffer liés ensemble
who-the. L'entrée de la méthode concat consiste en un tableau d'objets
tampons. La longueur totale du nouvel objet résulte de la somme des
différents objets d'entrée.

Chemin
Le dernier module que vous apprendrez dans cette section est le module
Path . Comme déjà annoncé, vous allez maintenant traiter de certaines
fonctionnalités de ce module et voir quelques exemples de la façon dont
vous pouvez l'intégrer dans une application Node.js et l'utiliser là-bas. Une
spécification de chemin dans le système d'exploitation est généralement une
séquence de plusieurs noms de répertoire séparés les uns des autres par le
séparateur de chemin du système d'exploitation. En plus des noms de
répertoires normaux, cependant, aussi . et .. répertoires valides. Un seul
point fait référence au répertoire courant, deux points indiquent le répertoire
parent. Ces éléments peuvent être utilisés pour des noms de répertoires tels
que /tmp/./. /./ .. / tmp plomb. Le module Path vous propose la méthode de
normalisation pour rendre ces détails de chemin plus clairs. Le Listing 4.34
vous montre le résultat de la normalisation.
$ node
> require ('chemin') .normalize ('/tmp/./././../tmp');
'/ tmp'

La méthode de normalisation est indépendante du répertoire de travail


actuel du processus Node.js et ne fait aucune distinction entre les chemins
absolus et relatifs. Il n'accepte qu'une chaîne de caractères et la normalise.
Étant donné que Node.js est largement indépendant du système
d'exploitation, le problème se pose ici que les applications qui doivent
fonctionner à la fois sur les systèmes Windows et UNIX fonctionnent avec
le séparateur de chemin respectif du système.À cette fin et pour vous éviter
en tant que développeur des requêtes inutiles système d'exploitation, la
propriété sep existe dans le module Path , qui contient le séparateur de
chemin valide pour le système actuel. Si vous souhaitez créer un chemin
complet à partir de plusieurs fragments, vous pouvez utiliser la méthode de
jointure . Il accepte n'importe quel nombre de noms de répertoires, les
combine dans un chemin global et normalise le résultat. Le Listing 4.35
montre comment vous pouvez utiliser la méthode join .
$ node
> var chemin = require ('chemin');
Indéfini
> path.join (path.sep, 'home', 'root', '..', path.sep + 'sspringer');
'/ home / sspringer'

Dans le cas de la méthode join , Node.js fait un peu de travail pour vous,
par exemple les fragments de chemin individuels sont automatiquement
séparés les uns des autres par un séparateur de chemin. La normalisation du
chemin garantit également qu'il n'y a pas de séparateurs de chemin en
double ou inutiles dans le chemin global. Une autre aide à la navigation est
la méthode de résolution , qui peut être utilisée pour convertir une cible en
un chemin absolu. Pour ce faire, vous spécifiez un chemin initial et une
série de commandes pour naviguer vers la destination, et la méthode
retourne ensuite le chemin résultant. La méthode relative vous donne les
commandes avec lesquelles vous pouvez passer d'un chemin absolu à un
autre. Donc, si vous entrez les deux chemins / home et / tmp, vous obtenez
le résultat ../tmp. Les méthodes dirname , basename et extname sont utiles
lorsque vous travaillez avec des chemins et des fichiers. Ils acceptent
chacun une chaîne comme argument, qui décrit un chemin vers un fichier,
et renvoient le chemin sans le nom du fichier, uniquement le nom du fichier
sans le chemin ou uniquement l'extension de fichier. Dans les dernières
sections, vous avez reçu une brève introduction à certains modules
importants de Node.js que vous rencontrerez encore et encore lors du
développement d'applications pour la plate-forme Node.js et avec l'aide
desquels vous pouvez résoudre un certain nombre de problèmes standard
avec peu d'effort . Dans la section suivante, vous allez maintenant aborder
la question de savoir comment concevoir et structurer votre propre code
afin qu'il reste aussi maintenable et flexible que possible.

Créez et intégrez vos propres classes


Jusqu'à présent, les exemples ont été relativement courts et clairs, et le code
source n'a été qu'un fichier à la fois. Cependant, vous avez déjà vu comment
vous pouvez intégrer des fonctionnalités supplémentaires sous la forme des
modules Node.js et comment vous pouvez étendre considérablement les
possibilités de votre application. L'intégration de modules permet également
de réutiliser des parties du code source, de sorte que vous n'ayez pas à
copier de code dans votre application. Ce qui s'applique aux modules
Node.js internes est, bien entendu, également souhaitable pour votre propre
code source. Dès que votre application devient plus étendue et complexe et
que vous pouvez voir que des zones avec des fonctionnalités autonomes
commencent à émerger, celles avec des interfaces uniformes peuvent être
communiquées, il est temps d'externaliser ce code source et de l'intégrer en
tant que module. Cela s'applique encore plus lorsque vous commencez à
copier le code source dans votre application, ce qui est un signe certain que
le code source copié est une fonctionnalité que vous pouvez réutiliser sous
la même forme ou au moins sous une forme similaire. Vous devez ensuite
procéder à l'externalisation du code source dans des fonctions ou des classes
et ceux-ci à l'entrée verwenden.Als dans ce sujet vous servir un exemple
simple. La tâche consiste à créer un outil de ligne de commande auquel
deux nombres peuvent être passés. Le but est maintenant d'interpréter ces
deux nombres comme le nombre de secondes chacun et de calculer la
différence entre les deux valeurs. Jusqu'à présent, cette tâche ne devrait pas
vous poser de problèmes majeurs. Pour aggraver les choses, cependant, les
valeurs d'entrée et la différence de format »HH: MM: SS« doivent être
sorties sur la sortie standard. Commencez par la sortie formatée d'une
option de l'outil de ligne de commande. Le Listing 4.36 vous montre
comment passer de la lecture du paramètre à la sortie terminée.
var util = require ('util'),
numSecs = process.argv [2],
hours = Math.floor (numSecs / 3600),
minutes = Math.floor ((numSecs - (hours * 3600)) / 60),
seconds = numSecs - (hours * 3600) - (minutes * 60);
if ( ('' + hours) .length === 1) {
hours = '0' + hours;
}
if ( ('' + minutes) .length === 1) {
minutes = '0' + minutes;
}
if ( ('' + seconds) .length === 1) {
seconds = '0' + seconds;
}
util.puts ("From:" + hours + ':' + minutes + ':' + seconds);
Le script de Listing se compose en fait de trois parties: dans la première,
vous lisez les données et les convertissez, dans la seconde, vous les
formatez et dans la troisième, vous les sortez enfin. Dans la section
suivante, vous examinerez brièvement les trois parties en détail.
Développez ensuite le code afin que les parties restantes de la tâche
puissent également être remplies. Le premier bloc de code de l'application
initialise toutes les variables requises pour l'application. Cela inclut
principalement l'intégration du module Util , dont vous aurez besoin plus
tard pour la sortie. De plus, la première option transmise au script sur la
ligne de commande est lue et transmise à la variable numSecs . Cette
variable constitue également la base du calcul des heures, minutes et
secondes à sortir ultérieurement. Pour que la sortie soit exécutée comme
vous le souhaitez, assurez-vous dans le bloc suivant que toutes les valeurs
de longueur 1 , c'est-à-dire constituées d'un seul nombre, sont précédées
d'un 0 . Enfin, la dernière ligne utilise la méthode util.puts pour s'assurer
que la chaîne est sortie dans le format correct. Si vous souhaitez intégrer le
deuxième numéro dans votre application, vous pouvez copier l'intégralité
du bloc de code, ajuster l'option à lire et la sortie au lieu de De: une sortie
jusqu'à: et la deuxième partie des exigences serait terminée . Pour la
troisième sous-tâche, le calcul et la sortie de la différence, tout ce que vous
avez à faire est de soustraire la deuxième option de ligne de commande du
script de la première, de copier à nouveau les blocs de code correspondants
et d'adapter à nouveau l'étiquette, et la tâche serait alors terminé. Comment
procéderiez-vous dans ce cas, cependant, si vous utilisiez un trait d'union au
lieu d'un deux-points pour séparer les heures, les minutes et les secondes?
Dans un tel cas, vous devrez effectuer exactement les mêmes opérations à
trois endroits différents dans le code. Cela signifie que la maintenabilité et
l'évolutivité sont considérablement limitées dans une application aussi
petite si le code source n'est pas externalisé et réutilisé plusieurs fois. Dans
l'étape suivante, essayez d'optimiser le code source d'une part pour la plus
grande réutilisabilité possible des pièces individuelles et d'autre part pour
répondre à toutes les exigences. Les fonctions peuvent être utilisées pour
séparer les différentes zones de l'application. En utilisant des arguments, il
est également possible de rendre les fonctions plus configurables. Une autre
optimisation
consiste à encapsuler les trois parties dans une seule classe. Le but est
maintenant de créer une structure dans laquelle un nombre est passé au
constructeur et la méthode toString est appelée après l'instance résultante,
qui renvoie une chaîne formatée.
var SecondsFormatter = function (numSeconds) {
this.numSecs = numSeconds;
};

montre le constructeur de votre nouvelle classe. Il reçoit le nombre de


secondes à formater et enregistre la valeur dans la propriété numSecs à cet
effet . À l'étape suivante, séparez les données d'entrée en parties
individuelles et renvoyez-les sous forme de tableau.
SecondsFormatter.prototype.calculateParts = function (numSecs) {
var num = parseInt (numSecs);
var result = [];
result [ 0] = Math.floor (num / 3600),
result [ 1] = Math.floor ((num - (result [0] * 3600)) / 60),
result [ 2] = num - (result [0] * 3600) - (result [1] * 60);
return result;
}

La méthode CalculateParts du Listing 4.38 prend soin de diviser un nombre


de secondes en heures, minutes et secondes. La fonction reçoit cette valeur
comme argument. Au début, cette valeur est convertie en un entier, qui peut
être utilisé dans le cours ultérieur. La décomposition en composants
individuels est effectuée de manière analogue au premier exemple, sauf que
les valeurs individuelles ne sont pas stockées dans des variables séparées,
mais dans un tableau, car la jonction des composants individuels est
considérablement simplifiée en utilisant la méthode de jointure de le
tableau. L'étape suivante consiste à s'assurer que la mise en forme des
nombres individuels répond aux exigences. Cela signifie que les nombres à
un chiffre doivent être précédés d'un 0 et que des chaînes sont donc créées
à partir des nombres transférés.
. var util = require ('util');
SecondsFormatter.prototype.padParts = function (parts) {
if (! util .isArray (parts) && parts.length! == 3) {
throw new error ( 'Not a valid parts Array!');
}
for (var i = 0; i < parts.length ; i ++) {
if ( ('' + parts [i]). length === 1) {
parts [i] = '0' + parts [i];
}
}
return parts;
}

Dans la liste, vous pouvez voir la méthode padParts . En argument, il reçoit


un tableau composé de trois éléments. Vérifiez ces exigences au début de la
méthode. Pour cela, il est nécessaire d'intégrer le module utilitaire , car cela
vous donne la possibilité de tester le type avec la méthode isArray . Si les
conditions ne sont pas remplies, renvoyez une erreur. Si le test est réussi,
parcourez les différentes parties de la méthode et, si le nombre doit être un
chiffre, mettez un 0 devant. La valeur de retour, comme la première
méthode, est un tableau de trois éléments. Une fois les deux premières
parties de la tâche terminées, vous pouvez maintenant vous concentrer sur
la troisième et dernière partie: renvoyer la valeur calculée. Ici, vous écrasez
la méthode toString qui hérite de chaque objet de l' objet Function sous-
jacent . Par défaut, cette méthode garantit qu'une chaîne est renvoyée qui
représente l'objet actuel. Dans votre cas, ce serait la chaîne HH: MM: SS ,
constituée des valeurs calculées.
SecondsFormatter.prototype.toString = function () {
var parts = this.calculateParts (this.numSecs),
parts = this.padParts (parts);
return parts.join (':');
}

La méthode toString du Listing 4:40 ne prend aucun argument, car elle fera
en sorte que la propriété Wertaus numSecs lit l'objet. En interne, la méthode
toString appelle d'abord la méthode CalculateParts et transmet la valeur de
retour reçue à la méthode padParts . Le résultat est finalement joint et
renvoyé à l'aide de la méthode join avec les deux points comme séparateur.
Maintenant que vous assemblez les différentes parties, vous obtenez une
classe à l'aide de laquelle il est possible de générer une chaîne de caractères
formatée à partir d'un certain nombre de secondes. Une fois que vous avez
implémenté la classe SecondsFormatter , il n'y a que quelques lignes de
code entre vous et la solution de la tâche.

if ( process.argv .length! == 4) {
throw new error ( 'Usage: node tracker.js <from> <to>');
}

var from = new SecondsFormatter ( process.argv [2]),


to = new SecondsFormatter ( process.argv [3]),
diff = new SecondsFormatter ( process.argv [3] - process.argv [2]);
util.puts ("From:" + from.toString ());
util.puts ("Until:" + to.toString ());
util.puts ("Difference:" + diff.toString ());

Le Listing 4.41 montre les dernières étapes requises pour compléter la


candidature. Dans la première étape, vous utilisez l' objet de processus pour
vérifier si l'application dispose des options nécessaires. Dans ce cas,
l'utilisateur doit spécifier deux valeurs, une valeur de début et une valeur de
fin. Vous utilisez ensuite ces valeurs pour créer trois objets
SecondsFormatter , un avec la valeur de début, un avec la valeur de fin et
un avec la différence. La dernière étape consiste à sortir les trois éléments
d' informations en utilisant une combinaison de util.puts et la toString
méthode des objets. Si les exigences changent, il vous est facile d'adapter
l'application en conséquence. Si le résultat doit maintenant être sorti sous la
forme »HH-MM-SS« au lieu de dans le format »HH: MM: SS«, c'est-à-dire
avec des tirets au lieu de deux-points, vous pouvez le faire en changeant un
caractère dans le code source . Cependant, il existe également la possibilité
de paramétrer la méthode toString et de rendre ainsi le séparateur
configurable. Le Listing 4.42 montre les ajustements nécessaires à la
méthode toString .
SecondsFormatter.prototype.toString = function (glue) {
var parts = this.calculateParts (this.numSecs),
parts = this.padParts (parts);
colle = colle || ':';
return parts.join (colle);
}
Dans l'exemple présenté, vous aborderez de plus près la structuration des
applications et les possibilités que la plateforme Node.js vous offre dans ce
contexte.

Propres modules dans Node.js


Si les applications deviennent plus étendues, il est conseillé de structurer le
code source en unités logiques et de les stocker dans des fichiers séparés.
Une telle procédure rend le caractère modulaire d'une application plus clair
et le couplage des pièces individuelles plus lâche. L'objectif est de refléter
les différentes parties de l'application afin que le code puisse non seulement
être utilisé dans une seule application, mais que la solution du problème soit
si universelle que vous pouvez la réutiliser dans d'autres projets. Cela
s'applique moins aux solutions spéciales spécifiques à l'application qu'aux
solutions pour des tâches plus générales. Les développeurs de la plateforme
Node.js ont développé le module Modules précisément pour ce problème.
À la base, il s'agit du chargeur de module de Node.js. Un module est une
unité logique relativement autonome qui peut être utilisée dans le cadre
d'une application. Les modules sont stockés dans des fichiers séparés et
fournissent leurs fonctionnalités via des interfaces. En pratique, cela signifie
que les modules sont principalement des classes ou des objets qui sont
intégrés dans une application. Les modules fournis par Node.js dans le
cadre de la plate-forme en fournissent un bon exemple. Ils fonctionnent sur
le même principe et sont représentés dans les deux variantes avec la classe
Buffer ou l' objet util . Pour l'exemple, cela signifie que vous pouvez
enregistrer la classe SecondsFormatter dans un fichier séparé et l'intégrer
en tant que module. Tout ce que vous avez à faire est de déplacer l'
instruction require , le constructeur et toutes les méthodes ajoutées au
prototype dans un fichier séparé. Cependant, le module ne fonctionne pas
uniquement avec cela. Quelques modifications supplémentaires sont
nécessaires pour cela. Vous verrez la base de ces changements dans les
sections suivantes.

Le module Modules
Les deux composants les plus importants du module Modules , à savoir le
chargeur de module de Node.js, sont d'une part l' objet exports , que vous
utilisez pour publier les modules, et d'autre part la méthode require , avec
laquelle vous pouvez intégrer le module. En plus de ces deux
fonctionnalités de base, ce module vous offre un certain nombre d'autres
fonctionnalités qui peuvent être très utiles dans le développement et le
fonctionnement des modules. Pour cela, la plateforme Node.js vous fournit
l' objet module globalement, vous n'avez donc pas à le rendre disponible
via la méthode require . Dans un module, vous pouvez accéder à un certain
nombre de propriétés du module Module, avec lesquelles vous pouvez
interroger diverses informations sur le module actuel. Tout d'abord appelé
les propriétés module.id et module.filename . Ces deux propriétés
indiquent généralement le nom de fichier absolu du module. Si vous
souhaitez construire sur ces informations, vous devez utiliser la deuxième
option pour module.filename . La propriété module.id contient la valeur »
. «Si vous y accédez en dehors d'un module, par exemple dans le fichier
principal de votre application. Vous pouvez également accéder à ces deux
propriétés de l' objet module dans Node.js REPL. Dans ce cas, la propriété
id a la valeur repl et le nom de fichier se compose du chemin actuel et a le
nom de fichier repl. Vous pouvez utiliser la propriété chargée de l' objet
module pour savoir si le module actuel est déjà chargé. Dans ce cas, la
valeur est vraie . Si le module actuel n'a pas encore été chargé ou est
toujours en cours de chargement, la valeur de cette propriété est false. Si
une application Node.js est lancée, la propriété require.main est
automatiquement renseignée avec l' objet module du fichier d'entrée. Cela
signifie que vous pouvez accéder au nom de fichier du fichier, qui sert de
point d'entrée à votre application, dans chaque module via require.main
.filename . Le module modules s'arrête à côté de cette information, les
données sur le front des rela-relations entre les modules, de sorte que le
module par lequel les autres nous re-dener a été chargé ou quels modules à
travers un module particulier. La propriété parent de l' objet module vous
fournit des informations sur le module qui a chargé le module actuel. Ces
informations se présentent sous la forme d'un objet module . Cela signifie
que, entre autres, vous avez accès aux propriétés d' id ou de nom de
fichier du module parent . La propriété children contient un tableau de
modules que le module actuel doit charger. Cependant, cela ne s'applique
qu'à vos propres modules. Les modules fournis par la plate-forme Node.js
elle-même ne sont pas répertoriés dans le tableau des enfants . Les objets
de cette structure de données ont la même structure que l' objet parent .
Le chargeur de module
Les modules sont intégrés en utilisant la méthode requise . Pour cela,
comme vous pouvez le voir dans l'exemple du Listing 4.44, vous passez le
nom du fichier qui contient le code source du module à charger. Vous
pouvez spécifier le nom du fichier à la fois de manière absolue et relative au
fichier actuel.
$ ls / srv / node / wordCount
WordCount.js app.js

Supposons que vous ayez une structure de répertoires comme le montre le


Listing 4.45, c'est à dire les deux fichiers WordCount.js, qui contient le
code du module, et app.js, le point d'entrée de l'application. Vous pouvez
démarrer l'application avec la commande nodeapp.js . Vous pouvez
démarrer le module soit via require ('./ Word-Count.js') comme dans le
Listing 4.44 soit avec le chemin absolu, c'est- à- dire en utilisant require
('/ srv / node / wordCount / WordCount.js') . Si vous souhaitez exécuter
votre application indépendamment de votre structure de répertoires actuelle,
vous devez choisir la spécification relative des modules. Cela vous permet
de faire fonctionner l'application sur d'autres systèmes ou de la mettre à
disposition d'autres personnes.

node_modules
Donne envie de charger le module, ni / ni . / à l' avance, le chargeur de
module charge soit un module interne de la plateforme Node.js, soit
recherche dans le répertoire node_modules un module avec le nom
correspondant. Le lanceur de module lance la recherche dans le répertoire
node_modules du répertoire courant. Si le module n'y est pas trouvé, une
tentative est faite un niveau supérieur pour trouver le module. Dans la
structure de répertoires du Listing 4.45, cela signifie que le répertoire / srv /
node / wordCount / node_modules est recherché en premier, puis dans / srv
/ node / node_modules et ainsi de suite jusqu'à ce que le chargeur de
module arrive dans le répertoire racine. Si le module n'est pas trouvé dans
cette structure de répertoires, le chargeur de module recherche dans les
répertoires spécifiés dans la variable d'environnement NODE_PATH . De
plus, les répertoires <home> /.node _modules, <home> /.node_libraries et
<install-prefix> / lib / node sont recherchés. Lors du chargement de
modules à l'aide de la méthode require , le chargeur de module recherche
non seulement le fichier spécifié, mais également le nom du fichier si
aucune extension de fichier n'est spécifiée et ajoute les extensions .js, .json
et .node. Ce type de recherche de modules vous permet d'installer
différentes versions de modules Node.js sur votre système et de contrôler la
version que le chargeur de module doit charger en plaçant les modules
respectifs. De cette manière, vous pouvez éviter les conflits de version qui
résultent du fait qu'une autre application ou bibliothèque nécessite une
version différente d'un module. Selon l'endroit où vous enregistrez les
modules, vous pouvez influencer la vitesse du processus de chargement.
Les modules qui sont stockés dans le répertoire local node_modules sont
chargés le plus rapidement car un processus de recherche fastidieux est
évité. La liste suivante résume brièvement les répertoires dans lesquels les
modules sont recherchés dans l'exemple ./srv/node/wordCount/
node_modules / srv / node / node_modules / srv / node_modules /
node_modules / home / sspringer / .node_modules / home / sspringer /.
node_libraries / usr / local / lib / node_modules La variable
d'environnement NODE_PATH est vide sur ce système, donc aucun chemin
supplémentaire n'est ajouté. Avec le chargeur de modules de Node.js, il
existe un autre moyen d'intégrer des modules dans votre application. Au
lieu du nom d'un module, vous pouvez également spécifier un répertoire
entier. La raison en est que les bibliothèques sont souvent stockées dans
leurs propres structures de répertoires. Il existe une convention de
dénomination définie pour ces modules, la façon dont les fichiers doivent
être nommés afin que le chargeur de module puisse trouver le code source
et l'intégrer correctement. Si vous donnez au chargeur de module un
répertoire au lieu d'un nom de fichier, la première étape consiste à essayer le
fichier avec le nom package. pour trouver json. Vous rencontrerez à
nouveau ce fichier au cours de ce chapitre en ce qui concerne le Package
Manager de la plateforme Node.js et ses modules. Beaucoup de choses
doivent être dites à l'avance ici: Ce fichier concerne la configuration et la
description interne des modules. Vous pouvez utiliser ce fichier pour faire
référence au point d'entrée d'un module dans un répertoire. Pour illustrer ce
cas, adaptez un peu l'exemple avec le compteur de mots. Vous devez
d'abord créer un répertoire appelé WordCount. Celui-ci contiendra plus tard
votre module. Copiez ensuite le fichier WordCount.js, qui contient le code
source du module, dans un sous-répertoire lib de ce répertoire. Créez
ensuite un fichier appelé package.json dans le répertoire WordCount. Le
contenu de ce fichier correspond au code source de Listing.

{
"nom": "WordCount", "main": "./lib/WordCount.js"
}
Vous devez effectuer le dernier ajustement dans app.js, c'est-à-dire dans le
point d'entrée de l'application. Il ne vous reste plus qu'à vous assurer que le
module WordCount est intégré à l'aide de la commande varstats = require
('./ WordCount') . Si vous spécifiez un répertoire lorsque vous souhaitez
charger un module et qu'il n'a pas de fichier package.json, le chargeur de
module recherche alternativement les fichiers index.js et index.node comme
point d'entrée dans le module. Au sein de votre application, vous avez la
possibilité non seulement de charger un module une fois au début d'un
fichier de code source ou seulement dans un seul fichier, mais vous pouvez
le charger aussi souvent que vous le souhaitez et à divers endroits, et donc
plusieurs fois. Pour que ces modules n'aient pas à être lus plusieurs fois, le
chargeur de module effectue une optimisation en mettant en cache le
module. Cela signifie que le module n'a besoin d'être chargé et exécuté que
la première fois. Les appels restants à demander avec le nom du module
sont ensuite servis à partir du cache. La conséquence de cette fonctionnalité
est que le code source n'est exécuté que sur le premier require . Si vous
souhaitez obtenir un effet secondaire à chaque appel, vous devez le forcer
via des fonctions. Dans le Listing 4.47 et le Listing 4.48, vous pouvez voir
comment ce comportement peut être simulé.
myModule.js
console.log ('monModule appelé');
app.js
require ('./ myModule.js');
require ('./ myModule.js');

La fonctionnalité requise
Le chargeur de module de Node.js est relativement simple. Néanmoins, il
peut être difficile de suivre les applications avec de nombreux modules. La
gestion de différentes versions de certains modules sur un système est
également difficile. Le mécanisme de mise en cache du chargeur de module
peut également être un problème. En plus des fonctionnalités du système de
modules Node.js présentées jusqu'à présent, il existe d'autres fonctionnalités
qui peuvent faciliter votre manipulation des modules. Avec la méthode de
résolution de l' objet require , vous pouvez trouver dans quel fichier se
trouve un module particulier. Pour cela, il vous suffit de donner à la
méthode les informations sur le module que vous voulez charger. Le
schéma de dénomination est le même que celui utilisé dans les opérations
de chargement normales. La méthode de résolution effectue également les
mêmes opérations de recherche que l' exigence réelle , à la différence que
le module n'est pas chargé, mais que le chemin absolu du fichier dans lequel
se trouve le module est renvoyé sous forme de chaîne. Pour les modules
internes, résoudre ne renvoie que le nom du module. Cette fonctionnalité
n'est pas seulement disponible dans les applications, mais également dans
Node.js REPL. Vous avez déjà appris à connaître le cache du module de
Node.js. L' objet require vous fournit avec l' objet cache un moyen de lire
et de modifier ce cache. La propriété cache de l' objet require est une carte
de hachage, c'est-à-dire un objet JavaScript dans lequel les données sont
stockées à l'aide d'un magasin clé-valeur. Les clés sont constituées des noms
de fichiers absolus des modules respectifs, la valeur est l' objet module du
module. L' objet cache vous offre la possibilité de vérifier si un module a
déjà été chargé dans votre application. Un point important à noter,
cependant, est qu'aucun module Node.js interne n'est répertorié dans le
cache. Dans l'exemple du cache de module dans Listing, vous avez vu qu'un
module n'est évalué qu'une seule fois et est exploité à partir du cache la
deuxième fois. Vous pouvez utiliser l' objet cache pour influencer ce
comportement.
require ('./ myModule.js');
supprimer (require.cache [require.resolve ('./ myModule.js')]);
require ('./ myModule.js');

Si vous supprimez l'entrée de cache pour le module après le premier appel


require , comme on peut le voir dans la liste, le module est complètement
supprimé du cache, ce qui signifie qu'il sera rechargé et évalué la prochaine
fois qu'il sera appelé, et un un effet secondaire possible qui doit être obtenu
par le module se produit à nouveau. Non seulement le cache, mais aussi la
façon dont Node.js charge les modules que vous intégrez via require
peuvent être influencés. Le module require a la propriété extensions à cet
effet. La valeur est un objet dans lequel les clés sont constituées de
différentes extensions de fichier et les valeurs associées sont constituées des
fonctions utilisées pour charger les fichiers avec les extensions
correspondantes. Si vous souhaitez ajouter la prise en charge d'une autre
extension de fichier , tout ce que vous avez à faire est d'ajouter une clé à l'
objet extensions qui porte le nom de l'extension de fichier et d'ajouter une
fonction responsable du chargement des fichiers. Le moyen le plus simple
de le faire est d'utiliser simplement l'une des fonctions existantes. Dans la
section suivante, vous implémenterez une application un peu plus étendue
dans laquelle vous pourrez découvrir les différents aspects de Node.js en
action.

L'application de suivi du temps


La tâche consiste à implémenter un chronomètre. Le but de cette
application est de permettre à un utilisateur d'enregistrer le début et la fin de
son temps de travail sur la ligne de commande, et également d'indiquer le
travail qu'il a effectué pendant ce temps. Le Listing 4.52 montre comment
l'application peut être utilisée.
$ node index.js start 'Implémentation de l'application Timetracker'
$ node index.js fin
Statistiques $ node index.js 11.2012

Vous pouvez utiliser la ligne de commande pour spécifier à la fois le début


et la fin d'une tâche. Ces informations sont enregistrées dans un fichier
texte. Sur la base des données du fichier texte, vous pouvez générer des
statistiques mensuelles. L'application fonctionne en fournissant à un
utilisateur des données qui sont traitées au cours de l'application.
L'interaction avec l'application se fait via des options transmises sur la ligne
de commande. Cela signifie que c'est le premier point de départ pour
l'implémentation pour vous. Dans la liste, vous pouvez voir le code source,
ce qui garantit que les options sont lues correctement et enregistrées dans
une structure d'objet.

var in_array = function (aiguille, botte de foin) {


pour (var i = 0; i <haystack.length; i ++) {
if (meule de foin [i] === aiguille) {
retourne vrai;
}
}
retourner faux;
}
var availableModes = ['début', 'fin', 'statistiques'];
exports.getData = function () {
var result = {}, mode = process.argv [2];
if (in_ array (mode, availableModes)) {
résultat ['mode'] = mode;
}
autre {
throw new Error ('Modes disponibles:' + availableModes.join (','));
}
commutateur (mode) {
cas 'début':
if (process.argv .length <4) {
throw new Error ('Veuillez entrer votre tâche.');
}
résultat ['tâche'] = process.argv [3];
Pause;
cas 'statistiques':
if (process.argv .length <4) {
throw new Error ('Veuillez spécifier la période.');
}
result ['period'] = process.argv [3];
Pause;
}
résultat de retour;
}

Vous avez besoin de deux conditions pour terminer la tâche. D'une part,
vous implémentez la fonction in_array , qui vérifie si une valeur est
présente dans un tableau, d'autre part, un tableau avec des valeurs valides
pour les différents modes de l'application. Le cœur de ce module est
constitué d'une fonction que vous exportez dans la propriété
exports.getData et rendez ainsi disponible. Pour accéder aux différentes
options, utilisez l' objet process et plus particulièrement la propriété argv .
Les options individuelles sont validées selon certaines règles. Ainsi, un
utilisateur ne peut choisir que l'un des trois modes. Avec le démarrage de
l'état et les statistiques , d'autres options sont également importées. Vous
enregistrez les résultats dans un objet qui est renvoyé à la fin de la fonction.
L'étape suivante consiste à intégrer le module, comme vous pouvez le voir
dans l'extrait 4.54, dans le fichier index.js, le point d'entrée central de
l'application.
var getData = require ('./ lib / getData.js');
console.log (getData.getData ());

NPM
Le Node Package Manager, ou NPM en abrégé, vous offre, en tant que
développeur d'applications JavaScript côté serveur basées sur la plate-forme
Node.js, un moyen de créer des modules et de les mettre à la disposition
d'autres développeurs. Vous pouvez également utiliser les modules
développés par d'autres programmeurs dans votre application. Le site Web
du NPM est https://npmjs.org/. En plus de diverses ressources telles que des
listes de modules, vous trouverez également une documentation détaillée du
NPM et toutes les options disponibles. Le NPM a été développé à l'origine
par Isaac Schlueter indépendamment de la plate-forme Node.js; depuis la
version 0.6.3 de Node.js, le NPM a été intégré directement dans la
plateforme et n'a plus besoin d'être installé. Cela signifie que vous pouvez
soit installer le programme d'installation .msi sous Windows, le package
.pkg sous Mac OS X ou le package binaire sous Linux, puis utiliser
immédiatement le NPM. Le NPM est utilisé sur la ligne de commande et
contrôlé via diverses options.

Le gestionnaire de packages de nœuds est un gestionnaire de packages


complet pour la plate-forme Node.js. Vous pouvez l'utiliser pour rechercher,
installer, mettre à jour et supprimer des packages. Les modules Node
Packaged servent à étendre les fonctionnalités de la plate-forme Node.js.
Cela signifie qu'ils ajoutent le moteur V8 et les modules internes de Node.js
au cœur de la plate-forme Node.js. Les packages NPM sont gérés de
manière centralisée sur le serveur à l'adresse http://registry.npmjs.org/. Si
vous accédez à cette adresse depuis votre navigateur, vous ne recevrez que
des structures de données au format JSON. La racine du serveur fournit des
informations générales sur le référentiel, telles que le nombre de modules.
Une liste détaillée des modules peut être trouvée à
http://registry.npmjs.org/-/all. Cette page contient également une structure
de données JSON. Joyent, la société qui prend en charge Node.js, maintient
une liste des modules les plus importants sur le compte github de
l'entreprise. Vous pouvez trouver cette liste sur
https://github.com/joyent/node/wiki/Modules. Si, par exemple, vous avez
besoin d'un analyseur XML pour votre application, vous trouverez l'élément
Analyseurs et XML et vous y recevrez une liste d'analyseurs que vous
pouvez installer via le NPM. Afin de prendre une meilleure décision, vous
recevrez une brève description dans la liste et un lien vers la page du projet
du module respectif.

Trouver des packages


En avril 2013, il y avait déjà plus de 28 000 packages dans le référentiel. En
raison de ce grand nombre, il est difficile de garder une vue d'ensemble. Si
vous connaissez les fonctionnalités dont vous avez besoin dans votre
application, vous pouvez rechercher des packages spécifiques. Un point de
contact est la liste déjà mentionnée des modules dans le wiki github de
Joyent. Une autre option consiste à effectuer une recherche à l'aide de l'outil
de ligne de commande npm lui-même. Vous pouvez utiliser la recherche
option pour rechercher le référentiel. Les champs Nom , Description ,
Auteur et Mots clés sont disponibles pour la recherche. En supposant que
vous souhaitiez intégrer un analyseur XML dans votre application et que
vous ne sachiez pas exactement quel est le module à installer, vous pouvez
rechercher celui-ci dans le référentiel. Le Listing 4.66 montre la commande
et sa sortie.
analyseur XML de recherche $ npm
npm http GET https://registry.npmjs.org/-/all/since?sta ...
npm http 200 https://registry.npmjs.org/-/all/since?sta ...
NOM DESCRIPTION AUTEUR DATE MOTS-CLÉS
big-xml Analyseur XML léger ... = jahewson 03/04/2012 22:23
La commande npmsearch accède directement aux informations du
référentiel et aux structures de données JSON afin d'afficher les
informations recherchées. La sortie de la commande se compose du nom du
module, de la brève description, de l'auteur du module, de la date de la
dernière mise à jour et des mots-clés définis par le créateur du module.

Installer des packages


Une fois que vous avez trouvé le package et connu son nom, vous pouvez
maintenant l'installer sur votre système à l'étape suivante. Pour ce faire,
utilisez la commande npminstall et ajoutez le nom du package. En
supposant que vous souhaitiez installer la bibliothèque Underscore.js dans
votre application, vous pouvez le faire avec la commande
npminstallunderscore . Vous pouvez voir la sortie correspondante dans la
liste.
$ npm install underscorenpm http GET
https://registry.npmjs.org/underscorenpm http 200
https://registry.npmjs.org/underscorenpm http GET
https://registry.npmjs.org/underscore/- /underscore-1.4. 2.tgznpm http 200
https://registry.npmjs.org/underscore/-/underscore-1.4.2.tgz
underscore@1.4.2 node_modules / underscore

La commande npminstall interroge d' abord le registre pour obtenir des


informations sur le package souhaité. Comme vous pouvez le voir dans
l'extrait 4.67, la requête consiste en une requête GET normale, que vous
pouvez également émettre depuis votre navigateur. Ouvrez l'URL spécifiée
dans votre navigateur, vous verrez que le document est une structure de
données JSON qui contient un certain nombre d'informations sur le
package. Entre autres choses, dans la dernière section, vous trouverez des
informations sur la version actuelle du module, y compris l'URL du
package lui-même. Le package est disponible sur le serveur en tant
qu'archive tar compressée. Avec un autre reuqest GET, le NPM télécharge
cette archive et l'installe sur votre ordinateur. L'installation des modules via
le NPM a lieu sans autre entrée de ligne de commande localement dans le
répertoire dans lequel vous vous trouvez actuellement dans votre shell. Pour
vous, cela signifie que vous n'avez pas besoin de droits d'administrateur
pour installer les modules localement. L'archive tar téléchargée est extraite
dans le répertoire node_modules. Vous trouverez ici un sous-répertoire pour
chaque package avec le nom du package respectif. Dans le cas de l'exemple,
le répertoire node_modules a été créé car il n'existait pas encore. Un sous-
répertoire de soulignement y a été créé, qui à son tour contient les fichiers
du module. Cependant, Node Package Manager se charge non seulement du
téléchargement et de l'installation des modules, mais est également capable
de résoudre les dépendances de modules. Dans ce cas, les dépendances sont
des modules dont un package a besoin pour fonctionner. Vous pouvez voir
un exemple de ceci avec le module mysql dans l'extrait 4.68. Le module
mysql vous fournit un client pour la base de données MySQL, à l'aide
duquel vous pouvez envoyer des requêtes à une base de données et gérer les
résultats dans votre application.
$ npm install mysqlnpm http GET https://registry.npmjs.org/mysqlnpm http
200 https://registry.npmjs.org/mysqlnpm http GET
https://registry.npmjs.org/mysql/-/mysql-2.0. 0-alpha4.tgznpm http 200
https://registry.npmjs.org/mysql/-/mysql-2.0.0-alpha4.tgznpm http GET
https://registry.npmjs.org/require-all/0.0.3npm http 200
https://registry.npmjs.org/require-all/0.0.3npm http GET
https://registry.npmjs.org/require-all/-/require-all-0.0.3.tgznpm http 200
https: / /registry.npmjs.org/require-all/-/require-all-0.0.3.tgzmysql@2.0.0-
alpha4 node_modules/mysqlrequire-all@0.0.3

Lors de l'installation, vous verrez que le NPM télécharge non seulement le


module mysql , mais également un autre module appelé require-all . Cela
fournit au module mysql un moyen de charger tous les fichiers d'un
répertoire. Si vous installez différents modules sur votre système, il peut y
avoir des conflits de version entre les dépendances des différents modules.
Pour cette raison, les dépendances d'un module au sein du module sont
résolues. Cela signifie dans ce cas pour le module mysql que, à son tour, un
répertoire node_modules est créé dans le répertoire mysql qui contient le
code source du module dans lequel se trouvent alors les modules sur
lesquels le module mysql se construit. De cette manière, les conflits de
version sont fondamentalement évités. Cependant, cela a le prix que les
mêmes modules peuvent être trouvés plusieurs fois sur votre système de
fichiers. En résumé, cela signifie que vous n'avez pas à vous soucier de la
résolution des dépendances, du téléchargement manuel des packages ou du
déballage et de l'installation des modules lors de l'utilisation de NPM. Le
gestionnaire de packages prend en charge toutes ces tâches pour vous. En
plus de l'installation locale dans le répertoire courant, il existe une autre
variante d'installation des modules. Vous pouvez également installer un
module Node.js à l'échelle du système afin qu'il soit disponible non
seulement pour vous dans votre projet actuel, mais pour tous les utilisateurs
et projets sur l'ordinateur. Vous pouvez installer un module globalement en
spécifiant l'option de ligne de commande -g , pour global, dans la
commande d'installation. La liste montre un exemple d'installation globale.

$ sudo npm install -g grunt-cliPassword: npm http GET https://registry.npmjs.org/grunt-clinpm http


200 https://registry.npmjs.org/grunt-clinpm http GET https: //registry.npmjs .org / resolvenpm http
GET https://registry.npmjs.org/noptnpm http GET https://registry.npmjs.org/findup-syncnpm http
200 https://registry.npmjs.org/findup-syncnpm http 200 https : //registry.npmjs.org/resolvenpm http
GET https://registry.npmjs.org/resolve/-/resolve-0.3.1.tgznpm http 200
https://registry.npmjs.org/noptnpm http 200 https: //registry.npmjs.org/resolve/-/resolve-0.3.1.tgznpm
http GET https://registry.npmjs.org/abbrevnpm http GET https://registry.npmjs.org/globnpm http
GET https: / /registry.npmjs.org/lodashnpm http 200 https://registry.npmjs.org/abbrevnpm http 200
https://registry.npmjs.org/globnpm http 200 https://registry.npmjs.org/lodashnpm http GET https :
//registry.npmjs.org/minimatchnpm http GET https://registry.npmjs.org/graceful-fsnpm http GET
https://registry.npmjs.org/inheritsnpm http 200 https: // reg istry.npmjs.org/inheritsnpm http 200
https://registry.npmjs.org/graceful-fsnpm http 200 https://registry.npmjs.org/minimatchnpm http GET
https: //registry.npmjs. org / minimatch / - /minimatch-0.2.12.tgznpm http 200
https://registry.npmjs.org/minimatch/-/minminatch-0.2.12.tgznpm http GET
https://registry.npmjs.org/sigmundnpm http GET https: // registry.npmjs.org/lru-cachenpm http 200
https://registry.npmjs.org/sigmundnpm http 200 https://registry.npmjs.org/lru-cachenpm http GET
https: // registre. npmjs.org/lru -cache / - / lru-cache- 2.3.0.tgznpm http 200
https://registry.npmjs.org/lru-cache/-/lru-cache-2.3.0.tgz/usr/local / bin / grunt ->
/usr/local/lib/node_modules/grunt-cli/bin/gruntgrunt-cli@0.1.7 /usr/local/lib/node_modules/grunt-
cliresolve@0.3.1nopt@1.0.10 (abréviation @ 1.0.4) findup-sync@0.1.2 (lodash@1.0.1,
glob@3.1.21)

Contrairement à l'installation locale, il y a quelques éléments à prendre en


compte lors de l'installation de modules globaux. En tant qu'utilisateur
normal, vous ne devez pas installer les modules globalement, car ils sont
stockés par défaut sous / usr / local / lib / node_modules. Vous devez donc
soit effectuer l'installation directement en tant qu'administrateur, soit sur les
systèmes UNIX avec la commande sudo . L'installation globale des
modules est principalement destinée aux outils de ligne de commande
implémentés avec Node.js. Les exemples incluent grunt, un outil de
création pour les applications JavaScript, ou lessc, un outil de traduction de
feuilles de style au format LESS. Pour les modules normaux tels que le
soulignement ou mysql , il est recommandé d'installer ces modules
localement. La première raison est que les modules locaux se chargent plus
rapidement car la recherche du module est considérablement raccourcie. La
deuxième raison, non négligeable, est que votre application avec des
modules installés globalement a des dépendances externes. Cela signifie
que ces modules globaux doivent être installés sur chaque système sur
lequel l'application doit être exécutée, sinon l'application ne fonctionnera
pas. Pour cette raison, il est recommandé que tous les modules sur lesquels
IhreApplikation construit s'installent également localement, afin qu'ils
s'exécutent de manière aussi indépendante que possible. Capacity ist.Egal si
vous installez un module localement ou globalement, vous obtiendrez en
sortie de commandes nodeinstall toujours des demandes au npmjs.org, les
réponses respectives du serveur et enfin une liste des packages installés et
de leurs interdépendances. Cependant, vous ne dépendez pas d'une
connexion permanente au serveur lors de l'installation de modules via le
NPM. En plus d'installer les modules via une connexion Internet existante,
vous avez également la possibilité d'installer des modules directement
depuis votre ordinateur. La seule condition à remplir est que vous ayez
téléchargé l'archive tar contenant le module ou que vous disposiez d'un
répertoire sur votre ordinateur contenant le code source du module et un
fichier package.json correspondant. Pour tester l'installation locale, vous
pouvez simplement télécharger le module de soulignement et l'installer. Le
listing 4.70 montre comment procéder.

$ wget http://registry.npmjs.org/underscore/-/underscore-1.4.2.tgz...2012-
11-30 11:27:35 (114 Ko / s) - 'underscore-1.4.2. tgz 'enregistré
[61836/61836] $ npm install underscore-1.4.2.tgzunderscore@1.4.2
node_modules / underscore
L'installation crée un répertoire node_modules, comme avec l'utilisation de
l'entreprise reppmjs.org, dans lequel le code source du module est copié.
Une fois l'installation réussie, vous pouvez utiliser le module dans votre
application.

Afficher les packages installés


Tous les packages que vous installez se trouvent dans le répertoire
node_modules de votre application. Cependant, puisque les dépendances
sont résolues par module, cela devient rapidement déroutant si vous voulez
savoir quels packages sont installés dans votre application. Un aperçu
rapide des modules dieinstallierten et de leurs dépendances propose la
commande npmlist .

$ npm list / tmp / nodemysql @ 2.0.0-alpha4require-all @ 0.0.3underscore


@ 1.4.2

Comme dans la liste peut voir, il est dans la liste des modules de
l'arborescence umeine, vous pouvez lire directement à partir des modules
sindund installés comme des dépendances être définies entre les modules.
Vous obtenez une vue similaire après l'installation d'un module. Cependant,
cela ne contient que le module lui-même et ses dépendances, alors que
npmlist répertorie tous les modules de votre répertoire node_modules
local. L' option -g vous donne également une liste de tous les modules
installés globalement dans votre système à partir du NPM, qui affiche
également toutes les dépendances dans une arborescence.

Utiliser des packages


Comme vous l'avez déjà vu, il existe deux types de modules différents qui
peuvent être installés via le NPM. D'une part, ce sont des collections de
fonctionnalités que vous pouvez intégrer directement dans votre
application, et d'autre part, il existe également des outils que vous pouvez
utiliser directement depuis la ligne de commande. Dans ce qui suit, vous
apprendrez à connaître les représentants des deux catégories. Vous verrez
comment vous pouvez utiliser les modules dans la pratique. Dans la liste,
vous avez déjà installé l'outil de construction JavaScript grunt-cli
globalement sur votre système. De plus, vous devez installer grunt en tant
que module local, après quoi vous pouvez l'utiliser pour créer votre
application ou pour effectuer diverses tâches d'assurance qualité. Pour
exécuter grunt, il vous suffit d'exécuter la commande de ligne de commande
grunt dans un répertoire contenant un fichier de configuration, le fichier dit
grunt. Le fichier de configuration contient les informations sur les
différentes tâches que Grunt est censé effectuer pour l'application. Le nom
de ce fichier est généralement Gruntfile et ment

au format JSON dans le répertoire racine de votre application. La


commande grunt dans ce cas est une application JavaScript normale, dans
laquelle il y a une note dans l'en-tête du fichier pour le système
d'exploitation, le soi-disant shebang, qui indique au shell avec quelle
application le script doit être interprété. Dans le cas de grunt, cette ligne est
#! / Usr / bin / envnode et signifie que le script doit être exécuté avec
Node.js. Avec ces ajustements, une application JavaScript comme grunt
peut être utilisée comme une commande normale sur la ligne de commande
et n'a pas à être transmise en tant que paramètre à Node.js. La deuxième
façon d'utiliser les modules que vous installez via le NPM est d'intégrer
directement la fonctionnalité correspondante dans votre application. Au
cours de cette section, vous avez déjà vu comment installer la bibliothèque
Underscore.js localement dans votre application. Nous allons maintenant
utiliser ce module pour créer un petit exemple d'utilisation de modules.
var _ = require ('underscore'),
arr1 = ['a', 'b', 'c'],
arr2 = ['b', 'c', 'd'];
console.log (_.intersection (arr1, arr2));

Dans la liste, le téléchargement via nécessite le module de soulignement


que vous avez précédemment installé localement avec demNPM. Ensuite,
vous définissez deux tableaux et obtenez leur sortie d'intersection.
Underscore.js vous fournit la fonction d' intersection pour cela. Dans ce
cas, le retour est un tableau avec les éléments b et c. Après cet exemple
d'introduction à l'utilisation de modules que vous pouvez installer avec le
NPM, lancez-vous de manière un peu plus pratique et développez votre
application de suivi du temps. L'un des plus gros problèmes de l'application
est l'écriture et la lecture des données. Vous utilisez actuellement un simple
fichier journal à cette fin. Au total, vous avez lu l'intégralité du fichier
journal et traité le contenu à trois endroits. Cependant, ce type d'accès ne
convient que pour les petits fichiers, dès que vous traitez plus de quelques
lignes dans le fichier journal, les accès deviennent plus lents. La solution la
plus simple à ce problème consiste à utiliser une base de données. Ces
enregistrements peuvent être lus sélectivement et il n'est pas nécessaire de
charger la totalité des données dans un objet de la mémoire de travail. Avec
l'approche modulaire que vous avez suivie lors de la création de cette
application, il est également possible d'utiliser une base de données au lieu
du fichier journal sans avoir à adapter directement l'ensemble de
l'application. Dans ce cas, utilisez la base de données SQL open source
MySQL comme base de données. Cette base de données est également
disponible sur tous les systèmes sur lesquels Node.js fonctionne. Le listing
4.73 vous montre les premières étapes, qui consistent en la création d'une
base de données correspondante et de la table correspondante, nécessaires à
la conversion prévue.
$ mysql -u racine - p
mysql> CRÉER UNE BASE DE DONNÉES `TimeTracker`;
Requête OK, 1 ligne affectée (0,00 s) mysql> use `TimeTracker`; Base de
données modifiée
mysql> CREATE TABLE `times` (` date` DATE, `startTime` TIME,`
endTime` TIME, `diff` TIME,` task` VARCHAR (255));
Requête OK, 0 ligne affectée (0,01 s)

Une fois la base de données créée et une table qui y a été créée, qui a la
même structure que le fichier journal, c'est-à-dire des champs pour la date,
l'heure de début et de fin, la différence entre les deux et un champ de texte
libre pour la tâche , vous pouvez choisir L'étape suivante consiste à
installer le module mysql à l'aide du NPM, ce qui vous donne la possibilité
d'accéder à la base de données depuis votre application Node.js. Pour
installer le module, il vous suffit d'émettre la commande npminstallmysql
dans le répertoire racine de l'application de suivi du temps. Vous avez déjà
vu les différentes étapes de l'installation dans l'extrait 4.68. Comme prévu,
vous devez effectuer les modifications les plus importantes au niveau de l'
enregistrement et de la lecture des données, sur le module persister .
Ensuite, vous convertirez progressivement ce module. Dans le Listing4.74,
vous pouvez voir comment vous pouvez intégrer les modules requis et
comment vous devez adapter la fonction constructeur en conséquence.

var fs = exiger ('fs'),


util = require ('util') mysql = require ('mysql');
var persister = function () {
this.connection = mysql.createConnection ({
hôte: 'localhost',
utilisateur: 'root',
base de données: 'TimeTracker',
mot de passe: ''});
this.connection .connect ();
};

Comme annoncé précédemment, liez maintenant le module persister au


module mysql qui vous offre un client pour la connexion à la base de
données requise. Avec l' objet mysql retourné , le client, vous pouvez
ensuite établir la connexion dans le constructeur. Pour ce faire, vous devez
créer un objet de connexion à l'aide de la méthode createConnection et
transmettre un objet de configuration contenant le serveur, l'utilisateur, la
base de données et le mot de passe. En appelant la méthode de connexion ,
vous établissez une connexion à la base de données. Vous pouvez
maintenant utiliser l' objet de connexion pour envoyer des requêtes au
serveur de base de données.

Persister.prototype.writeStart = fonction (tracker) {


var data = {"date": tracker.date, "startTime": tracker.startTime, "task":
tracker.task},
query = 'INSERT INTO `fois` SET? ';
this.connection .query (requête, données, fonction (err, résultat) {
if (err) {
jeter err;
}
util.puts ('Les données de' + tracker.task + 'ont été sauvegardées.');
this.connection.end ();
}
.bind (this));

La méthode de démarrage d'écriture que vous avez utilisée dans le Time


Tracker a été de créer un nouveau Zeile dans le fichier journal et une
nouvelle entrée. Pour convertir l'application, vous devez changer cette
méthode, comme vous pouvez le voir dans l'extrait 4.75. L'équivalent d'une
ligne dans le fichier journal est un nouvel enregistrement dans la table de la
base de données. Pour ce faire, formulez une requête qui garantit que la
date, l'heure de début et la tâche sont écrites dans la table. Toutes les
opérations de base de données sont effectuées de manière asynchrone. Pour
cette raison, vous devez attribuer à la méthode de requête une fonction de
rappel en plus de la chaîne de caractères contenant la requête et d'un objet
contenant les valeurs de la requête. Ce rappel est exécuté dès que la requête
a été effectuée et qu'il y a un retour. Cette rétroaction peut être positive,
dans ce cas le deuxième argument, result , contient une valeur, sinon un
objet d'erreur est le premier argument. La sortie vers l'utilisateur est la
même que lors de l'utilisation du fichier journal. Un point important à
garder à l'esprit lors de l'utilisation de connexions de base de données est
que vous devez toujours déconnecter une connexion existante. La
connexion est interrompue en appelant la méthode end sur l' objet de
connexion . Ne pas effectuer cette opération, la connexion est maintenue
ouverte, et l'application après avoir écrit l'ensemble de données ne
fonctionne pas homologue beendet.Das du début d'écriture méthode
consiste writeEnd méthode, diedafür assure que la fin des temps et la
différence entre le début et la fin dans denDatensatz écrit devenir.
L'enregistrement de données est identifié par une valeur vide dans le champ
heure de fin . La liste montre l'implémentation complète de la méthode
writeEnd .

Persister.prototype.writeEnd = fonction (tracker) {


var data = {"endTime": tracker.endTime, "diff": tracker.diff},
query = 'UPDATE `times` SET? O `endTime` EST NULL ';
this.connection .query (requête, données, fonction (err, rersult) {
if (err) {throw err};
util.puts ('Les données de' + tracker.task + 'ont été sauvegardées.');
this.connection.end ();
}
.bind (this));
}
Cendres asynchrones dans Node.js
Stabilité: 1-démo

Le module async_hooks fournit une API pour enregistrer les fonctions de rappel qui suivent les
ressources asynchrones créées dans les applications Node.js. Ce module est accessible à l'aide de la
commande suivante:

const async_hooks = require ('async_hooks');


Conventions
Une ressource asynchrone est une entité avec un rappel. Ce rappel peut être appelé plusieurs fois,
comme l'événement 'conection' dans net.createServer (), ou une seule fois, comme fs.open (). Le
fournisseur peut également fermer avant l'appel du rappel. AsyncHook ne différencie pas clairement
ces deux situations différentes, mais les représentera simplement comme une ressource.

Si vous utilisez la classe de travail, chaque thread aura sa propre interface async_hooks et utilisera un
nouvel ensemble d'ID asynchrones.

API générales
coup d'oeil
Le code suivant explique rapidement et complètement les interfaces de programmation générales:
const async_hooks = require ('async_hooks');

// Renvoie l'ID de contenu actuel de l'implémentation


const eid = async_hooks.executionAsyncId ();

// Renvoie l'ID du processeur à appeler et est responsable de


// Appelle le callback pour le domaine d'exécution actuel
const tid = async_hooks.triggerAsyncId ();

// Tous ces rappels sont facultatifs


const asyncHook =
async_hooks.createHook ({init, avant, après, détruire, promiseResolve});

// c'est. Cela n'est pas réellement implicite car AsyncHook permet d'appeler
des rappels de version
// Expire après l'exécution de la fonction albanaise, et doit être explicitement
déclaré pour lancer les réponses de rappel
asyncHook.enable ();

// Désactiver l'utilisation de nouveaux événements asynchrones


asyncHook.disable ();
//
// createHook () Voici les réponses aux appels qui peuvent être transmises à
//

// lors de la création de l'objet. La création de la ressource peut ne pas être


encore terminée lorsque le rappel est exécuté
// Cet asyncId est déjà rempli, donc tous les champs de ressources ne sont pas
référencés avant
function init (asyncId, type, triggerAsyncId, ressource) {}

// N juste avant d'appeler l'appel de ressource. Peut être appelé depuis


// Appelé une seule fois avec TCPWrap, temps avec des processeurs tels que
// demandes FSReqWrap comme
function before (asyncId) {}

// Uniquement après l'appel du fournisseur


function after (asyncId) {}

// AsyncWrap lors de la destruction d'une copie de


function destroy (asyncId) {}

// Lorsque la promesse passe uniquement pour les ressources promiseResolve


est appelée
// constructeur appelé fonction `Promise` to object` resolution`
// Promise (soit directement, soit via d'autres moyens pour interroger l'objet)
function promiseResolve (asyncId) {}

async_hooks.createHook (rappels)

Ajouté dans la version: v8.1.0

callbacks: <Object> Hook Callbacks à enregistrer, et peut contenir l'une des fonctions suivantes:

* init: fonction de rappel <Function> init.


* avant: <Fonction> Fonction de rappel avant.
* après: <Fonction> Fonction de rappel après.
* destroy: <Fonction> La fonction de rappel est une destruction.

Cette fonction renvoie une copie du hook asynchrone AsyncHook utilisé pour désactiver et exécuter
des hooks.

La fonction async_hooks.createHook (callbacks) enregistre les fonctions à appeler à différents


moments d'exécution des événements pour chaque opération asynchrone.

Les appels init (), before (), after () et destroy () sont appelés pour leur événement asynchrone
pendant l'existence de la ressource.

Tous les rappels sont facultatifs. Si, par exemple, vous devez suivre uniquement une analyse des
ressources, la réponse sera détruite. La spécification de toutes les fonctions qui peuvent être passées
aux callbacks se trouve dans la section "Callback Hook", qui sera mentionnée plus tard.

const async_hooks = require ('async_hooks');

const asyncHook = async_hooks.createHook ({


init (asyncId, type, triggerAsyncId, ressource) {},
détruire (asyncId) {}
});

Sachez que le rappel sera hérité par la chaîne prototype:

class MyAsyncCallbacks {
init (asyncId, type, triggerAsyncId, ressource) {}
détruire (asyncId) {}
}

La classe MyAddedCallbacks étend MyAsyncCallbacks {


avant (asyncId) {}
après (asyncId) {}
}

const asyncHook = async_hooks.createHook (new MyAddedCallbacks ());

La gestion des erreurs


Si vous lancez des réponses AsyncHook, l'application exécutera un rapport de trace de pile, puis se
fermera. Le chemin de sortie suit le même chemin que l'exception non interceptée, mais tous les
écouteurs suppriment «uncaughtException» et forcent le processus à le faire à la sortie. Les appels
'exit' sont toujours appelés uniquement si le programme est exécuté avec l'indicateur -abort-on-
uncaught-exception. Dans ce cas, un rapport de trace de pile sera imprimé et l'application se fermera
en laissant le fichier noyau.

La raison derrière le comportement du gestionnaire d'erreurs de cette manière est que ces rappels sont
effectués à des points fréquemment volatils et temporaires pendant l'existence d'un objet, comme lors
de la création et de la suppression d'une classe. En conséquence, il est nécessaire d'arrêter rapidement
ce processus pour éviter toute interruption involontaire à l'avenir. Cela sera sujet à changement si une
analyse approfondie est faite et des exceptions sont faites qui peuvent suivre le chemin de contrôle
normal sans aucun effet secondaire inattendu.

Imprimer dans le rappel AsyncHooks


Parce que l'impression dans le terminal n'est pas synchronisée, console.log () provoquera l'appel du
callback asyncHooks, donc l'utilisation de console.log () ou de toute opération asynchrone similaire
dans la fonction de rappel AsyncHooks provoquera une récursivité sans fin. Une solution simple pour
le débogage est l'utilisation de la journalisation asynchrone comme fs.writeSync (1, msg). Ceci
s'imprimera sur le flux de sortie standard (stdout), représentant 1 dans le descripteur de fichier avec le
flux de sortie standard et n'appellera pas AsyncHooks dans un format récursif car il est synchronisé.

const fs = require ('fs');


const util = require ('util');

debug de fonction (... args) {


// AsyncHooks Utilisez une fonction comme celle-ci lors du débogage dans le
callback
fs.writeSync (1, `$ {util.format (... args)} \ n`);
}
Si vous devez utiliser un processus asynchrone, il est possible de suivre la cause de l'opération
asynchrone en continu en utilisant les informations fournies par AsyncHooks lui-même. Le processus
d'enregistrement lui-même doit être ignoré lorsque le rappel est appelé AsyncHooks. Lorsque cela est
fait, les recoins infinis planteront.

asyncHook.enable ()
Cette fonction renvoie une référence à asyncHook, en effectuant le rappel pour le AsyncHook donné.
Si aucune réponse n'est faite, l'appel à cette fonction n'aura aucun effet.

La version AsyncHook installée est désactivée par défaut. Pour l'activer immédiatement après sa
création, vous pouvez suivre le formulaire suivant:

const async_hooks = require ('async_hooks');


const hook = async_hooks.createHook (rappels) .enable ();
asyncHook.disable ()

Cette fonction renvoie une référence à asyncHook, car les réponses de rappel à la version asyncHook
fournies par le bloc de réponses du pool public asyncHook sont désactivées. Le hook ne sera pas
rappelé en cas de dysfonctionnement jusqu'à ce qu'il le fasse à nouveau.

Pour l'interface de code de cohérence (API), la copie disable () d'AsyncHook renvoie également.

Rappels de hook
Lors de l'occurrence d'événements asynchrones, les événements clés sont regroupés en quatre
sections: pendant la construction, avant d'appeler le rappel, après l'appel du rappel et lors de la
suppression de la copie.

init (asyncId, type, triggerAsyncId, ressource)


asyncId: <number> Le nombre représente un identificateur unique (ID) pour la ressource asynchrone.
type: <chaîne> Une chaîne de texte représentant le type de ressource asynchrone.
triggerAsyncId: <number> Un nombre qui représente un identificateur unique pour la ressource
asynchrone du contexte d'exécution où cette ressource a été créée.
resource: <Object> Objet qui contient une référence à la ressource représentant l'opération
asynchrone, qui est lancée pendant le processus de suppression.
Cette fonction est appelée lorsque vous créez une classe qui peut lancer un événement asynchrone.
Cela ne signifie pas que la copie doit appeler l'appel avant et après avant d'appeler le destroyer, mais
seulement avoir la capacité de le faire.
Ce comportement peut être surveillé en ouvrant une ressource et en la fermant avant qu'elle ne soit
utilisée. Le morceau de code suivant décrit ceci:
require ('net'). createServer () .Listen (function () {this.close ();});
//
clearTimeout (setTimeout () => {}, 10));
Chaque nouvelle ressource attribue un identifiant unique (ID) dans le domaine de copie Node.js
actuel.

Type de paramètre
Le type de paramètre est une chaîne de texte qui définit le type de ressource qui a appelé le rappel
init. En général, il correspondra au nom du générateur de ressources.

FSEVENTWRAP, FSREQWRAP, GETADDRINFOREQWRAP, GETNAMEINFOREQWRAP,


HTTPPARSER,
JSSTREAM, PIPECONNECTWRAP, PIPEWRAP, PROCESSWRAP, QUERYWRAP,
SHUTDOWNWRAP,
SIGNALWRAP, STATWATCHER, TCPCONNECTWRAP, TCPSERVER, TCPWRAP,
TIMERWRAP, TTYWRAP,
UDPSENDWRAP, UDPWRAP, WRITEWRAP, ZLIB, SSLCONNECTION, PBKDF2REQUEST,
RANDOMBYTESREQUEST, TLSWRAP, Timeout, Immediate, TickObject

Il existe également le type de ressource PROMISE, qui est utilisé pour suivre les copies d'objet
Promise et le travail asynchrone planifié par elles.
Les utilisateurs peuvent connaître leur propre type lors de l'utilisation de l'intégration publique (API).

Il est possible d'avoir un conflit de noms de types, il est donc recommandé d'utiliser un préfixe
unique, tel que le nom du package npm, pour éviter tout conflit lors de l'écoute des hooks.

Le paramètre triggerAsyncId
Le paramètre triggerAsyncId est l'identificateur asyncId de la ressource qui a provoqué l'initialisation
de la nouvelle ressource, puis appelé le rappel init. Ceci est différent de
async_hooks.executionAsyncId () qui apparaît lorsque la ressource est créée tandis que
triggerAsyncId montre pourquoi la ressource a été créée.

Le code suivant est une explication pratique simple sur le paramètre triggerAsyncId:

async_hooks.createHook ({
init (asyncId, type, triggerAsyncId) {
const eid = async_hooks.executionAsyncId ();
fs.writeSync (
1, `$ {type} ($ {asyncId}): trigger: $ {triggerAsyncId} exécution: $ {eid} \
n`);
}
}). activer ();

require ('net'). createServer ((conn) => {}) .Listen (8080);

Cet exemple donnera le résultat suivant lorsque vous envoyez le 8080 localhost nc au serveur:

TCPSERVERWRAP (2): déclencheur: 1 exécution: 1


TCPWRAP (4): déclencheur: 2 exécution: 0

TCPSERVERWRAP est le serveur qui reçoit les connexions et TCPWRAP est une nouvelle
connexion du client. Lorsqu'une nouvelle connexion est établie, une copie de TCPWrap sera créée
directement et cela se produit en dehors de la pile JavaScript (la valeur 0 renvoyée par
executionAsyncId () indique qu'il s'exécute maintenant à partir de C ++ sans pile JavaScript au-
dessus). Avec seulement ces informations, il est impossible de lier les ressources entre elles depuis la
partie à l'origine de leur création, donc triggerAsyncId attribue une tâche de propagation à toute
ressource responsable de la présence de la nouvelle ressource.

La ressource de paramètre
La ressource est un objet qui représente la ressource asynchrone réelle qui a été configurée et peut
contenir des informations utiles qui varient selon le type de paramètre. Par exemple, le paramètre de
ressource pour le type de ressource GETADDRINFOREQWRAP fournit le nom d'hôte (nom d'hôte)
utilisé lorsque vous recherchez son adresse IP dans net.Server.listen (). L'interface logicielle (API)
qui permet d'accéder à ces informations n'est actuellement pas publique. Cependant, les utilisateurs
peuvent utiliser l'API intégrée pour fournir et documenter leurs objets de ressource. Par exemple,
vous pouvez fournir un objet de ressource qui peut contenir une instruction SQL à exécuter à ce
moment-là.

Dans Promises, l'objet de ressource aura la propriété promise qui fait référence à l'objet Promise qui
est alors configuré, et la propriété isChainedPromise qui est définie sur true si l'objet Promise a un
objet AP de type Promise, ou la valeur false existe dans le cas contraire. Si, par exemple, nous
regardons b = a. Alors (gestionnaire), nous trouvons que a est un objet Promise de l'objet b; b est une
promesse enchaînée.

La ressource est parfois réutilisée pour des raisons de performances, mais il n'est pas sûr de l'utiliser
comme clé dans l'objet WeakMap ou pour lui ajouter des attributs.

Un exemple de contexte asynchrone


L'exemple suivant montre comment appeler l'appel init entre l'appel de rappel avant et après, et
comment le rappel de la fonction listen () apparaîtra spécifiquement. Le format de sortie est
largement détaillé pour faciliter la lecture du contexte de l'appel.

laissez indenter = 0;
async_hooks.createHook ({
init (asyncId, type, triggerAsyncId) {
const eid = async_hooks.executionAsyncId ();
const indentStr = '' .repeat (indent);
fs.writeSync (
1,
'$ {indentStr} $ {type} ($ {asyncId}): `+
`trigger: $ {triggerAsyncId} exécution: $ {eid} \ n`);
},
avant (asyncId) {
const indentStr = '' .repeat (indent);
fs.writeSync (1, `$ {indentStr} avant: $ {asyncId} \ n`);
retrait + = 2;
},
après (asyncId) {
retrait - = 2;
const indentStr = '' .repeat (indent);
fs.writeSync (1, `$ {indentStr} après: $ {asyncId} \ n`);
},
détruire (asyncId) {
const indentStr = '' .repeat (indent);
fs.writeSync (1, `$ {indentStr} destroy: $ {asyncId} \ n`);
},
}). activer ();

('net'). createServer (() => {}) .Listen (8080, () => {


// Attendons 10 ms avant de connecter le serveur.
setTimeout () => {
console.log ('>>>', async_hooks.executionAsyncId ());
}, dix);
});

Les sorties suivantes apparaîtront en commençant par le serveur:

TCPSERVERWRAP (2): déclencheur: 1 exécution: 1


TickObject (3): déclencheur: 2 exécution: 1
avant: 3
Timeout (4): déclenchement: 3 exécution: 3
TIMERWRAP (5): déclenchement: 3 exécution: 3
après: 3
détruire: 3
avant: 5
avant: 4
TTYWRAP (6): déclencheur: 4 exécution: 4
SIGNALWRAP (7): déclenchement: 4 exécution: 4
TTYWRAP (8): déclencheur: 4 exécution: 4
>>> 4
TickObject (9): déclencheur: 4 exécution: 4
après: 4
après: 5
avant: 9
après: 9
détruire: 4
détruire: 9
détruire: 5

Comme le montre l'exemple, executionAsyncId () et execution déterminent la valeur du contexte


d'exécution actuel qui est décrit avec précision sur l'appel avant et après. Utilisez l'exécution pour
placer les résultats d'allocation de ressources dans une mappe comme suit:

TTYWRAP (6) -> Timeout (4) -> TIMERWRAP (5) -> TickObject (3) ->
root (1)
TCPSERVERWRAP ne fait pas partie de ce schéma même si c'était une raison pour appeler
console.log (). En effet, le processus de liaison d'un port sans nom d'hôte est un processus
synchronisé. Dans tous les cas, pour garder l'interface du logiciel complètement désynchronisée, le
rappel de l'utilisateur doit être placé dans process.nextTick ().
Le graphique montre uniquement quand la ressource a été créée et ne montre pas comment, utilisez
donc triggerAsyncId pour suivre comment la construction est créée.

avant (asyncId)
asyncId: <number> Le nombre représente un identificateur unique (ID) pour la ressource asynchrone.
Lorsqu'un processus asynchrone (comme une réception de serveur TCP) commence ou s'achève
(comme l'écriture de données sur le disque dur), un rappel est appelé pour alerter l' utilisateur, mais le
rappel est appelé avant avant d'exécuter l'identifiant unique attribué à la ressource sur laquelle le
rappel est sur le point d'être implémenté.

Le rappel sera appelé de 0 à N une fois qu'il ne sera jamais appelé (0 fois) si l'opération asynchrone
est annulée ou si le serveur TCP n'a reçu aucune connexion.

Les ressources continues - comme un serveur TCP - appelleront l'avant plusieurs fois tandis que
d'autres ressources - telles que fs.open () - seront appelées une fois.

après (asyncId)
asyncId: <number> Le nombre représente un identificateur unique (ID) pour la ressource asynchrone.
Un rappel est appelé après que la réponse de rappel spécifiée dans before soit terminée
immédiatement.
L'exception non interceptée se produit pendant l'exécution du rappel, et s'exécutera ensuite après que
l'événement déclenche «uncaughtException» ou exécute le gestionnaire de domaine de domaine.

détruire (asyncId)
asyncId: <number> Le nombre représente un identificateur unique (ID) pour la ressource asynchrone.
Un appel à destroy est appelé après la destruction de la ressource correspondant au paramètre asyncId
donné. Il est également appelé de manière asynchrone depuis l'interface du logiciel embarqué
(embedder) via emitDestroy ().

Certaines ressources dépendent du garbage collection pour être analysées, donc si vous créez une
ressource pour la ressource qui est passée au rappel d'initialisation, il est possible que le rappel
n'appelle pas du tout une destruction, provoquant ainsi une fuite de mémoire dans l'application. . Ceci
n'est pas pris en compte si le fournisseur ne dépend pas des déchets.

promiseResolve (asyncId)
asyncId: <number> Le nombre représente un identificateur unique (ID) pour la ressource asynchrone.
Cet appel est appelé lorsque la fonction resolver () est appelée sur l'objet Promise (soit directement,
soit via d'autres méthodes Promise).

Notez que la fonction resolver () n'effectue aucun travail synchrone notable.

L'objet Promise ne doit pas nécessairement être complété ou rejeté à ce stade s'il a été accepté sur la
base de l'hypothèse d'un état particulier d'un autre objet Promise.
nouvelle promesse ((résoudre) => résoudre (vrai)) alors ((a) => {});
Appelez les réponses d'appel suivantes:
init pour PROMISE avec id 5, trigger id: 1
promesse résoudre 5 # résoudre (vrai) Cela correspond
init pour PROMISE avec id 6, trigger id: 5 # Promise L'objet then () renvoie la fonction
avant 6 # puis () je donne un rappel
promise résoudre 6 # promise L'objet turn then () accepte le rappel
après 6
async_hooks.executionAsyncId ()
Ajouté dans la version: v8.1.0

Cette fonction renvoie le numéro asyncId, qui représente un identificateur unique pour le contexte
d'exécution actuel, et est utile dans le processus de suivi lorsque vous appelez quoi que ce soit.
const async_hooks = require ('async_hooks');

console.log (async_hooks.executionAsyncId ()); // 1 - bootstrap


fs.open (chemin, 'r', (err, fd) => {
console.log (async_hooks.executionAsyncId ()); // 6 - ouvert ()
});
L'identifiant renvoyé par la fonction executionAsyncId () se rapporte au temps d'exécution et non à
ses causes (utilisez triggerAsyncId () pour identifier les causes):
const server = net.createServer (fonction onConnection (conn) {
// L'ID du serveur est réinitialisé et non la nouvelle connexion car
// fonctionne dans le champ onConnection
// MakeCallback () Exécute le serveur
async_hooks.executionAsyncId ();

}). écouter (port, fonction onListening () {


// (comme process.nextTick ()), et TickObject renvoie l'ID de l'objet
// nextTick () encapsulé dans .listen () tous les rappels transmis à
async_hooks.executionAsyncId ();
});
Notez que le contexte Promise peut ne pas apporter une valeur valide à l'identificateur
executionAsyncIds par défaut. (Voir la section «Promesse de suivi» suivante).
async_hooks.triggerAsyncId ()
Cette fonction renvoie l'identificateur de ressource responsable de l'appel du rappel en cours
d'exécution.
serveur de const = net.createServer ((conn) => {
// La ressource à l'origine de cet appel de rappel était cette connexion
// Commande triggerAsyncId (). En conséquence, la valeur que vous
renvoyez
// "conn" est l'ID de connexion
async_hooks.triggerAsyncId ();

}). écouter (port, () => {


//, nextTick () est encapsulé dans .listen () bien que tous les callbacks soient
passés à
// .listen () indique que la même réponse de rappel est due à l'appel du
serveur
// En conséquence, cet ID de serveur sera réinitialisé
async_hooks.triggerAsyncId ();
});

Notez que le contexte Promise peut ne pas apporter une valeur valide à l'identificateur
executionAsyncIds par défaut. (Voir la section «Promesse de suivi» suivante).

Suivi de l'exécution des promesses


L'implémentation de la promesse n'attribue aucun des identifiants asyncId en raison de la nature
coûteuse de l'interface d'objet Promise créée dans la v8. Cela signifie que les programmes qui
utilisent des promesses, ou qui attendent ou qui sont asynchrones n'extraient pas de valeur valide
pour l'implémentation et les ID d'appel du contexte d'appel Promise par défaut.

Voici un exemple:

const ah = require ('async_hooks');


Promise.resolve (1729) .then (() => {
console.log (`eid $ {ah.executionAsyncId ()} tid $ {ah.triggerAsyncId ()}`);
});
// Il en résultera
// eid 1 tid 0

Notez que le rappel nécessite ensuite qu'il soit exécuté dans la portée externe, bien qu'il existe un saut
asynchrone commun. Notez également que la valeur de l'identificateur triggerAsyncId est 0, ce qui
signifie qu'il nous manque un contexte de la ressource qui a déclenché le rappel then (). L'installation
de hooks asynchrones via async_hooks.createHook suit l'exécution de la promesse. Par exemple,
vérifiez le code suivant:

const ah = require ('async_hooks');


ah.createHook ({init () {}}). activer (); // Contre lui PromiseHooks fait
Promise.resolve (1729) .then (() => {
console.log (`eid $ {ah.executionAsyncId ()} tid $ {ah.triggerAsyncId ()}`);
});
// Il en résultera
// eid 7 tid 6

Dans cet exemple, l'ajout de toute fonction de hook physique respecte les promesses. Il y a deux
promesses dans cet exemple; le premier a été créé via Promise.resolve (), et le second a été renvoyé
en appelant then (). La valeur de l'identifiant asyncId pour la première promesse est 6 et la deuxième
promesse est 7. Lors de l'exécution du callback then (), nous nous exécutions alors dans le cadre de la
promesse qui a la valeur 7 de l'identifiant asyncId. Cette promesse a été appelée via une ressource
asynchrone 6.
Une autre chose à propos de l'exactitude des promesses est que la réponse avant et après n'est mise en
œuvre qu'avec des promesses enchaînées. Cela signifie que les promesses qui ne sont pas générées
par la fonction then () ou la fonction catch () ne déclencheront pas l'appel avant et après. Pour plus
d'informations, consultez les détails de la version PromiseHooks V8.

API intégrée (API Embedder) en JavaScript


Est une bibliothèque de développeurs qui leur permet de gérer les performances des tâches pour leurs
ressources asynchrones telles que les E / S, la mise en commun ou la gestion des files d'attente de
rappel qui peuvent nécessiter l'utilisation de l'interface JavaScript AsyncWrap pour appeler toutes les
réponses Appel approprié.

AsyncResource
AsyncResource est conçu pour être extensible par des ressources intégrées asynchrones. Lorsqu'ils
sont utilisés, les utilisateurs peuvent facilement appeler des événements à tout moment avec leurs
ressources.

L'appel init sera appelé lorsqu'une copie de la classe AsyncResource est créée. Le code suivant donne
un aperçu de l'interface du logiciel AsyncResource:

const {AsyncResource, executionAsyncId} = require ('async_hooks');

// va s'étendre. Créer une nouvelle copie d'AsyncResource () signifie que


// Si le paramètre .init n'est pas donné à l'appel de rappel AsyncResource ()
de
// async_hook.executionAsyncId () utilisera, triggerAsyncId
const asyncResource = new AsyncResource (
type, {triggerAsyncId: executionAsyncId (), requireManualDestroy: false}
);

// L'exécution d'une fonction dans le cadre de l'exécution de ressources


conduit à
// * Créer le contexte de ressource
// * Réponses de rappel AsyncHooks
// * donné avec les arguments disponibles fonction d'appel `fn`
// * Après les appels de rappel AsyncHooks
// * Récupère le contexte d'exécution d'origine
asyncResource.runInAsyncScope (fn, thisArg, ... args);

// détruit les appels de rappel AsyncHooks


asyncResource.emitDestroy ();

// AsyncResource Renvoie l'identifiant unique attribué à la copie


asyncResource.asyncId ();

// AsyncResource pour la version (triggerAsyncId ou ID, trigger ID) pour


renvoyer l'ID appelant
asyncResource.triggerAsyncId ();
AsyncResource (type [, options])

type: <string> Une chaîne de texte qui représente le type d'événement asynchrone.

Options: <Object> Objet de type Object contient l'une des options suivantes:
triggerAsyncId: <numéro> Le numéro qui représente l'ID de contexte d'exécution qui a généré cet
événement asynchrone. La valeur par défaut est: executionAsyncId ().
requireManualDestroy: <boolean> Une valeur booléenne plante ou fait automatiquement
emitDestroy quand elle sort l'objet de la corbeille. Cette option n'est généralement pas définie (même
si vous appelez emitDestroy manuellement) à moins que vous ne renvoyiez l'identifiant asyncId à la
ressource et que vous l'utilisiez ensuite avec l'interface du logiciel emitDestroy. La valeur par défaut
est: false.

Examinez l'exemple pratique suivant qui explique l'utilisation de cette fonction:


la classe DBQuery étend AsyncResource {
constructeur (db) {
super ('DBQuery');
this.db = db;
}

getInfo (requête, rappel) {


this.db.get (requête, (err, données) => {
this.runInAsyncScope (rappel, null, err, données);
});
}

Fermer () {
this.db = null;
this.emitDestroy ();
}
}

asyncResource.runInAsyncScope (fn [, thisArg, ... args])


Ajouté dans la version: v9.6.0

fn: <Fonction> Fonction à appeler dans le contexte d'exécution de cette ressource synchrone.
thisArg: <any> Tout type de données JavaScript, représentant le récepteur (récepteur) à utiliser avec
l'appel de fonction.

... args: <any> Tout type de données JavaScript et représente les arguments supplémentaires à
transmettre à la fonction.
Examinez l'exemple pratique suivant qui explique l'utilisation de cette fonction:
la classe DBQuery étend AsyncResource {
constructeur (db) {
super ('DBQuery');
this.db = db;
}

getInfo (requête, rappel) {


this.db.get (requête, (err, données) => {
this.runInAsyncScope (rappel, null, err, données);
});
}

Fermer () {
this.db = null;
this.emitDestroy ();
}
}

asyncResource.runInAsyncScope (fn [, thisArg, ... args])

Ajouté dans la version: v9.6.0

fn: <Fonction> Fonction à appeler dans le cadre de l'exécution de cette ressource asynchrone.
thisArg: <any> Tout type de données JavaScript, représentant le récepteur (récepteur) à utiliser avec
l'appel de fonction.
... args: <any> Tout type de données JavaScript et représente les arguments supplémentaires à
transmettre à la fonction.
Cette fonction appelle la fonction qui lui est passée avec les arguments donnés dans le contexte
d'exécution de la ressource asynchrone. Cela va créer le contexte, puis lancer AsyncHooks avant le
rappel, puis appeler la fonction, puis lancer AsyncHooks après le rappel, puis restaurer le contexte
d'exécution d'origine.

asyncResource.emitBefore ()
Ignorer depuis la publication: v9.6.0

Stabilité: 0-négligée: utilisez plutôt la fonction asyncResource.runInAsyncScope ().

Cette fonction appelle tous les rappels avant de commencer à créer un nouveau contexte d'exécution.
Si vous appelez emitBefore () plusieurs fois, il suivra les identificateurs asyncId dans la pile et les
éliminera dans l'ordre dans lequel vous avez été appelé.
Le rappel doit être supprimé avant et après le même ordre qu'il a été appelé, sinon une exception que
vous ne pouvez pas corriger sera libérée et le processus s'arrêtera à ce moment-là. Pour cette raison,
les deux logiciels emitBefore et emitAfter sont ignorés. Veuillez utiliser la fonction runInAsyncScope
au lieu de cette fonction pour être plus sûr.

asyncResource.emitAfter ()
Ignorer depuis la publication: v9.6.0

Stabilité: 0-négligée: utilisez plutôt la fonction asyncResource.runInAsyncScope ().

Cette fonction appelle tous les rappels après. Si vous appelez emitAfter () plusieurs fois de manière
complexe, il suivra les identificateurs asyncId dans la pile et les éliminera dans l'ordre dans lequel
vous avez été appelé.

Si les appels de réponse de l'utilisateur sont une exception, emitAfter () appellera automatiquement
tous les identificateurs asyncIds de la pile si l'erreur a été traitée via le gestionnaire de domaine ou le
gestionnaire «uncaughtException».

Le rappel doit être supprimé avant et après le même ordre qu'il a été appelé, sinon une exception que
vous ne pouvez pas corriger sera libérée et le processus s'arrêtera. Pour cette raison, les deux logiciels
emitBefore et emitAfter sont ignorés. Veuillez utiliser la fonction runInAsyncScope au lieu de cette
fonction pour être plus sûr.

asyncResource.emitDestroy ()
Cette fonction appelle tous les destroyers. Il ne doit être appelé qu'une seule fois manuellement, et
une erreur sera appelée si vous en appelez plus. Laisser la ressource à collecter via le garbage
collection (GC) n'appellera pas les destroyers à ce moment-là.

asyncResource.asyncId ()
Cette fonction renvoie un nombre qui représente l'identificateur asyncId unique attribué à la
ressource.

asyncResource.triggerAsyncId ()
Cette fonction renvoie un nombre qui représente le même identificateur triggerAsyncId que celui
transmis à la classe de constructeur AsyncResource.
1

You might also like