Vous êtes sur la page 1sur 100

Machine Translated by Google

Chapitre 19 : nvm ­ Gestionnaire de versions de nœud

Section 19.1 : Installer NVM


Vous pouvez utiliser curl :

curl ­o­ https://raw.githubusercontent.com/creationix/nvm/v0.31.3/install.sh | frapper

Ou vous pouvez utiliser wget :

wget ­qO­ https://raw.githubusercontent.com/creationix/nvm/v0.31.3/install.sh | frapper

Section 19.2 : Vérifier la version de NVM


Pour vérifier que NVM a été installé, procédez :

commande ­v nvm

qui devrait afficher 'nvm' si l'installation a réussi.

Section 19.3 : Installation d'une version spécifique de Node


Liste des versions distantes disponibles pour l'installation

NVM LS­Remote

Installer une version distante

installation nvm <version>

Par exemple

nvm installer 0.10.13

Section 19.4 : Utilisation d'une version de nœud déjà installée


Pour répertorier les versions locales disponibles du nœud via NVM :

NVM LS

Par exemple, si nvm ls renvoie :

$nvmlsv4.3.0

v5.5.0

Vous pouvez passer à la v5.5.0 avec :

NVM utilise la version 5.5.0

Notes de GoalKicker.com Node.js pour les professionnels 90


Machine Translated by Google

Section 19.5 : Installer nvm sur Mac OSX


PROCESSUS D'INSTALLATION

Vous pouvez installer Node Version Manager en utilisant git, curl ou wget. Vous exécutez ces commandes dans Terminal sous Mac OSX.

exemple de boucle :

curl ­o­ https://raw.githubusercontent.com/creationix/nvm/v0.31.3/install.sh | frapper

exemple wget :

wget ­qO­ https://raw.githubusercontent.com/creationix/nvm/v0.31.3/install.sh | frapper

TESTEZ QUE NVM A ÉTÉ CORRECTEMENT INSTALLÉ

Pour tester que NVM a été correctement installé, fermez et rouvrez le Terminal et entrez NVM. Si vous recevez un message nvm: command not found , votre système

d'exploitation ne dispose peut­être pas du fichier .bash_profile nécessaire . Dans Terminal, entrez touch ~/.bash_profile et exécutez à nouveau le script d'installation ci­

dessus.

Si vous obtenez toujours la commande nvm : introuvable, essayez ce qui suit :

Dans Terminal, saisissez nano .bashrc. Vous devriez voir un script d'exportation presque identique au suivant :

export NVM_DIR=”/Users/johndoe/.nvm” [ ­s “$NVM_DIR/nvm.sh” ] && . « $NVM_DIR/nvm.sh »

Copiez le script d'exportation et supprimez­le de .bashrc Enregistrez et

fermez le fichier .bashrc (CTRL+O – Entrée – CTRL+X)

Ensuite, entrez nano .bash_profile pour ouvrir le profil Bash. Collez le script

d'exportation que vous avez copié dans le profil Bash sur une nouvelle ligne. Enregistrez et fermez le

profil Bash (CTRL+O – Entrée – CTRL+X)

Saisissez enfin nano .bashrc pour rouvrir le fichier .bashrc. Collez la ligne

suivante dans le fichier :

source ~/.nvm/nvm.sh

Enregistrer et fermer (CTRL+O – Entrée – CTRL+X)

Redémarrez le terminal et entrez nvm pour tester s'il fonctionne

Section 19.6 : Exécuter n'importe quelle commande arbitraire dans un sous­shell


avec la version souhaitée du nœud
Répertorier toutes les versions de nœud installées

NVM LS
v4.5.0
v6.7.0

Exécuter la commande en utilisant n'importe quelle version installée du nœud

nvm run 4.5.0 ­­version ou nvm exec 4.5.0 nœud ­­version

Notes de GoalKicker.com Node.js pour les professionnels 91


Machine Translated by Google

Nœud en cours d'exécution v4.5.0 (npm


v2.15.9) v4.5.0

nvm run 6.7.0 ­­version ou nvm exec 6.7.0 node ­­version Exécution du nœud v6.7.0 (npm
v3.10.3) v6.7.0

utiliser un pseudo

nvm run default ­­version ou nvm exec default node ­­version Exécution du nœud v6.7.0 (npm
v3.10.3) v6.7.0

Pour installer la version LTS du nœud

nvm installer ­­lts

Changement de version

nvm utilise la v4.5.0 ou nvm utilise stable ( alias )

Section 19.7 : Définition de l'alias pour la version du nœud


Si vous souhaitez définir un nom d'alias sur la version du nœud installé, procédez :

nvm alias <nom> <version>

De la même manière qu'unalias, faites :

nvm unalias <nom>

Un cas d'utilisation approprié serait si vous souhaitez définir une autre version que la version stable comme alias par défaut. les versions avec alias par

défaut sont chargées sur la console par défaut.

Comme:

nvm alias par défaut 5.0.1

Ensuite, à chaque démarrage de la console/du terminal, 5.0.1 serait présent par défaut.

Note:

nvm alias # répertorie tous les alias créés sur nvm

Notes de GoalKicker.com Node.js pour les professionnels 92


Machine Translated by Google

Chapitre 20 : http
Section 20.1 : serveur http
Un exemple basique de serveur HTTP.

écrivez le code suivant dans le fichier http_server.js :

var http = require('http');

var httpPort = 80 ;

http.createServer(handler).listen(httpPort, start_callback);

gestionnaire de fonctions (req, res) {

var clientIP = req.connection.remoteAddress;


var connectUsing = req.connection.encrypted ? 'SSL' : 'HTTP';
' ' ' '
console.log('Demande reçue : '+ connectUsing + + req.method + console.log(' IP client : + clientIP); + URL requise);
'

res.writeHead(200, "OK", {'Content­Type': 'text/plain'});


res.write("OK");
res.end();
retour;
}

fonction start_callback(){
'
console.log('Démarrer HTTP sur le port + port http)
}

puis à partir de votre emplacement http_server.js, exécutez cette commande :

nœud http_server.js

vous devriez voir ce résultat :

> Démarrez HTTP sur le port 80

vous devez maintenant tester votre serveur, vous devez ouvrir votre navigateur Internet et accéder à cette URL :

http://127.0.0.1:80

si votre machine exécute un serveur Linux, vous pouvez la tester comme ceci :

boucle 127.0.0.1:80

vous devriez voir le résultat suivant :

d'accord

dans votre console, en exécutant l'application, vous verrez les résultats suivants :

> Requête reçue : HTTP GET /


> IP client : :ffff:127.0.0.1

Notes de GoalKicker.com Node.js pour les professionnels 93


Machine Translated by Google

Section 20.2 : client http


un exemple de base pour le client http :

écrivez le code suivant dans le fichier http_client.js :

var http = require('http');

var options = { nom


d'hôte : '127.0.0.1', port : 80,
chemin : '/',
méthode :
'GET' } ;

var req = http.request(options, function(res) { console.log('STATUS :


' + res.statusCode); console.log('HEADERS : '
+ JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk)
{ console.log('Response: ' + chunk);
});
res.on('end', fonction (morceau) {
console.log('Réponse ENDED'); });

});

req.on('erreur', function(e)
'
{ console.log('problème avec la requête : + e.message);
});

req.end();

puis depuis votre emplacement http_client.js, exécutez cette commande :

nœud http_client.js

vous devriez voir ce résultat :

> STATUT : 200


> HEADERS : {"content­type": "text/plain", "date": jeu. 21 juil. 2016 11:27:17
GMT","connection":"fermer","transfer­encoding":"chunked"}
> Réponse : OK
> Réponse TERMINÉE

remarque : cet exemple dépend de l'exemple du serveur http.

Notes de GoalKicker.com Node.js pour les professionnels 94


Machine Translated by Google

Chapitre 21 : Utiliser les flux


Paramètre Définition
Type de flux lisible à partir duquel les données peuvent être lues

Type de flux inscriptible dans lequel les données peuvent être écrites

Type de flux Duplex Stream qui est à la fois lisible et inscriptible

Transform Stream Type de flux duplex qui peut transformer les données au fur et à mesure de leur lecture puis de leur écriture.

Section 21.1 : Lire les données de TextFile avec Streams


Les E/S dans le nœud sont asynchrones, donc interagir avec le disque et le réseau implique de transmettre des rappels aux fonctions. Vous
pourriez être tenté d'écrire du code qui sert un fichier à partir du disque comme ceci :

var http = require('http'); var fs =


require('fs');

var serveur = http.createServer (fonction (req, res) {


fs.readFile(__dirname + '/data.txt', function (err, data) { res.end(data);

});
});
serveur.écouter (8000);

Ce code fonctionne mais il est volumineux et met en mémoire tampon l'intégralité du fichier data.txt pour chaque requête avant de réécrire le résultat
aux clients. Si data.txt est très volumineux, votre programme pourrait commencer à consommer beaucoup de mémoire car il sert simultanément de
nombreux utilisateurs, en particulier pour les utilisateurs disposant de connexions lentes.

L'expérience utilisateur est également médiocre car les utilisateurs devront attendre que l'intégralité du fichier soit mise en mémoire tampon
sur votre serveur avant de pouvoir commencer à recevoir du contenu.

Heureusement, les deux arguments (req, res) sont des flux, ce qui signifie que nous pouvons écrire cela d'une bien meilleure manière en
utilisant fs.createReadStream() au lieu de fs.readFile() :

var http = require('http'); var fs =


require('fs');

var serveur = http.createServer (fonction (req, res) {


var stream = fs.createReadStream(__dirname + '/data.txt');
stream.pipe(res);
});
serveur.écouter (8000);

Ici, .pipe() se charge d'écouter les événements 'data' et 'end' de fs.createReadStream(). Ce code est non seulement plus propre, mais désormais
le fichier data.txt sera écrit sur les clients un morceau à la fois dès leur réception.
du disque.

Section 21.2 : Flux de tuyauterie


Les flux lisibles peuvent être « redirigés » ou connectés à des flux inscriptibles. Cela permet aux données de circuler du flux source vers le flux
de destination sans trop d'effort.

var fs = exiger('fs')

var lisible = fs.createReadStream('file1.txt')

Notes de GoalKicker.com Node.js pour les professionnels 95


Machine Translated by Google

var inscriptible = fs.createWriteStream('file2.txt')

readable.pipe(writable) // renvoie l'écriture

Lorsque les flux inscriptibles sont également des flux lisibles, c'est­à­dire lorsqu'il s'agit de flux duplex , vous pouvez continuer à les rediriger vers d'autres flux
inscriptibles.

var zlib = exiger('zlib')

fs.createReadStream('style.css')
.pipe(zlib.createGzip()) // L'objet renvoyé, zlib.Gzip, est un flux duplex. .pipe(fs.createWriteStream('style.css.gz')

Les flux lisibles peuvent également être redirigés vers plusieurs flux.

var readable = fs.createReadStream('source.css')


readable.pipe(zlib.createGzip()).pipe(fs.createWriteStream('output.css.gz'))
readable.pipe(fs.createWriteStream('output. css')

Notez que vous devez rediriger vers les flux de sortie de manière synchrone (en même temps) avant que les données ne « circulent ». Dans le cas contraire, des données

incomplètes pourraient être diffusées.

Notez également que les objets de flux peuvent émettre des événements d'erreur ; assurez­vous de gérer ces événements de manière responsable sur chaque flux, si
nécessaire :

var readable = fs.createReadStream('file3.txt') var writable =


fs.createWriteStream('file4.txt') readable.pipe(writable)
readable.on('error',
console.error) writable.on('error ',
console.erreur)

Section 21.3 : Création de votre propre flux lisible/inscriptible


Nous verrons des objets de flux renvoyés par des modules comme fs, etc., mais que se passe­t­il si nous voulons créer notre propre objet diffusable.

Pour créer un objet Stream, nous devons utiliser le module stream fourni par NodeJs

var fs = require("fs"); var


stream = require("stream").Writable;

/*
* Implémentation de la fonction d'écriture dans la classe de flux inscriptible.
* C'est la fonction qui sera utilisée lorsqu'un autre flux sera redirigé vers ce * flux inscriptible. */

stream.prototype._write = function(morceau, données)


{ console.log(données);
}

var customStream = nouveau flux();

fs.createReadStream("am1.js").pipe(customStream);

Cela nous donnera notre propre flux inscriptible personnalisé. nous pouvons implémenter n'importe quoi dans la fonction _write . La méthode ci­dessus fonctionne

dans la version NodeJs 4.xx, mais dans NodeJs 6.x ES6 a introduit les classes, la syntaxe a donc changé.

Vous trouverez ci­dessous le code de la version 6.x de NodeJs

Notes de GoalKicker.com Node.js pour les professionnels 96


Machine Translated by Google

const Writable = require('stream').Writable;

class MyWritable extends Writable


{ constructor(options)
{ super(options);
}

_write(morceau, encodage, rappel) {


console.log(morceau);
}
}

Section 21.4 : Pourquoi Streams ?


Examinons les deux exemples suivants pour lire le contenu d'un fichier :

La première, qui utilise une méthode asynchrone pour lire un fichier, et fournit une fonction de rappel qui est appelée une fois le fichier
entièrement lu en mémoire :

fs.readFile(`${__dirname}/utils.js`, (err, data) => {


if (erreur)
{ handleError(erreur); }
else
{ console.log(data.toString());

} })

Et la seconde, qui utilise des flux afin de lire le contenu du fichier, morceau par morceau :

var fileStream = fs.createReadStream(`${__dirname}/file`); var fichierContenu


= ''; fileStream.on('données',
données => {
fileContent += data.toString(); })

fileStream.on('end', () =>
{ console.log(fileContent); })

fileStream.on('erreur', err => {


handleError(err) })

Il convient de mentionner que les deux exemples font exactement la même chose. Quelle est la différence alors ?

Le premier est plus court et plus élégant. Le second


vous permet d'effectuer quelques traitements sur le fichier pendant sa lecture (!)

Lorsque les fichiers que vous traitez sont petits, l'utilisation de flux n'a aucun effet réel , mais que se passe­t­il lorsque le fichier est
volumineux ? (si gros qu'il faut 10 secondes pour le lire en mémoire)

Sans flux, vous attendrez, sans rien faire (sauf si votre processus fait autre chose), jusqu'à ce que les 10 secondes se soient
écoulées et que le fichier soit entièrement lu, et alors seulement vous pourrez commencer à traiter le fichier.

Avec les flux, vous obtenez le contenu du fichier morceau par morceau, dès qu'il est disponible , ce qui vous permet de traiter le fichier
pendant sa lecture.

Notes de GoalKicker.com Node.js pour les professionnels 97


Machine Translated by Google

L'exemple ci­dessus n'illustre pas comment les flux peuvent être utilisés pour un travail qui ne peut pas être effectué en mode rappel, regardons donc un autre

exemple :

Je souhaite télécharger un fichier gzip , le décompresser et enregistrer son contenu sur le disque. Etant donné l' url du fichier, voici ce qu'il faut faire :

Téléchargez le fichier

Décompressez le fichier

Enregistrez­le sur le disque

Voici un [petit fichier][1], qui est stocké dans mon stockage S3 . Le code suivant effectue ce qui précède en mode rappel.

var startTime = Date.now()


s3.getObject({Bucket : 'some­bucket', Clé : 'tweets.gz'}, (err, data) => {
// ici, tout le fichier a été téléchargé

zlib.gunzip(data.Body, (err, data) => { // ici, tout le


fichier a été décompressé

fs.writeFile(`${__dirname}/tweets.json`, data, err => {


si (erreur) console.erreur (erreur)

// ici, le fichier entier a été écrit sur le disque var endTime


= Date.now() console.log(`$
{endTime ­ startTime} milliseconds`) // 1339 millisecondes }) }) })

// 1339 millisecondes

Voici à quoi cela ressemble en utilisant les flux :

s3.getObject({Bucket : 'some­bucket', Clé : 'tweets.gz'}).createReadStream()

.pipe(zlib.createGunzip()) .pipe(fs.createWriteStream(`${__dirname}/tweets.json`));

// 1204 millisecondes

Oui, ce n'est pas plus rapide lorsqu'il s'agit de petits fichiers ­ le fichier testé pèse 80 Ko. Le test sur un fichier plus gros, 71 Mo compressés (382 Mo

décompressés), montre que la version Streams est beaucoup plus rapide.

Il a fallu 20 925 millisecondes pour télécharger 71 Mo, le décompresser, puis écrire 382 Mo sur le disque ­ à l'aide du rappel.
mode.

En comparaison, il a fallu 13434 millisecondes pour faire la même chose avec la version streams (35% plus rapide, pour un fichier pas si gros)

Notes de GoalKicker.com Node.js pour les professionnels 98


Machine Translated by Google

Chapitre 22 : Déploiement d'applications Node.js


en production
Section 22.1 : Définition de NODE_ENV="production"
Les déploiements en production varient de nombreuses manières, mais une convention standard lors du déploiement en production consiste à définir une variable

d'environnement appelée NODE_ENV et à définir sa valeur sur « production ».

Indicateurs d'exécution

Tout code exécuté dans votre application (y compris les modules externes) peut vérifier la valeur de NODE_ENV :

if(process.env.NODE_ENV === 'production') { // Nous


fonctionnons en mode production } else {

// Nous fonctionnons en mode développement


}

Dépendances

Lorsque la variable d'environnement NODE_ENV est définie sur « production », toutes les dépendances dev de votre fichier package.json seront complètement ignorées lors

de l'exécution de l'installation de npm . Vous pouvez également appliquer cela avec un indicateur ­­production :

npm installer ­­production

Pour définir NODE_ENV, vous pouvez utiliser l'une de ces méthodes

méthode 1 : définir NODE_ENV pour toutes les applications de nœud

Les fenêtres :

définir NODE_ENV=production

Linux ou autre système basé sur Unix :

export NODE_ENV=production

Cela définit NODE_ENV pour la session bash en cours. Ainsi, toutes les applications démarrées après cette instruction auront NODE_ENV défini sur production.

méthode 2 : définir NODE_ENV pour l'application actuelle

NODE_ENV=nœud de production app.js

Cela définira NODE_ENV pour l'application actuelle uniquement. Cela est utile lorsque nous voulons tester nos applications sur différents
environnements.

méthode 3 : créez un fichier .env et utilisez­le

Cela utilise l'idée expliquée ici. Reportez­vous à cet article pour une explication plus détaillée.

Fondamentalement, vous créez un fichier .env et exécutez un script bash pour les définir sur l'environnement.

Pour éviter d'écrire un script bash, le env­cmd Le package peut être utilisé pour charger les variables d'environnement définies dans le

Notes de GoalKicker.com Node.js pour les professionnels 99


Machine Translated by Google

Fichier .env .

env­cmd .env nœud app.js

méthode 4 : utiliser le package cross­env

Ce paquet permet aux variables d'environnement d'être définies d'une manière pour chaque plate­forme.

Après l'avoir installé avec npm, vous pouvez simplement l'ajouter à votre script de déploiement dans package.json comme suit :

"build:deploy": "cross­env NODE_ENV=webpack de production"

Section 22.2 : Gérer l'application avec le gestionnaire de processus


C'est une bonne pratique d'exécuter des applications NodeJS contrôlées par des gestionnaires de processus. Le gestionnaire de processus permet de maintenir

l'application en vie pour toujours, de redémarrer en cas d'échec, de recharger sans temps d'arrêt et simplifie l'administration. Les plus puissants d'entre eux (comme

PM2) avoir un équilibreur de charge intégré. PM2 vous permet également de gérer la journalisation, la surveillance et le clustering des applications.

Gestionnaire de processus PM2

Installation de PM2 :

npm installer pm2 ­g

Le processus peut être démarré en mode cluster impliquant un équilibreur de charge intégré pour répartir la charge entre les processus :

pm2 start app.js ­i 0 ­­name "api" (­i doit spécifier le nombre de processus à générer. S'il est égal à 0, le numéro de processus
sera basé sur le nombre de cœurs de processeur)

Tout en ayant plusieurs utilisateurs en production, il faut avoir un seul point pour PM2. Par conséquent, la commande pm2 doit être préfixée par un emplacement

(pour la configuration PM2), sinon elle générera un nouveau processus pm2 pour chaque utilisateur avec une configuration dans le répertoire personnel

respectif. Et ce sera incohérent.

Utilisation : PM2_HOME=/etc/.pm2 pm2 start app.js

Section 22.3 : Déploiement à l'aide du gestionnaire de processus


Le gestionnaire de processus est généralement utilisé en production pour déployer une application nodejs. Les principales fonctions d'un gestionnaire de processus

sont le redémarrage du serveur en cas de panne, la vérification de la consommation des ressources, l'amélioration des performances d'exécution, la surveillance
etc.

Certains des gestionnaires de processus les plus populaires créés par la communauté des nœuds sont Forever, PM2, etc.

Pour toujours

pour toujours est un outil d'interface de ligne de commande permettant de garantir qu'un script donné s'exécute en continu. L'interface simple de Forever

le rend idéal pour exécuter des déploiements plus petits d' applications et de scripts Node.js.

surveille toujours votre processus et le redémarre en cas de panne.

Installez pour toujours dans le monde entier.

$ npm install ­g pour toujours

Exécuter l'application :

Notes de GoalKicker.com Node.js pour les professionnels 100


Machine Translated by Google

$ démarrer pour toujours server.js

Cela démarre le serveur et donne un identifiant pour le processus (commence à partir de 0).

Redémarrez l'application :

$ redémarrer pour toujours 0

Ici 0 est l'identifiant du serveur.

Arrêter l'application :

$ arrêter pour toujours 0

Semblable au redémarrage, 0 est l'identifiant du serveur. Vous pouvez également donner l'identifiant du processus ou le nom du script à la place de l'identifiant donné par Forever.

Pour plus de commandes : https://www.npmjs.com/package/forever

Section 22.4 : Déploiement à l'aide de PM2


PM2 est un gestionnaire de processus de production pour les applications Node.js , qui vous permet de maintenir les applications en vie pour toujours et de les

recharger sans temps d'arrêt. PM2 vous permet également de gérer la journalisation, la surveillance et le clustering des applications.

Installez pm2 globalement.

npm installer ­g pm2

Ensuite, exécutez l' application node.js à l'aide de PM2.

pm2 start server.js ­­name "mon­application"

Les commandes suivantes sont utiles lorsque vous travaillez avec PM2.

Répertoriez tous les processus en cours :

liste pm2

Arrêter une application :

pm2 arrête mon application

Notes de GoalKicker.com Node.js pour les professionnels 101


Machine Translated by Google

Redémarrez une application :

pm2 redémarrer mon application

Pour afficher des informations détaillées sur une application :

pm2 afficher mon application

Pour supprimer une application du registre de PM2 :

pm2 supprimer mon application

Section 22.5 : Utilisation de différentes propriétés/configurations pour différents


environnements tels que le développement, l'assurance qualité, la préparation, etc.

Les applications à grande échelle nécessitent souvent des propriétés différentes lorsqu'elles sont exécutées sur différents environnements. nous pouvons y

parvenir en transmettant des arguments à l'application NodeJs et en utilisant le même argument dans le processus de nœud pour charger un fichier de

propriétés d'environnement spécifique.

Supposons que nous ayons deux fichiers de propriétés pour un environnement différent.

dev.json

{
"PORT": 3000,
"DB":
{ "host": "localhost",
"user": "bob",
"password": "12345"
}
}

qa.json

{
"PORT": 3001,
"DB":
{ "host": "where_db_is_hosted",
"user": "bob",
"password": "54321"
}
}

Le code suivant dans l'application exportera le fichier de propriétés respectif que nous souhaitons utiliser.

process.argv.forEach(function (val) { var arg =


val.split("="); if (arg.length > 0)
{ if (arg[0] === 'env') {

var env = require('./' + arg[1] + '.json'); exports.prop =


env;
}

Notes de GoalKicker.com Node.js pour les professionnels 102


Machine Translated by Google

}
});

Nous donnons des arguments à l'application comme suit

nœud app.js env=dev

si nous utilisons le gestionnaire de processus pour toujours , c'est aussi simple que

démarrer pour toujours app.js env=dev

Section 22.6 : Tirer parti des clusters


Une seule instance de Node.js s'exécute dans un seul thread. Pour profiter des systèmes multicœurs, l'utilisateur souhaitera parfois
lancer un cluster de processus Node.js pour gérer la charge.

var cluster = require('cluster');

var numCPUs = require('os').cpus().length;

if (cluster.isMaster) { // Dans
la vraie vie, vous utiliseriez probablement plus de 2 travailleurs, // et ne
placeriez peut­être pas le maître et le travailleur dans le même fichier. // // Vous

pouvez aussi, bien sûr, devenir un peu plus sophistiqué en matière de


journalisation et // implémenter la logique personnalisée dont vous avez
besoin pour empêcher // les attaques DoS
et
autres mauvais comportements. // // Voir les options dans la

documentation du cluster. // // L'important est que le maître fasse très peu, //


augmentant notre résilience aux erreurs inattendues.
'
console.log('votre serveur travaille sur + numCPUs + 'noyaux');

for (var i = 0; i < numCPUs; i++) { cluster.fork();

cluster.on('déconnecter', function(worker) {
console.error('déconnecter!'); //
clearTimeout(délai d'attente);
cluster.fork(); });

} else
{ require('./app.js');

Notes de GoalKicker.com Node.js pour les professionnels 103


Machine Translated by Google

Chapitre 23 : Sécurisation des applications Node.js Section 23.1 : SSL/TLS dans

Node.js
Si vous choisissez de gérer SSL/TLS dans votre application Node.js, considérez que vous êtes également responsable du maintien de la prévention
des attaques SSL/TLS à ce stade. Dans de nombreuses architectures serveur­client, SSL/TLS se termine sur un proxy inverse, à la fois pour
réduire la complexité des applications et la portée de la configuration de sécurité.

Si votre application Node.js doit gérer SSL/TLS, elle peut être sécurisée en chargeant les fichiers de clé et de certificat.

Si votre fournisseur de certificat nécessite une chaîne d'autorité de certification (CA), elle peut être ajoutée dans l' option ca sous forme de tableau.
Une chaîne avec plusieurs entrées dans un seul fichier doit être divisée en plusieurs fichiers et entrée dans le même ordre dans le tableau, car
Node.js ne prend actuellement pas en charge plusieurs entrées ca dans un seul fichier. Un exemple est fourni dans le code ci­dessous pour
les fichiers 1_ca.crt et 2_ca.crt. Si le tableau ca est requis et n'est pas défini correctement, les navigateurs clients peuvent afficher des messages
indiquant qu'ils n'ont pas pu vérifier l'authenticité du certificat.

Exemple

const https = exiger('https'); const fs =


require('fs');

const options = { clé :


fs.readFileSync('privatekey.pem'), cert :
fs.readFileSync('certificate.pem'), ca :
[fs.readFileSync('1_ca.crt'), fs.readFileSync('2_ca .crt')] };

https.createServer(options, (req, res) =>


{ res.writeHead(200);
res.end('hello
world\n'); }).listen(8000);

Section 23.2 : Prévention de la falsification de demandes intersites (CSRF)


CSRF est une attaque qui oblige l'utilisateur final à exécuter des actions indésirables sur une application Web dans laquelle il est
actuellement authentifié.

Cela peut se produire parce que des cookies sont envoyés à chaque demande adressée à un site Web, même lorsque ces demandes proviennent
d'un autre site.

Nous pouvons utiliser le module csurf pour créer un jeton csrf et le valider.

Exemple

var express = require('express') var


cookieParser = require('cookie­parser') var csrf = //pour l'analyse des cookies
require('csurf') var bodyParser = //module csrf
require('body­parser') //pour l'analyse du corps

// configuration des middlewares


de route var csrfProtection = csrf({ cookie: true }) var
parseForm = bodyParser.urlencoded({ extended: false })

// crée une application


express var app = express()

Notes de GoalKicker.com Node.js pour les professionnels 104


Machine Translated by Google

// analyser les cookies


app.use(cookieParser())

app.get('/form', csrfProtection, function(req, res) { // générer et transmettre


le csrfToken à la vue res.render('send', { csrfToken:
req.csrfToken() }) })

app.post('/process', parseForm, csrfProtection, function(req, res) {


res.send('les données sont en cours de traitement') })

Ainsi, lorsque nous accédons à GET /form, il transmettra le jeton csrf csrfToken à la vue.

Maintenant, dans la vue, définissez la valeur csrfToken comme valeur d'un champ de saisie masqué nommé _csrf.

par exemple pour les modèles de guidon

<form action="/process" method="POST"> <input


type="hidden" name="_csrf" value="{{csrfToken}}">
Nom : <input type="text" name="name"> <button
type="submit">Soumettre</button> </form>

par exemple pour les modèles de jade

formulaire(action="/processus" méthode="post")
input(type="hidden", nom="_csrf", valeur=csrfToken)

span Nom :
input(type="text", name="name", obligatoire=true) br

entrée(type="soumettre")

par exemple pour les modèles ejs

<form action="/process" method="POST"> <input


type="hidden" name="_csrf" value="<%= csrfToken %>">
Nom : <input type="text" name="name"> <button
type="submit">Soumettre</button> </form>

Section 23.3 : Configuration d'un serveur HTTPS


Une fois que node.js est installé sur votre système, suivez simplement la procédure ci­dessous pour obtenir un serveur Web de base fonctionnant avec la prise en charge de HTTP

et HTTPS !

Étape 1 : Créer une autorité de certification

1. créez le dossier dans lequel vous souhaitez stocker votre clé et votre certificat :

mkdir conf

Notes de GoalKicker.com Node.js pour les professionnels 105


Machine Translated by Google

2. allez dans ce répertoire :

conférence cd

3. récupérez ce fichier ca.cnf pour l'utiliser comme raccourci de configuration :

wget https://raw.githubusercontent.com/anders94/https­authorized­clients/master/keys/ca.cnf

4. créez une nouvelle autorité de certification en utilisant cette configuration :

openssl req ­new ­x509 ­days 9999 ­config ca.cnf ­keyout ca­key.pem ­out ca­cert.pem

5. maintenant que nous avons notre autorité de certification dans ca­key.pem et ca­cert.pem, générons une clé privée pour
le serveur :

openssl genrsa ­out key.pem 4096

6. récupérez ce fichier server.cnf pour l'utiliser comme raccourci de configuration :

wget https://raw.githubusercontent.com/anders94/https­authorized­clients/master/keys/server.cnf

7. générer la demande de signature de certificat en utilisant cette configuration :

openssl req ­new ­config server.cnf ­key key.pem ­out csr.pem

8. signez la demande :

openssl x509 ­req ­extfile server.cnf ­days 999 ­passin "pass:mot de passe" ­in csr.pem ­CA ca­cert.pem ­CAkey ca­
key.pem ­CAcreateserial ­out cert.pem

Étape 2 : Installez votre certificat en tant que certificat racine

1. copiez votre certificat dans le dossier de vos certificats racine :

Notes de GoalKicker.com Node.js pour les professionnels 106


Machine Translated by Google

sudo cp ca­crt.pem /usr/local/share/ca­certificates/ca­crt.pem

2. mettre à jour le magasin CA :

sudo update­ca­certificats

Section 23.4 : Utilisation de HTTPS

La configuration minimale pour un serveur HTTPS dans Node.js ressemblerait à ceci :

const https = exiger('https'); const fs =


require('fs');

const httpsOptions = { clé :


fs.readFileSync('chemin/vers/serveur­key.pem'), cert :
fs.readFileSync('chemin/vers/serveur­crt.pem')

const app = function (req, res)


{ res.writeHead(200);
res.end("bonjour tout le monde\n");
}

https.createServer(httpsOptions, app).listen(4433);

Si vous souhaitez également prendre en charge les requêtes http, vous devez effectuer cette petite modification :

const http = exiger('http'); const https


= exiger('https'); const fs = require('fs');

const httpsOptions = { clé :


fs.readFileSync('chemin/vers/serveur­key.pem'), cert :
fs.readFileSync('chemin/vers/serveur­crt.pem')

const app = function (req, res)


{ res.writeHead(200);
res.end("bonjour tout le monde\n");
}

http.createServer(app).listen(8888);
https.createServer(httpsOptions, app).listen(4433);

Section 23.5 : Application sécurisée express.js 3

La configuration pour établir une connexion sécurisée à l'aide d'express.js (Depuis la version 3) :

var fs = require('fs'); var http


= require('http'); var https =
require('https'); var privateKey =
fs.readFileSync('sslcert/server.key', 'utf8'); var certificat = fs.readFileSync('sslcert/
server.crt', 'utf8');

Notes de GoalKicker.com Node.js pour les professionnels 107


Machine Translated by Google

// Définissez votre clé et votre certificat

var informations d'identification = {clé : clé privée, cert : certificat} ; var express =
require('express'); var app = express();

// votre configuration express ici

var httpServer = http.createServer(app); var httpsServer =


https.createServer (informations d'identification, application);

// Utilisation du port 8080 pour http et 8443 pour https

httpServeur.écouter(8080);
httpsServeur.écouter(8443);

De cette façon, vous fournissez un middleware express au serveur http/https natif

Si vous souhaitez que votre application s'exécute sur des ports inférieurs à 1024, vous devrez utiliser la commande sudo (non recommandée) ou utiliser
un proxy inverse (par exemple nginx, haproxy).

Notes de GoalKicker.com Node.js pour les professionnels 108


Machine Translated by Google

Chapitre 24 : Bibliothèque Mangouste

Section 24.1 : Connectez­vous à MongoDB à l'aide de Mongoose

Tout d’abord, installez Mongoose avec :

npm installer la mangouste

Ensuite, ajoutez­le à server.js en tant que dépendances :

var mangouste = require('mangouste'); var


Schema = mangouste.Schema;

Créez ensuite le schéma de la base de données et le nom de la collection :

var schemaName = new


Schema({ requête :
chaîne, heure :

numéro }, { collection : 'collectionName'


});

Créez un modèle et connectez­vous à la base de données :

var Model = mangouste.model('Model', schemaName);


mangouste.connect('mongodb://localhost:27017/dbName');

Ensuite, démarrez MongoDB et exécutez server.js en utilisant node server.js

Pour vérifier si nous avons réussi à nous connecter à la base de données, nous pouvons utiliser les événements open, erreur de l' objet

mongoose.connection .

var db = mangouste.connection;
db.on('erreur', console.error.bind(console, 'erreur de connexion :')); db.once('open',
function() { // nous sommes
connectés ! });

Section 24.2 : Rechercher des données dans MongoDB à l'aide de


Mongoose, des routes Express.js et de l'opérateur $text

Installation

Tout d’abord, installez les packages nécessaires avec :

npm installer la mangouste express cors


Code

Ensuite, ajoutez des dépendances à server.js, créez le schéma de base de données et le nom de la collection, créez un serveur Express.js et connectez­

vous à MongoDB :

var express = require('express'); var cors =


require('cors'); // Nous utiliserons CORS pour activer les requêtes de domaine d'origine croisée. var mangouste =
require('mangouste');

Notes de GoalKicker.com Node.js pour les professionnels 109


Machine Translated by Google

var Schema = mangouste.Schema;

var app = express();

var schemaName = new


Schema({ requête :
chaîne, heure :

numéro }, { collection : 'collectionName'


});

var Model = mangouste.model('Model', schemaName);


mangouste.connect('mongodb://localhost:27017/dbName');

var port = processus.env.PORT || 8080 ;


app.listen(port, function()
'
{ console.log('Node.js écoutant sur le port + port);
});

Ajoutez maintenant les routes Express.js que nous utiliserons pour interroger les données :

app.get('/find/:query', cors(), function(req, res) { var query =


req.params.query;

Model.find({ 'request':
query }, function(err, result) { if
(err) throw err; if (result)
{ res.json(result) }
else

{ res.send(JSON.stringify({ erreur :
'Erreur'
}))
}
})
})

Supposons que les documents suivants se trouvent dans la collection du modèle :

{
"_id" : ObjectId("578abe97522ad414b8eeb55a"), "request" :
"JavaScript est génial", "time" : 1468710551

}{
"_id" : ObjectId("578abe9b522ad414b8eeb55b"), "request" :
"JavaScript est génial", "time" : 1468710555

}{
"_id" : ObjectId("578abea0522ad414b8eeb55c"), "request" :
"JavaScript est génial", "time" : 1468710560

Et que le but est de retrouver et d'afficher tous les documents contenant uniquement le mot "JavaScript" sous la touche "requête" .

Pour ce faire, créez d'abord un index de texte pour "requête" dans la collection. Pour cela, ajoutez le code suivant à server.js :

Notes de GoalKicker.com Node.js pour les professionnels 110


Machine Translated by Google

nom_schéma.index({ requête : 'texte' });

Et remplacez :

Model.find({ 'request':
query }, function(err, result) {

Avec:

Model.find({ $text :
{ $search :
requête
}
}, fonction (erreur, résultat) {

Ici, nous utilisons les opérateurs $text et $search MongoDB pour rechercher tous les documents de la collection collectionName
qui contient au moins un mot de la requête de recherche spécifiée.

Usage

Pour l'utiliser pour rechercher des données, accédez à l'URL suivante dans un navigateur :

http://localhost:8080/find/<requête>

Où <query> est la requête de recherche.

Exemple:

http://localhost:8080/find/JavaScript

Sortir:

[{
_id : « 578abe97522ad414b8eeb55a »,
requête : « JavaScript est génial », heure :
1468710551, __v : 0

},
{
_id : « 578abe9b522ad414b8eeb55b »,
requête : « JavaScript est génial », heure :
1468710555, __v : 0

},
{
_id : « 578abea0522ad414b8eeb55c »,
requête : « JavaScript est génial », heure :
1468710560, __v : 0

}]

Section 24.3 : Enregistrer les données sur MongoDB à l'aide des routes
Mongoose et Express.js
Installation

Notes de GoalKicker.com Node.js pour les professionnels 111


Machine Translated by Google

Tout d’abord, installez les packages nécessaires avec :

npm installer la mangouste express cors


Code

Ensuite, ajoutez des dépendances à votre fichier server.js , créez le schéma de base de données et le nom de la collection, créez un serveur Express.js et connectez­

vous à MongoDB :

var express = require('express'); var cors =


require('cors'); // Nous utiliserons CORS pour activer les requêtes de domaine d'origine croisée. var mangouste
= require('mangouste'); var Schema =
mangouste.Schema;

var app = express();

var nom_schéma = nouveau schéma({


requête : chaîne,
heure : numéro },

{ collection : 'collectionName'
});

var Model = mangouste.model('Model', schemaName);


mangouste.connect('mongodb://localhost:27017/dbName');

var port = processus.env.PORT || 8080 ;


app.listen(port, function()
'
{ console.log('Node.js écoutant sur le port + port);
});

Ajoutez maintenant les routes Express.js que nous utiliserons pour écrire les données :

app.get('/save/:query', cors(), function(req, res) { var query =


req.params.query;

var savedata = new


Model({ 'request':
query, 'time': Math.floor(Date.now() / 1000) // Heure de sauvegarde des données au format d'horodatage unix
}).save(function(err, result) { if (err) throw
err;

si (résultat)
{ res.json (résultat)
}
})
})

Ici, la variable de requête sera le paramètre <query> de la requête HTTP entrante, qui sera enregistrée dans

MongoDB :

var savedata = nouveau modèle


({ 'requête' :
requête, //...

Si une erreur se produit lors de la tentative d'écriture sur MongoDB, vous recevrez un message d'erreur sur la console. Si tout réussit, vous verrez les

données enregistrées au format JSON sur la page.

//...

Notes de GoalKicker.com Node.js pour les professionnels 112


Machine Translated by Google

}).save(function(err, result) { if (err) throw


err;

si (résultat)
{ res.json (résultat)
}

}) //...

Maintenant, vous devez démarrer MongoDB et exécuter votre fichier server.js à l'aide du nœud server.js.

Usage

Pour l'utiliser pour enregistrer des données, accédez à l'URL suivante dans votre navigateur :

http://localhost:8080/save/<query>

Où <query> est la nouvelle requête que vous souhaitez enregistrer.

Exemple:

http://localhost:8080/save/JavaScript%20is%20Awesome

Sortie au format JSON :

{
__v : 0,
requête : "JavaScript est génial", heure :
1469411348, _id :
"57957014b93bc8640f2c78c4"
}

Section 24.4 : Rechercher des données dans MongoDB à l'aide des routes
Mongoose et Express.js
Installation

Tout d’abord, installez les packages nécessaires avec :

npm installer la mangouste express cors


Code

Ensuite, ajoutez des dépendances à server.js, créez le schéma de base de données et le nom de la collection, créez un serveur Express.js et connectez­

vous à MongoDB :

var express = require('express'); var cors =


require('cors'); // Nous utiliserons CORS pour activer les requêtes de domaine d'origine croisée. var mangouste =
require('mangouste'); var Schema =
mangouste.Schema;

var app = express();

var nom_schéma = nouveau schéma({


requête : chaîne,
heure : numéro },

{ collection : 'collectionName'

Notes de GoalKicker.com Node.js pour les professionnels 113


Machine Translated by Google

});

var Model = mangouste.model('Model', schemaName);


mangouste.connect('mongodb://localhost:27017/dbName');

var port = processus.env.PORT || 8080 ;


app.listen(port, function()
'
{ console.log('Node.js écoutant sur le port + port);
});

Ajoutez maintenant les routes Express.js que nous utiliserons pour interroger les données :

app.get('/find/:query', cors(), function(req, res) { var query =


req.params.query;

Model.find({ 'request':
query }, function(err, result) { if
(err) throw err; if (result)
{ res.json(result) }
else

{ res.send(JSON.stringify({ erreur :
'Erreur'
}))
}
})
})

Supposons que les documents suivants se trouvent dans la collection du modèle :

{
"_id" : ObjectId("578abe97522ad414b8eeb55a"), "request" :
"JavaScript est génial", "time" : 1468710551

}{
"_id" : ObjectId("578abe9b522ad414b8eeb55b"), "request" :
"JavaScript est génial", "time" : 1468710555

}{
"_id" : ObjectId("578abea0522ad414b8eeb55c"), "request" :
"JavaScript est génial", "time" : 1468710560

Et le but est de retrouver et d'afficher tous les documents contenant "JavaScript is Awesome" sous la touche "request" .

Pour cela, démarrez MongoDB et exécutez server.js avec node server.js :

Usage

Pour l'utiliser pour rechercher des données, accédez à l'URL suivante dans un navigateur :

http://localhost:8080/find/<requête>

Où <query> est la requête de recherche.

Notes de GoalKicker.com Node.js pour les professionnels 114


Machine Translated by Google

Exemple:

http://localhost:8080/find/JavaScript%20is%20Awesome

Sortir:

[{
_id : « 578abe97522ad414b8eeb55a »,
requête : « JavaScript est génial », heure :
1468710551, __v : 0

},
{
_id : « 578abe9b522ad414b8eeb55b »,
requête : « JavaScript est génial », heure :
1468710555, __v : 0

},
{
_id : « 578abea0522ad414b8eeb55c »,
requête : « JavaScript est génial », heure :
1468710560, __v : 0

}]

Section 24.5 : Fonctions utiles de Mongoose


Mongoose contient des fonctions intégrées qui s'appuient sur la méthode find() standard.

doc.find({'some.value':5},function(err,docs){
// renvoie la documentation du tableau

});

doc.findOne({'some.value':5},function(err,doc){
// renvoie le document doc
});

doc.findById(obj._id,function(err,doc){ //renvoie le
document doc
});

Section 24.6 : Index dans les modèles


MongoDB prend en charge les index secondaires. Dans Mongoose, nous définissons ces index dans notre schéma. La définition d'index
au niveau du schéma est nécessaire lorsque nous devons créer des index composés.

Connexion mangouste

var strConnection = 'mongodb://localhost:27017/dbName'; var db =


mangouste.createConnection(strConnection)

Création d'un schéma de base

var Schema = require('mangouste').Schema; var


usersSchema = nouveau schéma
({ nom d'utilisateur : {
tapez : chaîne,

Notes de GoalKicker.com Node.js pour les professionnels 115


Machine Translated by Google

obligatoire : vrai,
unique : vrai
},

mail : { type :
Chaîne, obligatoire : vrai
},
mot de passe :
{ type : chaîne,
obligatoire : vrai
},
créé : { type :
Date, par
défaut : Date.now
}
});

var usersModel = db.model('users', usersSchema);


module.exports = utilisateursModèle ;

Par défaut, mangoose ajoute deux nouveaux champs dans notre modèle, même lorsque ceux­ci ne sont pas définis dans le modèle. Ceux
les champs sont :

_identifiant

Mongoose attribue à chacun de vos schémas un champ _id par défaut s'il n'est pas transmis au constructeur de schéma.
Le type attribué est un ObjectId qui coïncide avec le comportement par défaut de MongoDB. Si vous ne souhaitez pas du tout qu'un _id soit ajouté à votre
schéma, vous pouvez le désactiver en utilisant cette option.

var usersSchema = new Schema({ nom


d'utilisateur :
{ type : String,
obligatoire : true,
unique : true },

{ _id : false
});

__v ou versionKey

La versionKey est une propriété définie sur chaque document lors de sa première création par Mongoose. Cette valeur de clé contient la révision interne du
document. Le nom de cette propriété de document est configurable.

Vous pouvez facilement désactiver ce champ dans la configuration du modèle :

var usersSchema = new Schema({ nom


d'utilisateur :
{ type : String,
obligatoire : true,
unique : true },

{ versionKey : false
});

Index composés

Nous pouvons créer d'autres index en plus de ceux créés par Mongoose.

usersSchema.index({nom d'utilisateur : 1 });

Notes de GoalKicker.com Node.js pour les professionnels 116


Machine Translated by Google

usersSchema.index({email : 1 });

Dans ce cas, notre modèle dispose de deux index supplémentaires, un pour le champ nom d'utilisateur et un autre pour le champ email. Mais nous pouvons

créer des index composés.

usersSchema.index({nom d'utilisateur : 1, email : 1 });

Impact sur la performance de l'indice

Par défaut, Mongoose appelle toujours le EnsureIndex pour chaque index de manière séquentielle et émet un événement « index » sur le modèle
lorsque tous les appels EnsureIndex ont réussi ou lorsqu'il y a eu une erreur.

Dans MongoDB, EnsureIndex est obsolète depuis la version 3.0.0, c'est désormais un alias pour createIndex.

Il est recommandé de désactiver le comportement en définissant l'option autoIndex de votre schéma sur false, ou globalement sur la connexion en
définissant l'option config.autoIndex sur false.

usersSchema.set('autoIndex', false);

Section 24.7 : rechercher des données dans MongoDB à l'aide de promesses

Installation

Tout d’abord, installez les packages nécessaires avec :

npm installer la mangouste express cors


Code

Ensuite, ajoutez des dépendances à server.js, créez le schéma de base de données et le nom de la collection, créez un serveur Express.js et connectez­
vous à MongoDB :

var express = require('express'); var cors =


require('cors'); // Nous utiliserons CORS pour activer les requêtes de domaine d'origine croisée. var mangouste =
require('mangouste'); var Schema =
mangouste.Schema;

var app = express();

var nom_schéma = nouveau schéma({


requête : chaîne,
heure : numéro },

{ collection : 'collectionName'
});

var Model = mangouste.model('Model', schemaName);


mangouste.connect('mongodb://localhost:27017/dbName');

var port = processus.env.PORT || 8080 ;


app.listen(port, function()
'
{ console.log('Node.js écoutant sur le port + port);
});

app.use(function(err, req, res, next)


{ console.error(err.stack);
res.status(500).send('Quelque chose est cassé !'); });

Notes de GoalKicker.com Node.js pour les professionnels 117


Machine Translated by Google

app.use(function(req, res, next)


{ res.status(404).send('Désolé , je ne trouve pas ça !'); });

Ajoutez maintenant les routes Express.js que nous utiliserons pour interroger les données :

app.get('/find/:query', cors(), function(req, res, next) {


var requête = req.params.query;

Model.find({ 'requête' : requête

}) .exec() //n'oubliez pas d'ajouter exec, les requêtes ont un attribut .then mais ne sont pas des
promesses .then(function(result)
{ if (result)
{ res.json(result) }
else
{ next() / /passer au gestionnaire 404
}

}) .catch(next) //passer au gestionnaire d'erreurs


})

Supposons que les documents suivants se trouvent dans la collection du modèle :

{
"_id" : ObjectId("578abe97522ad414b8eeb55a"), "request" :
"JavaScript est génial", "time" : 1468710551

}{
"_id" : ObjectId("578abe9b522ad414b8eeb55b"), "request" :
"JavaScript est génial", "time" : 1468710555

}{
"_id" : ObjectId("578abea0522ad414b8eeb55c"), "request" :
"JavaScript est génial", "time" : 1468710560

Et le but est de retrouver et d'afficher tous les documents contenant "JavaScript is Awesome" sous la touche "request" .

Pour cela, démarrez MongoDB et exécutez server.js avec node server.js :

Usage

Pour l'utiliser pour rechercher des données, accédez à l'URL suivante dans un navigateur :

http://localhost:8080/find/<requête>

Où <query> est la requête de recherche.

Exemple:

http://localhost:8080/find/JavaScript%20is%20Awesome

Notes de GoalKicker.com Node.js pour les professionnels 118


Machine Translated by Google

Sortir:

[{
_id : « 578abe97522ad414b8eeb55a »,
requête : « JavaScript est génial », heure :
1468710551, __v : 0

},
{
_id : « 578abe9b522ad414b8eeb55b »,
requête : « JavaScript est génial », heure :
1468710555, __v : 0

},
{
_id : « 578abea0522ad414b8eeb55c »,
requête : « JavaScript est génial », heure :
1468710560, __v : 0

}]

Notes de GoalKicker.com Node.js pour les professionnels 119


Machine Translated by Google

Chapitre 25 : async.js
Section 25.1 : Parallèle : multitâche
async.parallel (tâches, afterTasksCallback) exécutera un ensemble de tâches en parallèle et attendra la fin de toutes les tâches (signalée par l'appel
de la fonction de rappel ).

Lorsque les tâches sont terminées, appelez de manière asynchrone le rappel principal avec toutes les erreurs et tous les résultats des tâches.

function shortTimeFunction(callback)
{ setTimeout(function()
{ callback(null, 'resultOfShortTime'); }, 200);

function mediumTimeFunction(callback)
{ setTimeout(function()
{ callback(null, 'resultOfMediumTime'); }, 500);

function longTimeFunction(callback)
{ setTimeout(function()
{ callback(null, 'resultOfLongTime'); }, 1000);

async.parallel([ shortTimeFunction,
mediumTimeFunction,

longTimeFunction ], function(err,
results) { if
(err) { return console.error(err);
}

console.log(résultats); });

Résultat : ["resultOfShortTime", "resultOfMediumTime", "resultOfLongTime"].

Appelez async.parallel() avec un objet

Vous pouvez remplacer le paramètre du tableau de tâches par un objet. Dans ce cas, les résultats seront également un objet avec les mêmes
clés que les tâches.

C'est très utile pour calculer certaines tâches et retrouver facilement chaque résultat.

async.parallel({ short:
shortTimeFunction, medium:
mediumTimeFunction, long:
longTimeFunction },

function(err, results) { if (err)


{ return
console.error(err);
}

Notes de GoalKicker.com Node.js pour les professionnels 120


Machine Translated by Google

console.log(résultats); });

Résultat : {short : "resultOfShortTime", medium : "resultOfMediumTime", long : "resultOfLongTime"}.

Résolution de plusieurs valeurs

Chaque fonction parallèle reçoit un rappel. Ce rappel peut soit renvoyer une erreur comme premier argument, soit des valeurs de réussite par la
suite. Si un rappel reçoit plusieurs valeurs de réussite, ces résultats sont renvoyés sous forme de tableau.

async.parallel({ court :
function shortTimeFunction(callback) {
setTimeout(function()
{ callback(null, 'resultOfShortTime1', 'resultOfShortTime2'); }, 200); }, support :
fonction

mediumTimeFunction(callback) {
setTimeout(function()
{ callback(null, 'resultOfMediumTime1', 'resultOfMeiumTime2'); }, 500);

} }, function(err, results) { if (err)


{ return
console.error(err);
}

console.log(résultats); });

Résultat :

{
court : ["resultOfShortTime1", "resultOfShortTime2"], moyen :
["resultOfMediumTime1", "resultOfMediumTime2"]
}

Section 25.2 : async.each (pour gérer efficacement un tableau de données)


Lorsque nous voulons gérer un tableau de données, il est préférable d'utiliser async.each. Lorsque nous voulons effectuer quelque chose avec
toutes les données et que nous voulons obtenir le rappel final une fois que tout est fait, cette méthode sera utile. Ceci est géré de manière
parallèle.

function createUser (nom d'utilisateur, rappel) {

//créer un utilisateur dans la


base de données callback(null)//ou erreur basée sur la création
}

var arrayOfData = ['Ritu', 'Sid', 'Tom']; async.each


(arrayOfData, function (eachUserName, rappel) {

// Effectue l'opération sur chaque utilisateur.


console.log('Création d'un utilisateur '+eachUserName); //
Le retour du rappel est indispensable. Sinon, il ne recevra pas le rappel final, même si nous manquons de renvoyer un rappel.

Notes de GoalKicker.com Node.js pour les professionnels 121


Machine Translated by Google

createUser (eachUserName, rappel);

}, function(err) { //Si
l'une des créations d'utilisateurs échoue, une erreur peut être
générée.
if( err ) { // Une des itérations a produit une erreur.
// Tout le traitement va maintenant
s'arrêter. console.log('impossible de créer un

utilisateur'); } else { console.log('Tous les utilisateurs ont été créés avec succès');
}
});

Pour en faire un à la fois, vous pouvez utiliser async.eachSeries

Section 25.3 : Séries : mono­tâches indépendantes


async.series (tâches, afterTasksCallback) exécutera un ensemble de tâches. Chaque tâche est exécutée après l'autre. Si une tâche échoue, async arrête

immédiatement l'exécution et passe au rappel principal.

Lorsque les tâches sont terminées avec succès, appelez de manière asynchrone le rappel « maître » avec toutes les erreurs et tous les résultats des tâches.

function shortTimeFunction(callback)
{ setTimeout(function()
{ callback(null, 'resultOfShortTime'); }, 200);

function mediumTimeFunction(callback)
{ setTimeout(function()
{ callback(null, 'resultOfMediumTime'); }, 500);

function longTimeFunction(callback)
{ setTimeout(function()
{ callback(null, 'resultOfLongTime'); }, 1000);

async.series([ mediumTimeFunction,
shortTimeFunction,
longTimeFunction ],

function(err, results) { if (err)


{ return
console.error(err);
}

console.log(résultats); });

Résultat : ["resultOfMediumTime", "resultOfShortTime", "resultOfLongTime"].

Appelez async.series() avec un objet

Vous pouvez remplacer le paramètre du tableau de tâches par un objet. Dans ce cas, les résultats seront également un objet avec les mêmes clés que les tâches.

Notes de GoalKicker.com Node.js pour les professionnels 122


Machine Translated by Google

C'est très utile pour calculer certaines tâches et retrouver facilement chaque résultat.

async.series({ short :
shortTimeFunction, medium :
mediumTimeFunction, long :
longTimeFunction },

function(err, results) { if (err)


{ return
console.error(err);
}

console.log(résultats); });

Résultat : {short : "resultOfShortTime", medium : "resultOfMediumTime", long : "resultOfLongTime"}.

Section 25.4 : Waterfall : mono­tâche dépendante


async.waterfall (tâches, afterTasksCallback) exécutera un ensemble de tâches. Chaque tâche est exécutée l'une après l'autre et le résultat d'une tâche est transmis à

la tâche suivante. Comme async.series(), si une tâche échoue, async arrête l'exécution et appelle immédiatement le rappel principal.

Lorsque les tâches sont terminées avec succès, appelez de manière asynchrone le rappel « maître » avec toutes les erreurs et tous les résultats des tâches.

fonction getUserRequest (rappel) {


// On simule la requête avec un timeout
setTimeout(function() { var
userResult = { name :
'Aamu'

rappel (null, userResult); }, 500);

function getUserFriendsRequest (utilisateur, rappel) {


// Une autre requête simulée avec un timeout
setTimeout(function() {
var amisResult = [];

if (user.name === "Aamu")


{ friendsResult =
[{ nom : 'Alice' },

{ nom : 'Bob' }];

rappel (null, amisResult); }, 500);

async.waterfall([ getUserRequest,

getUserFriendsRequest ],
function(err,
results) { if (err) { return console.error(err);

Notes de GoalKicker.com Node.js pour les professionnels 123


Machine Translated by Google

console.log(JSON.stringify(results)); });

Résultat : results contient le deuxième paramètre de rappel de la dernière fonction de la cascade, qui est friendsResult dans ce cas.

Section 25.5 : async.times (pour mieux gérer la boucle for)


Pour exécuter une fonction dans une boucle dans node.js, vous pouvez utiliser une boucle for pour les boucles courtes. Mais la boucle est longue,
l'utilisation de la boucle for augmentera le temps de traitement, ce qui pourrait entraîner le blocage du processus du nœud. Dans de tels scénarios,
vous pouvez utiliser : asycn.times

fonction récursiveAction(n, rappel) {

//fait ce que tu veux faire à plusieurs reprises


callback(err, result);

} async.times(5, function(n, next)


{ recursiveAction(n, function(err, result) { next(err,
result);

}); }, fonction (erreur, résultats) {


// nous devrions maintenant avoir 5 résultats
});

C'est ce qu'on appelle en parallèle. Lorsque nous voulons l'appeler un par un, utilisez : async.timesSeries

Section 25.6 : async.series (Pour gérer les événements un par un)


Dans async.series, toutes les fonctions sont exécutées en série et les sorties consolidées de chaque fonction sont transmises au rappel final. par
exemple

var async = require('async');

async.series([ function (callback)


{ console.log('First Execute..');
callback(null, 'userPersonalData');
},
function (rappel)
{ console.log('Second Execute.. '); rappel
(null, 'userDependentData');
}
],

function (erreur, résultat)


{ console.log(result);
});

Sortir:

Première exécution.. Deuxième exécution.. ['userPersonalData','userDependentData'] //résultat

Notes de GoalKicker.com Node.js pour les professionnels 124


Machine Translated by Google

Chapitre 26 : Téléchargement de fichiers

Section 26.1 : Téléchargement d'un seul fichier à l'aide de multer

Se souvenir de

créer un dossier pour le téléchargement (téléchargements dans


l'exemple). installer multer npm i ­S multer

serveur.js :

var express = require("express"); var multer =


require('multer'); = exprimer(); var app var fs
= require('fs');

app.get('/',function(req,res)
{ res.sendFile(__dirname + "/index.html");
});

var storage = multer.diskStorage({ destination :


function (req, file, callback) { fs.mkdir('./uploads', function(err)
{ if(err) { console.log(err.stack) } else { rappel(null,
'./uploads');

}) }, nom de fichier : fonction (req, fichier, rappel) {


callback(null, file.fieldname + '­' + Date.now());

} });

app.post('/api/file',function(req,res){ var upload =


multer({ storage : storage}).single('userFile'); upload(req,res,function(err) { if( err)
{ return res.end("Erreur lors du

téléchargement du fichier.");

} res.end("Le fichier est téléchargé");


});
});

app.listen(3000,function()
{ console.log("Travail sur le port 3000");
});

index.html :

<form id = "uploadForm" enctype =


"multipart/form­data" = "/api/file" action =
"post"
méthode
>
<input type="file" name="userFile" /> <input
type="submit" value="Télécharger le fichier" name="submit">

Notes de GoalKicker.com Node.js pour les professionnels 125


Machine Translated by Google
</form>

Note:

Pour télécharger un fichier avec l'extension, vous pouvez utiliser le chemin Node.js bibliothèque intégrée

Pour cela, il vous suffit de demander le chemin du fichier server.js :

var chemin = require('chemin');

et changer :

callback(null, file.fieldname + '­' + Date.now());

en ajoutant une extension de fichier de la manière suivante :

callback(null, file.fieldname + '­' + Date.now() + path.extname(file.originalname));

Comment filtrer le téléchargement par extension :

Dans cet exemple, voyez comment télécharger des fichiers pour autoriser uniquement certaines extensions.

Par exemple uniquement les extensions d’images. Ajoutez simplement à var upload =
multer({ storage : storage}).single('userFile'); condition de filtre de fichier

var upload =
multer({ stockage :
stockage, fileFilter : fonction (req, fichier, rappel) {
var ext = chemin.extname(file.originalname); if(ext !==
'.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') { return callback(new Error('Seules les images
sont autorisées '))

} rappel (nul, vrai)

} }).single('userFile');

Vous pouvez désormais télécharger uniquement des fichiers image avec des extensions png, jpg, gif ou jpeg.

Section 26.2 : Utilisation du module formidable


Installer le module et lire la documentation

npm je suis formidable@dernier

Exemple de serveur sur port 8080

var formidable = require('formidable'), http =


require('http'), util = require('util');

http.createServer(function(req, res) { if (req.url == '/


upload' && req.method.toLowerCase() == 'post') {
// analyser un téléchargement
de fichier var form = new formidable.IncomingForm();

form.parse (req, fonction (erreur, champs, fichiers) {


si (erreur)
faire­qch ; // erreur de processus

Notes de GoalKicker.com Node.js pour les professionnels 126


Machine Translated by Google

// Copier le fichier depuis un emplacement


temporaire // var fs = require('fs'); //
fs.rename(file.path, <targetPath>, function (err) { ... });

// Envoie le résultat sur le client


res.writeHead(200, {'content­type': 'text/plain'}); res.write('
téléchargement reçu :\n\n');
res.end(util.inspect({champs : champs, fichiers : fichiers})); });

retour;
}

// affiche un formulaire de
téléchargement de fichier res.writeHead(200, {'content­type': 'text/
html'});
res.end( '<form action="/upload" enctype="multipart/form­data" method="post">'+ '<input
type="text" name="title"><br>'+ ' <input type="file"
name="upload" multiple="multiple"><br>'+ '<input type="submit" value="Upload">'+
'</form>' ); }).écouter(8080);

Notes de GoalKicker.com Node.js pour les professionnels 127


Machine Translated by Google

Chapitre 27 : Communication Socket.io


Section 27.1 : « Bonjour tout le monde ! » avec des messages de socket

Installer les modules de nœuds

npm installer express


npm installer socket.io

Serveur Node.js

const express = require('express'); const app


= express(); const server =
app.listen(3000,console.log(" Le serveur Socket.io Hello World a démarré!")); const io = require('socket.io')
(serveur);

io.on('connexion', (socket) => {


//console.log("Client connecté !");
socket.on('message­du­client­au­serveur', (msg) => { console.log(msg);

})
socket.emit('message­from­server­to­client', 'Hello World!');
});

Client de navigateur

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF­8">
<title>Bonjour tout le monde avec Socket.io</title> </
head>
<body>
<script src="https://cdn.socket.io/socket.io­1.4 .5.js"></script> <script> var socket =
io("http://
localhost:3000"); socket.on("message­du­serveur­au­
client", function(msg) { document.getElementById('message').innerHTML =
msg;
});
socket.emit('message­du­client­au­serveur', 'Bonjour tout le monde !'); </script>
<p>Le
client Socket.io Hello World a démarré !</p> <p
id="message"></p> </
body> </
html>

Notes de GoalKicker.com Node.js pour les professionnels 128


Machine Translated by Google

Chapitre 28 : Intégration de Mongodb


Paramètre Détails
document Un objet javascript représentant un document
documents Une panoplie de documents

filtre de Un objet définissant une requête de recherche


requête Un objet définissant une requête de recherche
rappeler Fonction à appeler lorsque l'opération est terminée

choix (facultatif) Paramètres facultatifs (par défaut : null)


w (facultatif) Le problème d'écriture
sans délai (facultatif) Le délai d'expiration du problème d'écriture. (par défaut : nul)

j (facultatif) Spécifiez un problème d'écriture de journal (par défaut : faux)

insérer (facultatif) Opération de mise à jour (par défaut : false)


multi (facultatif) Mettre à jour un/tous les documents (par défaut : false)
sérialiserFonctions (facultatif) Sérialiser les fonctions sur n'importe quel objet (par défaut : false)

forceServerObjectId (facultatif) Forcer le serveur à attribuer des valeurs _id au lieu du pilote (par défaut : false)

(facultatif) Autoriser le pilote à contourner la validation du schéma dans MongoDB 3.2 ou version ultérieure (par défaut :
bypassDocumentValidation faux)

Section 28.1 : Connexion simple


MongoDB.connect('mongodb://localhost:27017/databaseName', function(erreur, base de données) { if(erreur) return
console.log(erreur); const collection = base de données.collection('collectionName'); collection.insert({clé : 'valeur'},
function (erreur, résultat) { console.log (erreur, résultat); }); });

Section 28.2 : Connexion simple, à l'aide de promesses


const MongoDB = require('mongodb');

MongoDB.connect('mongodb://localhost:27017/databaseName')
.then (fonction (base de données) {
const collection = base de données.collection('collectionName');
return collection.insert({clé : 'valeur'});

}) .then(fonction(résultat) {
console.log(résultat);
});
```

Section 28.3 : Se connecter à MongoDB


Connectez­vous à MongoDB, imprimez « Connecté ! » et fermez la connexion.

const MongoClient = require('mongodb').MongoClient;

var url = 'mongodb://localhost:27017/test';

MongoClient.connect(url, function(err, db) { // Méthode MongoClient 'connect'


if (err) lance une nouvelle erreur (err);
console.log("Connecté!");
db.close(); // N'oubliez pas de fermer la connexion lorsque vous avez terminé
});

Notes de GoalKicker.com Node.js pour les professionnels 129


Machine Translated by Google

Méthode MongoClient Connect()

MongoClient.connect(url, options, rappel)

URL du type Description


d’argument chaîne Une chaîne spécifiant l'adresse IP/le nom d'hôte du serveur, le port et les

options de base de données. Objet (facultatif) Paramètres facultatifs


(par défaut : null) rappel Fonction Fonction à appeler lorsque la tentative de connexion est effectuée

La fonction de rappel prend deux arguments

err : Error ­ Si une erreur se produit, l' argument err sera défini db : object
­ L'instance MongoDB

Section 28.4 : Insérer un document


Insérez un document appelé « myFirstDocument » et définissez 2 propriétés, salutations et adieu.

const MongoClient = require('mongodb').MongoClient;

const url = 'mongodb://localhost:27017/test';

MongoClient.connect(url, fonction (erreur, db) {


if (err) lance une nouvelle erreur (err);
db.collection('myCollection').insertOne({ // Insérer la méthode 'insertOne' "myFirstDocument":
{
"salutations": "Bonjour",
"adieu": "Au revoir"
}
}, fonction (erreur, résultat) {
if (err) lance une nouvelle erreur (err);
console.log("Insérer un document dans la collection myCollection !"); db.close(); // N'oubliez
pas de fermer la connexion lorsque vous avez terminé }); });

Méthode de collecte insertOne()

db.collection(collection).insertOne(document, options, rappel)

Argument Type Description


collection string Une chaîne spécifiant l' objet du document de
collection Le document à insérer dans l' objet d'options de collection (facultatif)
Paramètres facultatifs (par défaut : null) rappel Fonction Fonction à
appeler lorsque l'opération d'insertion est terminée

La fonction de rappel prend deux arguments

err : Error ­ Si une erreur se produit, l' argument err sera défini result :
object ­ Un objet contenant des détails sur l'opération d'insertion

Notes de GoalKicker.com Node.js pour les professionnels 130


Machine Translated by Google

Section 28.5 : Lire une collection

Récupérez tous les documents de la collection « myCollection » et imprimez­les sur la console.

const MongoClient = require('mongodb').MongoClient;

const url = 'mongodb://localhost:27017/test';

MongoClient.connect(url, fonction (erreur, db) {


if (err) lance une nouvelle erreur (err);
var curseur = db.collection('myCollection').find(); // Lire la méthode 'find' curseur.each(function
(err, doc) { if (err) throw new Error(err); if
(doc != null) {

console.log(doc); // Imprimer tous les documents }


else
{ db.close(); // N'oubliez pas de fermer la connexion lorsque vous avez terminé

} }); });

Méthode de collecte find()

db.collection(collection).find()

Type d'argument Description


chaîne de collection Une chaîne spécifiant la collection

Article 28.6 : Mettre à jour un document


Recherchez un document avec la propriété { salutations : 'Bonjour' } et remplacez­le par { salutations : 'Quoi ?' }

const MongoClient = require('mongodb').MongoClient;

const url = 'mongodb://localhost:27017/test';

MongoClient.connect(url, function (err, db) { if (err) throw


new Error(err);
db.collection('myCollection').updateOne({ // Méthode de mise à jour 'updateOne'
salutations : "Bonjour" },
{ $set : { salutations : "Quoi ?" }}, function
(err, result) { if (err) throw new
Error(err); db.close(); // N'oubliez pas
de fermer la connexion lorsque vous avez terminé
});
});

Méthode de collecte updateOne()

db.collection(collection).updateOne(filtre, mise à jour, options. rappel)

Filtre Type de Description


paramètre objet Précise l'objet critères de sélection
mise à jour Précise les modifications à appliquer

Notes de GoalKicker.com Node.js pour les professionnels 131


Machine Translated by Google

objet options (facultatif) Paramètres facultatifs (par défaut : null) rappel


Fonction Fonction à appeler lorsque l'opération est terminée

La fonction de rappel prend deux arguments

err : Error ­ Si une erreur se produit, l'argument err sera défini db :


object ­ L'instance MongoDB

Article 28.7 : Supprimer un document

Supprimer un document avec la propriété { salutations : 'Quoi ?' }

const MongoClient = require('mongodb').MongoClient;

const url = 'mongodb://localhost:27017/test';

MongoClient.connect(url, function (err, db) { if (err) throw


new Error(err);
db.collection('myCollection').deleteOne(// Supprimer la méthode 'deleteOne'
{ salutations : "Quoi ?" },
function (err, result) { if (err)
throw new Error(err); db.close(); //
N'oubliez pas de fermer la connexion lorsque vous avez terminé
});
});

Méthode de collecte deleteOne()

db.collection(collection).deleteOne(filtre, options, rappel)

Filtre Type de Objet de


paramètre description Un document précisant les critères de sélection

objet options (facultatif) Paramètres facultatifs (par défaut : null) rappel


Fonction Fonction à appeler lorsque l'opération est terminée

La fonction de rappel prend deux arguments

err : Error ­ Si une erreur se produit, l'argument err sera défini db :


object ­ L'instance MongoDB

Section 28.8 : Supprimer plusieurs documents


Supprimez TOUS les documents dont la propriété « adieu » est définie sur « ok ».

const MongoClient = require('mongodb').MongoClient;

const url = 'mongodb://localhost:27017/test';

MongoClient.connect(url, function (err, db) { if (err) throw


new Error(err);
db.collection('myCollection').deleteMany(// Méthode de suppression MongoDB 'deleteMany'
{ adieu : "ok" }, // Supprimez TOUS les documents avec la propriété "adieu : ok" function (err, result) { if
(err) throw new Error(err);
db.close(); // N'oubliez pas de fermer
la connexion lorsque vous avez terminé

Notes de GoalKicker.com Node.js pour les professionnels 132


Machine Translated by Google

});
});

Méthode de collecte deleteMany()

db.collection(collection).deleteMany(filtre, options, rappel)

Filtre Type de Description


paramètre document Un document précisant les critères de sélection
Objet options (facultatif) Paramètres facultatifs (par défaut : null)
fonction de rappel Fonction à appeler lorsque l'opération est terminée

La fonction de rappel prend deux arguments

err : Erreur ­ Si une erreur se produit, l'argument err sera défini


db : objet ­ L'instance MongoDB

Notes de GoalKicker.com Node.js pour les professionnels 133


Machine Translated by Google

Chapitre 29 : Gestion des requêtes POST dans Node.js

Section 29.1 : Exemple de serveur node.js qui gère uniquement les


requêtes POST
« utiliser strict » ;

const http = exiger('http');

constPORT = 8080 ;
const server = http.createServer((request, réponse) => { let buffer = '';
request.on('data',
chunk => { buffer += chunk; });
request.on('end', ( )
=>
{
const réponseString = `Chaîne reçue ${buffer}` ; console.log(`Répondre
avec : ${responseString}`); réponse.writeHead(200, "Content­Type :
texte/plain"); réponse.end(responseString); }); }).listen(PORT, () =>
{ console.log(`Écoute sur ${PORT}`); });

Notes de GoalKicker.com Node.js pour les professionnels 134


Machine Translated by Google

Chapitre 30 : API CRUD simple basée sur REST


Section 30.1 : API REST pour CRUD dans Express 3+
var express = require("express"),
bodyParser = require("body­parser"), server
= express();

//analyseur de corps pour analyser le corps de


la requête server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));

//stockage temporaire de `item` en mémoire var


itemStore = [];

//OBTENIR tous
les éléments server.get('/item', function (req, res)
{ res.json(itemStore);
});

//OBTENEZ l'élément avec l'identifiant


spécifié server.get('/item/:id', function (req, res)
{ res.json(itemStore[req.params.id]);
});

//POST nouvel
élément server.post('/item', function (req, res)
{ itemStore.push(req.body);
res.json(req.body);
});

// METTRE l'élément modifié à la place de l'élément avec


l'identifiant spécifié server.put('/item/:id', function (req,
res) { itemStore[req.params.id] = req.body
res.json(req. corps);
});

//DELETE élément avec l'identifiant


spécifié server.delete('/item/:id', function (req, res)
{ itemStore.splice(req.params.id, 1)
res.json(req.body);
});

// DÉMARRER LE
SERVEUR server.listen (3000, function ()
{ console.log ("Serveur en cours d'exécution");
})

Notes de GoalKicker.com Node.js pour les professionnels 135


Machine Translated by Google

Chapitre 31 : Cadres de modèles


Article 31.1 : Nunjucks
Moteur côté serveur avec héritage de blocs, échappement automatique, macros, contrôle asynchrone, etc. Fortement inspiré de jinja2,
très similaire à Twig (php).

Documents ­ http://mozilla.github.io/nunjucks/
Installer ­ npm i nunjucks

Utilisation de base avec Express ci­dessous.

app.js

var express = exiger (« express »); var


nunjucks = require('nunjucks');

var app = express();


app.use(express.static('/public'));

// Appliquez des nunjucks et ajoutez un filtre et une fonction personnalisés (par


exemple). var env = nunjucks.configure(['views/'], { // définir des dossiers avec des modèles
échappement automatique :
vrai, express : application
});
env.addFilter('myFilter', function(obj, arg1, arg2) { console.log('myFilter',
obj, arg1, arg2); // Faire quelque chose avec obj
return obj;

});
env.addGlobal('myFunc', function(obj, arg1)
{ console.log('myFunc', obj, arg1); // Faire
quelque chose avec obj
return obj;
});

app.get('/', function(req, res)


{ res.render('index.html', {title: 'Page principale'});
});

app.get('/foo', function(req, res){


res.locals.smthVar = 'C'est Sparte !';
res.render('foo.html', {titre : 'Foo page'});
});

app.écouter(3000, fonction() {
console.log('Exemple d'application écoutant sur le port 3000...');
});

/views/index.html

<html>
<tête>
<title> Exemple de Nunjucks</title>
</head>
<body>
{% bloquer le contenu
%} {{title}}

Notes de GoalKicker.com Node.js pour les professionnels 136


Machine Translated by Google

{% endblock %} </
body> </
html>

/views/foo.html

{% étend "index.html" %}

{# Ceci est un commentaire


#} {% bloquer le contenu
%} <h1>{{title}}</h1> {#
appliquer la fonction personnalisée et les filtres intégrés et personnalisés suivants #}
{{ myFunc(smthVar) | inférieur | monFiltre(5, 'abc') }} {% endblock %}

Notes de GoalKicker.com Node.js pour les professionnels 137


Machine Translated by Google

Chapitre 32 : Architecture et fonctionnement interne de Node.js

Section 32.1 : Node.js ­ sous le capot

Section 32.2 : Node.js ­ en mouvement

Notes de GoalKicker.com Node.js pour les professionnels 138


Machine Translated by Google

Chapitre 33 : Débogage de l'application Node.js


Section 33.1 : Débogueur Core node.js et inspecteur de nœuds
Utilisation du débogueur principal

Node.js fournit un utilitaire de débogage non graphique intégré. Pour démarrer le build dans le débogueur, démarrez l'application avec cette
commande :

nom de fichier de débogage du nœud.js

Considérez l'application Node.js simple suivante contenue dans le fichier debugDemo.js

« utiliser strict » ;

function addTwoNumber(a, b){ // la fonction


renvoie la somme des deux nombres . le débogueur renvoie a + b ;

var résultat = addTwoNumber(5, 9);


console.log(résultat);

Le débogueur de mot­clé arrêtera le débogueur à ce stade du code.

Référence de commande

1. Faire un pas

cont, c ­ Continuer l'exécution suivante, n ­


Étape suivante, s ­ Entrer et
sortir, o ­ Sortir

2. Points d'arrêt

setBreakpoint(), sb() ­ Définir un point d'arrêt sur la ligne actuelle setBreakpoint(line),


sb(line) ­ Définir un point d'arrêt sur une ligne spécifique

Pour déboguer le code ci­dessus, exécutez la commande suivante

débogage du nœud debugDemo.js

Une fois les commandes ci­dessus exécutées, vous verrez la sortie suivante. Pour quitter l'interface du débogueur, tapez process.exit()

Notes de GoalKicker.com Node.js pour les professionnels 139


Machine Translated by Google

Utilisez la commande watch(expression) pour ajouter la variable ou l'expression dont vous souhaitez surveiller la valeur et redémarrer pour redémarrer l'application et le

débogage.

Utilisez repl pour saisir le code de manière interactive. Le mode repl a le même contexte que la ligne que vous déboguez. Cela vous permet d'examiner le contenu des variables et

de tester des lignes de code. Appuyez sur Ctrl+C pour quitter le remplacement de débogage.

Utilisation de l'inspecteur de nœud intégré


Version v6.3.0

Vous pouvez exécuter le nœud intégré inspecteur v8 ! L' inspecteur de nœuds le plug­in n’est plus nécessaire.

Passez simplement le drapeau de l'inspecteur et vous recevrez une URL vers l'inspecteur.

nœud ­­inspecter le serveur.js

Utilisation de l'inspecteur de nœuds

Installez l'inspecteur de nœuds :

npm install ­g inspecteur de nœud

Exécutez votre application avec la commande node­debug :

nom de fichier node­debug.js

Après cela, cliquez sur Chrome :

http://localhost:8080/debug?port=5858

Notes de GoalKicker.com Node.js pour les professionnels 140


Machine Translated by Google

Parfois, le port 8080 peut ne pas être disponible sur votre ordinateur. Vous pouvez obtenir l'erreur suivante :

Impossible de démarrer le serveur à 0.0.0.0:8080. Erreur : écoutez EACCES.

Dans ce cas, démarrez l'inspecteur de nœuds sur un autre port à l'aide de la commande suivante.

$node­inspector ­­web­port=6500

Vous verrez quelque chose comme ceci :

Notes de GoalKicker.com Node.js pour les professionnels 141


Machine Translated by Google

Chapitre 34 : Serveur de nœud sans framework

Section 34.1 : Serveur de nœuds sans framework


var http = require('http'); var fs =
require('fs'); var chemin =
require('chemin');

http.createServer(function (demande, réponse)


{ console.log('request ', request.url);

var cheminfichier = '.' + demande.url ; if


(filePath == './') filePath = './
index.html';

var nomext = String(path.extname(filePath)).toLowerCase(); var contentType


= 'texte/html'; var mimeTypes = { '.html' :
'text/html', '.js' : 'text/
javascript', '.css' : 'text/css',
'.json' : 'application/json', '. png' :
'image/png', '.jpg' :
'image/jpg', '.gif' : 'image/gif', '.wav' :
'audio/wav', '.mp4' :
'vidéo/ mp4', '.woff' :
'application/font­woff',
'.ttf' : 'applilcation/font­ttf',
'.eot' : 'application/vnd.ms­
fontobject', '.otf' : ' application/font­otf',
'.svg' : 'application/image/svg+xml'

contentType = mimeTypes[nom externe] || 'application/flux d'octects';

fs.readFile(filePath, function(erreur, contenu) { if (erreur)


{ if(error.code
== 'ENOENT'){
fs.readFile('./404.html', fonction(erreur, contenu) {
réponse.writeHead(200, { 'Content­Type': contentType });
réponse.end(content, 'utf­8');
});

} autre
{ réponse.writeHead(500);
réponse.end('Désolé, vérifiez auprès de l'administrateur du site l'erreur : '+error.code+' ..\n'); réponse.end();

} else
{ réponse.writeHead(200, { 'Content­Type': contentType });
réponse.end(content, 'utf­8');

} });

}).écouter(8125);
console.log('Serveur exécuté sur http://127.0.0.1:8125/');

Notes de GoalKicker.com Node.js pour les professionnels 142


Machine Translated by Google

Section 34.2 : Surmonter les problèmes CORS

// Site Web auquel vous souhaitez autoriser la


connexion à réponse.setHeader('Access­Control­Allow­Origin', '*');

// Requête des méthodes que vous souhaitez


autoriser Response.setHeader('Access­Control­Allow­Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

// En­têtes de requête que vous souhaitez


autoriser réponse.setHeader('Access­Control­Allow­Headers', 'X­Requested­With,content­type');

// Défini sur true si vous avez besoin que le site Web inclue des cookies dans les requêtes
envoyées // à l'API (par exemple si vous utilisez des
sessions) réponse.setHeader('Access­Control­Allow­Credentials', true);

Notes de GoalKicker.com Node.js pour les professionnels 143


Machine Translated by Google

Chapitre 35 : Node.JS avec ES6


ES6, ECMAScript 6 ou ES2015 est la dernière spécification pour JavaScript qui introduit du sucre syntaxique dans le langage. C'est une grosse mise à jour du

langage et introduit de nombreuses nouvelles fonctionnalités

Plus de détails sur Node et ES6 peuvent être trouvés sur leur site https://nodejs.org/en/docs/es6/

Section 35.1 : Support de Node ES6 et création d'un projet avec


Babel
L'ensemble de la spécification ES6 n'est pas encore entièrement implémenté, vous ne pourrez donc utiliser que certaines des nouvelles fonctionnalités.

Vous pouvez voir une liste des fonctionnalités ES6 actuellement prises en charge sur http://node.green/

Depuis NodeJS v6, le support est assez bon. Donc, si vous utilisez NodeJS v6 ou supérieur, vous pouvez profiter d'ES6.

Cependant, vous souhaiterez peut­être également utiliser certaines des fonctionnalités inédites et d’autres. Pour cela vous devrez utiliser un transpileur

Il est possible d'exécuter un transpilateur au moment de l'exécution et de la construction, d'utiliser toutes les fonctionnalités d'ES6 et bien plus encore. Le

transpileur le plus populaire pour JavaScript s'appelle Babel.

Babel vous permet d'utiliser toutes les fonctionnalités de la spécification ES6 et certaines fonctionnalités supplémentaires non
spécifiées avec 'stage­0' telles que l'importation d'un objet depuis 'thing au lieu de var thing = require('thing')

Si nous voulions créer un projet dans lequel nous utilisons des fonctionnalités « étape 0 » telles que l'importation, nous devrons ajouter Babel comme

transpilateur. Vous verrez des projets utilisant React et Vue et d'autres modèles basés sur CommonJS implémenter assez souvent l'étape 0.

créer un nouveau projet de nœud

mkdir mon­es6­app
cd mon­es6­app
npm init

Installez Babel le préréglage ES6 et stage­0

npm install ­­save­dev babel­preset­es2015 babel­preset­stage­2 babel­cli babel­register

Créez un nouveau fichier appelé server.js et ajoutez un serveur HTTP de base.

importer http depuis 'http'

http.createServer((req, res) => {


res.writeHead(200, {'Content­Type' : 'text/plain'}) res.end('Hello
World\n') }).listen(3000,
'127.0.0.1')

console.log('Serveur exécuté sur http://127.0.0.1:3000/')

Notez que nous utilisons une importation http depuis 'http'. Il s'agit d'une fonctionnalité de niveau 0 et si cela fonctionne, cela signifie que le
transpilateur fonctionne correctement.

Si vous exécutez node server.js, il échouera sans savoir comment gérer l'importation.

Créez un fichier .babelrc à la racine de votre répertoire et ajoutez les paramètres suivants

Notes de GoalKicker.com Node.js pour les professionnels 144


Machine Translated by Google

{
"presets": ["es2015", "stage­2"], "plugins": []

vous pouvez maintenant exécuter le serveur avec le nœud src/index.js ­­exec babel­node

Terminer ce n'est pas une bonne idée d'exécuter un transpilateur au moment de l'exécution sur une application de production. Nous pouvons cependant implémenter

certains scripts dans notre package.json pour faciliter le travail.

"scripts": { "start":
"node dist/index.js", "dev": "babel­node src/
index.js", "build": "babel src ­d dist", "postinstall":
" npm run build" },

Ce qui précède, lors de l'installation de npm , construira le code transpilé dans le répertoire dist, permettant à npm start d'utiliser le code transpilé
pour notre application de production.

npm run dev démarrera le serveur et le runtime babel, ce qui est très bien et préféré lorsque vous travaillez sur un projet localement.

En allant plus loin, vous pouvez ensuite installer nodemon npm install nodemon ­­save­dev pour surveiller les modifications, puis redémarrer
l'application de nœud.

Cela accélère vraiment le travail avec Babel et NodeJS. Dans votre package.json, mettez simplement à jour le script "dev" pour utiliser nodemon

"dev": "nodemon src/index.js ­­exec babel­node",

Section 35.2 : Utilisez JS es6 sur votre application NodeJS


JS es6 (également connu sous le nom d'es2015) est un ensemble de nouvelles fonctionnalités du langage JS visant à le rendre plus intuitif lors de l'utilisation de la POO ou

face à des tâches de développement modernes.

Conditions préalables:

1. Découvrez les nouvelles fonctionnalités d'es6 sur http://es6­features.org ­ cela peut vous clarifier si vous avez vraiment l'intention de l'utiliser sur votre prochaine

application NodeJS

2. Vérifiez le niveau de compatibilité de la version de votre nœud sur http://node.green

3. Si tout va bien, codons !

Voici un très court échantillon d'une simple application Hello World avec JS es6

'utiliser strict'

Programme de classe
{
constructeur() {

this.message = 'bonjour es6 :)';


}

imprimer()
{
setTimeout(() =>

Notes de GoalKicker.com Node.js pour les professionnels 145


Machine Translated by Google

{
console.log(ce.message);

this.print();

}, Math.random() * 1000);
}
}

nouveau programme().print();

Vous pouvez exécuter ce programme et observer comment il imprime le même message encore et encore.

Maintenant… décomposons­le ligne par ligne :

'utiliser strict'

Cette ligne est en fait requise si vous avez l'intention d'utiliser js es6. le mode strict , intentionnellement, a une sémantique différente
du code normal (veuillez en savoir plus sur MDN ­ https://
developer.mozilla.org/en­US/docs/Web/JavaScript/Reference/Strict_mode)

Programme de classe

Incroyable ­ un mot­clé de classe ! Juste pour une référence rapide ­ avant Es6, la seule façon de définir une classe en js était avec le mot­clé... function !

function MyClass() // définition de classe {

var maClasseObject = new MaClasse(); // génération d'un nouvel objet avec un type MyClass

Lors de l'utilisation de la POO, une classe est une capacité très fondamentale qui aide le développeur à représenter une partie spécifique d'un
système (la décomposition du code est cruciale lorsque le code devient plus volumineux... par exemple : lors de l'écriture de code côté serveur)

constructeur() {

this.message = 'bonjour es6 :)';


}

Vous devez l’admettre : c’est assez intuitif ! C'est le c'tor de ma classe ­ cette "fonction" unique se produira chaque fois qu'un objet est créé à partir de
cette classe particulière (dans notre programme ­ une seule fois)

imprimer()
{
setTimeout(() => // ceci est une fonction 'flèche' {

console.log(ce.message);

this.print(); // ici nous appelons la méthode 'print' à partir du modèle de classe lui­même (une récursion
dans ce cas particulier)

}, Math.random() * 1000);
}

Parce que print est défini dans la portée de la classe ­ il s'agit en fait d'une méthode ­ qui peut être invoquée depuis l'objet de

Notes de GoalKicker.com Node.js pour les professionnels 146


Machine Translated by Google

la classe ou depuis la classe elle­même !

Donc... jusqu'à présent, nous avons défini notre classe... il est temps de l'utiliser :

nouveau programme().print();

Ce qui équivaut véritablement à :

var prog = nouveau programme (); // définit un nouvel objet de type 'Programme'

prog.print(); // utilise le programme pour s'imprimer

En conclusion : JS es6 peut simplifier votre code ­ le rendre plus intuitif et facile à comprendre (par rapport à la version précédente de JS). Vous pouvez

essayer de réécrire votre code existant et voir la différence par vous­même.

APPRÉCIER :)

Notes de GoalKicker.com Node.js pour les professionnels 147


Machine Translated by Google

Chapitre 36 : Interagir avec la console


Article 36.1 : Journalisation
Module de console

Semblable à l'environnement de navigateur de JavaScript, node.js fournit un module de console qui offre des possibilités simples de journalisation et
de débogage.

Les méthodes les plus importantes fournies par le module console sont console.log, console.error et console.time.
Mais il en existe plusieurs autres comme console.info.

console.log

Les paramètres seront imprimés sur la sortie standard (stdout) avec une nouvelle ligne.

console.log('Bonjour tout le monde');

console.erreur

Les paramètres seront imprimés à l'erreur standard (stderr) avec une nouvelle ligne.

console.error('Oh, désolé, il y a une erreur.');

console.time, console.timeEnd

console.time démarre un minuteur avec une étiquette unique qui peut être utilisée pour calculer la durée d'une opération. Lorsque vous appelez
console.timeEnd avec la même étiquette, le minuteur s'arrête et imprime le temps écoulé en millisecondes sur
sortie standard.

Module de processus

Il est possible d'utiliser le module process pour écrire directement dans la sortie standard de la console. Il existe donc la méthode
process.stdout.write. Contrairement à console.log, cette méthode n'ajoute pas de nouvelle ligne avant votre sortie.

Ainsi, dans l’exemple suivant, la méthode est appelée deux fois, mais aucune nouvelle ligne n’est ajoutée entre leurs sorties.

Mise en page

On peut utiliser des codes de terminal (de contrôle) pour émettre des commandes spécifiques comme changer de couleur ou positionner le curseur.

Notes de GoalKicker.com Node.js pour les professionnels 148


Machine Translated by Google

Général
Code d'effet
Réinitialiser \033[0m

Hicolor \033[1m
Souligner \033[4m
Inverse \033[7m
Couleurs de police

Code d'effet
Noir \033[30m
Rouge \033[31min

Vert \033[32m
Jaune \033[33m
Bleu \033[34min

Magenta \033[35m
Cyan \033[36 min

Blanc \033[37m

Couleurs d'arrière­plan
Code d'effet
Noir \033[40m
Rouge \033[41min

Vert \033[42m
Jaune \033[43m
Bleu \033[44min

Magenta \033[45m
Cyan \033[46min

Blanc \033[47m

Notes de GoalKicker.com Node.js pour les professionnels 149


Machine Translated by Google

Chapitre 37 : Intégration de Cassandra


Article 37.1 : Bonjour tout le monde

Pour accéder à Cassandra cassandra­driver Le module de DataStax peut être utilisé. Il prend en charge toutes les fonctionnalités et peut
être facilement configuré.

const cassandra = require("cassandra­driver"); const


clientOptions = { contactPoints :
["host1", "host2"], espace de clés : "test"

const client = nouveau cassandra.Client(clientOptions);

const query = "SELECT hello FROM world WHERE name = ?";


client.execute(query, ["John"], (err, results) => { if (err) { return

console.error(err);
}

console.log(results.rows);
});

Notes de GoalKicker.com Node.js pour les professionnels 150


Machine Translated by Google

Chapitre 38 : Création d'API avec Node.js


Section 38.1 : OBTENIR l'API à l'aide d'Express
Les API Node.js peuvent être facilement construites dans le framework Web Express .

L'exemple suivant crée une API GET simple pour répertorier tous les utilisateurs.

Exemple

var express = require('express'); var app


= express();

var users

=[{ identifiant : 1,
nom :
"John Doe", âge : 23, email : "john@doe.com"
}];

// GET /api/users
app.get('/api/users', function(req, res){ return
res.json(users); //renvoie la réponse au format JSON
});

app.listen('3000', function()
{ console.log('Serveur en écoute sur le port 3000');
});

Section 38.2 : API POST utilisant Express


L'exemple suivant crée une API POST à l'aide d'Express. Cet exemple est similaire à l'exemple GET , à l'exception de l'utilisation d' un analyseur
de corps qui analyse les données de publication et les ajoute à req.body.

Exemple

var express = require('express'); var app


= express(); // pour
analyser le corps dans la requête POST var
bodyParser = require('body­parser');

var users

=[{ identifiant : 1,
nom :
"John Doe", âge : 23, email : "john@doe.com"
}];

app.use(bodyParser.urlencoded({ extended: false }));


app.use(bodyParser.json());

// GET /api/users
app.get('/api/users', function(req, res){ return
res.json(users);
});

/* POST /api/utilisateurs

Notes de GoalKicker.com Node.js pour les professionnels 151


Machine Translated by Google

{
"user":
{ "id": 3,
"name": "Utilisateur test",
"age" : 20,
"email": "test@test.com"
}
}
*/
app.post('/api/users', function (req, res) { var user =
req.body.user; users.push(user);

return res.send('L'utilisateur a été ajouté avec succès');


});

app.listen('3000', function()
{ console.log('Serveur en écoute sur le port 3000');
});

Notes de GoalKicker.com Node.js pour les professionnels 152


Machine Translated by Google

Chapitre 39 : Arrêt progressif


Section 39.1 : Arrêt progressif ­ SIGTERM

En utilisant server.close() et process.exit(), nous pouvons intercepter l'exception du serveur et effectuer un arrêt progressif.

var http = require('http');

var server = http.createServer(function (req, res)


{ setTimeout(function () { //simuler une requête longue
res.writeHead(200, {'Content­Type' : 'text/plain'}); res.end('Bonjour
tout le monde\n'); },

4000); }).écouter(9090, fonction (erreur) {


console.log('écoute http://localhost:9090/'); console.log('pid
'
est + process.pid); });

process.on('SIGTERM', function ()
{ server.close(function ()
{ process.exit(0); }); });

Notes de GoalKicker.com Node.js pour les professionnels 153


Machine Translated by Google

Chapitre 40 : Utilisation d'IISNode pour héberger des applications Web Node.js dans
IIS

Section 40.1 : Utilisation d'un répertoire virtuel IIS ou d'une


application imbriquée via <appSettings>
L’utilisation d’un répertoire virtuel ou d’une application imbriquée dans IIS est un scénario courant et très probablement dont vous souhaiterez tirer parti
lorsque vous utiliserez IISNode.

IISNode ne fournit pas de support direct pour les répertoires virtuels ou les applications imbriquées via la configuration. Pour y parvenir, nous devrons profiter
d'une fonctionnalité d'IISNode qui ne fait pas partie de la configuration et est beaucoup moins connue. Tous les enfants de l' élément <appSettings>
avec Web.config sont ajoutés à l' objet process.env en tant que propriétés à l'aide de la clé appSetting.

Créons un répertoire virtuel dans notre <appSettings>

<appSettings>
<add key="virtualDirPath" value="/foo" />
</appSettings>

Dans notre application Node.js, nous pouvons accéder au paramètre virtualDirPath

console.log(process.env.virtualDirPath); // imprime /foo

Maintenant que nous pouvons utiliser l' élément <appSettings> pour la configuration, profitons­en et utilisons­le dans notre
code du serveur.

// Accédez aux appSettings de virtualDirPath et donnez­lui la valeur par défaut de '/' // dans le cas où
il n'existe pas ou n'est pas défini var virtualDirPath =
process.env.virtualDirPath || '/';

// Nous voulons également nous assurer que notre virtualDirPath //


commence toujours par une barre oblique if (!
virtualDirPath.startsWith('/', 0)) virtualDirPath = '/' +
virtualDirPath;

// Configurer une route à l'index de notre application


server.get(virtualDirPath, (req, res) => {
return res.status(200).send('Hello World');
});

Nous pouvons également utiliser virtualDirPath avec nos ressources statiques

// Annuaire public
server.use(express.static(path.join(virtualDirPath, 'public'))); // Bower server.use('/

bower_components', express.static(path.join(virtualDirPath, 'bower_components')));

Mettons tout cela ensemble

const express = require('express'); const serveur


= express();

const port = processus.env.PORT || 3000 ;

Notes de GoalKicker.com Node.js pour les professionnels 154


Machine Translated by Google

// Accédez aux appSettings de virtualDirPath et donnez­lui la valeur par défaut de '/' // dans le cas où il
n'existe pas ou n'est pas défini var virtualDirPath =
process.env.virtualDirPath || '/';

// Nous voulons également nous assurer que notre virtualDirPath //


commence toujours par une barre oblique if (!
virtualDirPath.startsWith('/', 0))
virtualDirPath = '/' + virtualDirPath ;

// Annuaire public
server.use(express.static(path.join(virtualDirPath, 'public'))); // Bower server.use('/

bower_components', express.static(path.join(virtualDirPath, 'bower_components')));

// Configurer une route à l'index de notre application


server.get(virtualDirPath, (req, res) => {
return res.status(200).send('Hello World');
});

server.listen(port, () =>
{ console.log(`Écoute sur ${port}`);
});

Article 40.2 : Démarrage


IISNœud permet aux applications Web Node.js d'être hébergées sur IIS 7/8, tout comme le ferait une application .NET. Bien sûr, vous pouvez auto­héberger

votre processus node.exe sous Windows, mais pourquoi le faire alors que vous pouvez simplement exécuter votre application dans IIS.

IISNode gérera la mise à l'échelle sur plusieurs cœurs, la gestion des processus de node.exe et recyclera automatiquement votre application
IIS chaque fois que votre application est mise à jour, pour ne citer que quelques­uns de ses avantages.

Exigences

IISNode a quelques exigences avant de pouvoir héberger votre application Node.js dans IIS.

1. Node.js doit être installé sur l'hôte IIS, 32 bits ou 64 bits, les deux sont pris en charge.
2. IISNode installé x86 ou x64, cela devrait correspondre au nombre de bits de votre hôte IIS.
3. Le module de réécriture d'URL Microsoft pour IIS installé sur votre hôte IIS.
C'est la clé, sinon les requêtes adressées à votre application Node.js ne fonctionneront pas comme prévu.
4. Un Web.config dans le dossier racine de votre application Node.js.

5. Configuration IISNode via un fichier iisnode.yml ou un élément <iisnode> dans votre Web.config.

Section 40.3 : Exemple de base de Hello World utilisant Express


Pour que cet exemple fonctionne, vous devrez créer une application IIS 7/8 sur votre hôte IIS et ajouter le répertoire contenant l'application Web Node.js
en tant que répertoire physique. Assurez­vous que votre identité d’application/pool d’applications peut accéder à l’installation de Node.js. Cet exemple
utilise l'installation Node.js 64 bits.

Structure du projet

Il s'agit de la structure de projet de base d'une application Web IISNode/Node.js. Il semble presque identique à n’importe quelle application
Web non­IISNode, à l’exception de l’ajout du Web.config.

­ /app_root ­
package.json ­
serveur.js

Notes de GoalKicker.com Node.js pour les professionnels 155


Machine Translated by Google

­Web.config _

server.js ­ Application express

const express = require('express'); const serveur =


express();

// Nous devons obtenir le port que IISNode nous transmet // en utilisant la variable
d'environnement PORT, si elle n'est pas définie, utilisez une valeur par défaut const port = process.env.PORT ||
3000 ;

// Configurer une route à l'index de notre application


server.get('/', (req, res) => { return
res.status(200).send('Hello World');
});

server.listen(port, () => { console.log(`Écoute


sur ${port}`);
});

Configuration et Web.config

Le Web.config est comme n'importe quel autre Web.config IIS , sauf que les deux éléments suivants doivent être présents, une URL
<rewrite><rules> et un IISNode <handler>. Ces deux éléments sont des enfants de l' élément <system.webServer> .

Configuration

Vous pouvez configurer IISNode en utilisant un iisnode.yml fichier ou en ajoutant le <iisnode> élément en tant qu'enfant de
<system.webServer> dans votre Web.config. Ces deux configurations peuvent être utilisées conjointement. Cependant, dans ce cas, Web.config devra
spécifier le fichier iisnode.yml ET tout conflit de configuration sera extrait du fichier iisnode.yml. iisnode.yml fichier à la place. Ce remplacement de
configuration ne peut pas se produire dans l’autre sens.

Gestionnaire de nœuds IISNode

Pour qu'IIS sache que server.js contient notre application Web Node.js, nous devons le lui dire explicitement. Nous pouvons le faire en ajoutant IISNode
<handler> à l' élément <handlers> .

<gestionnaires>
<add name="iisnode" path="server.js" verb="*" modules="iisnode"/> </handlers>

Règles de réécriture d'URL

La dernière partie de la configuration consiste à garantir que le trafic destiné à notre application Node.js entrant dans notre instance IIS est dirigé vers IISNode.
Sans règles de réécriture d'URL, nous aurions besoin de visiter notre application en accédant à http://<host>/server.js et pire encore,
lorsque vous essayez de demander une ressource fournie par server.js , vous obtiendrez un 404. C'est pourquoi la réécriture d'URL est nécessaire pour
les applications Web IISNode.

<réécrire>
<règles>
<!­­ Nous examinons d'abord si l'URL entrante correspond à un fichier physique dans le dossier /public
­­>
<rule name="StaticContent" patternSyntax="Wildcard">
<action type="Rewrite" url="public/{R:0}" logRewritingUrl="true"/> <conditions>

<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>


</conditions>
<match url="*.*"/>
</règle>

Notes de GoalKicker.com Node.js pour les professionnels 156


Machine Translated by Google

<!­­ Toutes les autres URL sont mappées au point d'entrée de l'application Node.js ­­> <rule
name="DynamicContent"> <conditions>

<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>


</conditions>
<action type="Rewrite" url="server.js"/> </rule> </rules> </
rewrite>

C'est un travail Web.config fichier pour cet exemple, configuration pour une installation Node.js 64 bits.

Voilà, visitez maintenant votre site IIS et voyez votre application Node.js fonctionner.

Section 40.4 : Utilisation de Socket.io avec IISNode


Pour que Socket.io fonctionne avec IISNode, les seules modifications nécessaires lorsque vous n'utilisez pas de répertoire virtuel/application
imbriquée se trouvent dans le fichier Web.config.

Étant donné que Socket.io envoie des requêtes commençant par /socket.io, IISNode doit communiquer à IIS que celles­ci doivent également être
gérées par IISNode et ne sont pas uniquement des requêtes de fichiers statiques ou autre trafic. Cela nécessite un <handler> différent de celui des
applications IISNode standard.

<gestionnaires>
<add name="iisnode­socketio" path="server.js" verb="*" modules="iisnode" />
</gestionnaires>

En plus des modifications apportées aux <handlers>, nous devons également ajouter une règle de réécriture d'URL supplémentaire. La règle de
réécriture envoie tout le trafic /socket.io vers notre fichier serveur sur lequel le serveur Socket.io est exécuté.

<rule name="SocketIO" patternSyntax="ECMAScript"> <match url="socket.io.


+"/> <action type="Rewrite" url="server.js"/
>
</règle>

Si vous utilisez IIS 8, vous devrez désactiver votre paramètre webSockets dans votre Web.config en plus d'ajouter le gestionnaire ci­dessus et les
règles de réécriture. Ceci n'est pas nécessaire dans IIS 7 puisqu'il n'y a pas de support webSocket.

<webSocket activé="false" />

Notes de GoalKicker.com Node.js pour les professionnels 157


Machine Translated by Google

Chapitre 41 : CLI
Section 41.1 : Options de ligne de commande
­v, ­­version

Ajouté dans : v0.1.3 Version du nœud d'impression.

­h, ­­aide

Ajouté dans : v0.1.3 Options de ligne de commande du nœud d'impression. Le résultat de cette option est moins détaillé que ce document.

­e, ­­eval "script"

Ajouté dans : v0.5.2 Évaluez l'argument suivant en tant que JavaScript. Les modules prédéfinis dans le REPL peuvent également être utilisés en script.

­p, ­­print "script"

Ajouté dans : v0.6.4 Identique à ­e mais imprime le résultat.

­c, ­­vérifier

Ajouté dans : v5.0.0 La syntaxe vérifie le script sans l'exécuter.

­i, ­­interactif

Ajouté dans : v0.7.7 Ouvre le REPL même si stdin ne semble pas être un terminal.

­r, ­­require le module

Ajouté dans : v1.6.0 Préchargez le module spécifié au démarrage.

Suit les règles de résolution du module require(). module peut être soit un chemin d'accès à un fichier, soit un nom de module de nœud.

­­pas de dépréciation

Ajouté dans : v0.8.0 Avertissements de dépréciation silencieux.

­­trace­dépréciation

Ajouté dans : v0.8.0 Imprimer les traces de pile pour les dépréciations.

­­lancer­dépréciation

Ajouté dans : v0.11.14 Génère des erreurs pour les dépréciations.

­­pas d'avertissements

Ajouté dans : v6.0.0 Faites taire tous les avertissements de processus (y compris les dépréciations).

­­trace­avertissements

Notes de GoalKicker.com Node.js pour les professionnels 158


Machine Translated by Google

Ajouté dans : v6.0.0 Imprimer les traces de pile pour les avertissements de processus (y compris les dépréciations).

­­trace­sync­io

Ajouté dans : v2.1.0 Imprime une trace de pile chaque fois que des E/S synchrones sont détectées après le premier tour de la boucle d'événements.

­­zero­fill­buffers

Ajouté dans : v6.0.0 Remplit automatiquement à zéro toutes les instances Buffer et SlowBuffer nouvellement allouées.

­­preserve­symlinks

Ajouté dans : v6.3.0 Demande au chargeur de module de conserver les liens symboliques lors de la résolution et de la mise en cache des modules.

Par défaut, lorsque Node.js charge un module à partir d'un chemin qui est symboliquement lié à un emplacement différent sur le disque, Node.js déréférencera

le lien et utilisera le "chemin réel" réel du module sur le disque comme identifiant. et comme chemin racine pour localiser d'autres modules de dépendance. Dans la

plupart des cas, ce comportement par défaut est acceptable. Cependant, lors de l'utilisation de dépendances homologues liées symboliquement, comme illustré

dans l'exemple ci­dessous, le comportement par défaut provoque la levée d'une exception si moduleA tente d'exiger moduleB comme dépendance homologue :

{appDir}
├──
app │ ├── index.js
│ └── node_modules │
├── moduleA ­> {appDir}/moduleA │ └── moduleB
│ ├── index.js │
package.json └ ── moduleA
└──
├── index.js

└──
package.json

L'indicateur de ligne de commande ­­preserve­symlinks demande à Node.js d'utiliser le chemin du lien symbolique pour les modules par opposition au chemin réel,

permettant ainsi de trouver les dépendances homologues liées symboliquement.

Notez cependant que l'utilisation de ­­preserve­symlinks peut avoir d'autres effets secondaires. Plus précisément, les modules natifs liés symboliquement peuvent

ne pas se charger s'ils sont liés à partir de plusieurs emplacements dans l'arborescence des dépendances (Node.js les verrait comme deux modules distincts et

tenterait de charger le module plusieurs fois, provoquant la levée d'une exception). ).

­­track­heap­objets

Ajouté dans : v2.4.0 Suivez les allocations d'objets de tas pour les instantanés de tas.

­­prof­processus

Ajouté dans : v6.0.0 Traiter la sortie du profileur v8 générée à l'aide de l'option v8 ­­prof.

­­v8­options

Ajouté dans : v0.1.3 Imprimer les options de ligne de commande v8.

Remarque : les options v8 permettent de séparer les mots par des tirets (­) ou des traits de soulignement (_).

Notes de GoalKicker.com Node.js pour les professionnels 159


Machine Translated by Google

Par exemple, ­­stack­trace­limit est équivalent à ­­stack_trace_limit.

­­tls­cipher­list=liste

Ajouté dans : v4.0.0 Spécifiez une autre liste de chiffrement TLS par défaut. (Nécessite que Node.js soit construit avec la prise en charge du chiffrement.

(Défaut))

­­enable­fips

Ajouté dans : v6.0.0 Activer le chiffrement compatible FIPS au démarrage. (Nécessite que Node.js soit construit avec ./configure ­­openssl­fips)

­­force­fips

Ajouté dans : v6.0.0 Forcer le chiffrement conforme à FIPS au démarrage. (Ne peut pas être désactivé à partir du code de script.) (Mêmes exigences que ­­enable­fips)

­­icu­data­dir=fichier

Ajouté dans : v0.11.15 Spécifiez le chemin de chargement des données ICU. (remplace NODE_ICU_DATA)

Variables d'environnement

NODE_DEBUG=module[,…]

Ajouté dans : v0.1.32, liste séparée par ',' des modules de base qui doivent imprimer les informations de débogage.

NODE_PATH=chemin[:…]

Ajouté dans : v0.1.32 ':' ­ liste de répertoires séparés avec préfixe au chemin de recherche du module.

Remarque : sous Windows, il s'agit plutôt d'une liste séparée par des points ;

NODE_DISABLE_COLORS=1

Ajouté dans : v0.3.0 Lorsqu'elles sont définies sur 1, les couleurs ne seront pas utilisées dans le REPL.

NODE_ICU_DATA=fichier

Ajouté dans : v0.11.15 Chemin de données pour les données ICU (objet international). Étendra les données liées une fois compilées avec le support small­icu.

NODE_REPL_HISTORY=fichier

Ajouté dans : v5.0.0 Chemin d'accès au fichier utilisé pour stocker l'historique REPL persistant. Le chemin par défaut est ~/.node_repl_history, qui est remplacé par cette

variable. La définition de la valeur sur une chaîne vide ("" ou " ") désactive l'historique REPL persistant.

Notes de GoalKicker.com Node.js pour les professionnels 160


Machine Translated by Google

Chapitre 42 : Frameworks NodeJS


Section 42.1 : Frameworks de serveur Web

Exprimer
var express = require('express'); var app
= express();

app.get('/', function (req, res)


{ res.send('Hello World!'); });

app.listen(3000, function ()
{ console.log('Exemple d'application écoutant sur le port
3000 !'); });

Koa

var koa = require('koa'); var


app = koa();

app.use(function *(next){ var


start = new Date;
rendement
suivant; var ms = new Date ­
start; console.log('%s %s ­ %s', this.method, this.url, ms ); });

app.use(function *()
{ this.body = 'Hello World'; });

app.écouter (3000);

Section 42.2 : Cadres d'interface de ligne de commande

Commandant.js
var programme = require('commander');

programme .version('0.0.1')

programme .command('salut') .description('initialiser la


configuration du
projet') .action(function(){ console.log('Salut mon ami!!!');
});

programme .command('au
revoir [nom]') .description('initialiser la configuration du
projet') .action(function(nom)
{ console.log('Au revoir +' nom + '. C'était un plaisir de te voir!');
});

programme .command('*')

Notes de GoalKicker.com Node.js pour les professionnels 161


Machine Translated by Google

.action(function(env)
{ console.log('Entrez une commande valide');
terminate(true);
});

programme.parse(process.argv);

Vorpal.js
const vorpal = require('vorpal')();

vorpal .command('foo', 'Sorties


"bar".') .action(function(args, callback)
{ this.log('bar');
callback(); });

vorpal .delimiter('myapp$') .show();

Notes de GoalKicker.com Node.js pour les professionnels 162


Machine Translated by Google

Chapitre 43 : grognement

Section 43.1 : Introduction à GruntJs


Grunt est un Task Runner JavaScript, utilisé pour l'automatisation de tâches répétitives telles que la minification, la compilation, les tests unitaires, le
peluchage, etc.

Pour commencer, vous devez installer l'interface de ligne de commande (CLI) de Grunt globalement.

npm install ­g grognement­cli

Préparation d'un nouveau projet Grunt : une configuration typique impliquera l'ajout de deux fichiers à votre projet : package.json et le Gruntfile.

package.json : ce fichier est utilisé par npm pour stocker les métadonnées des projets publiés sous forme de modules npm. Vous listerez Grunt et
les plugins Grunt dont votre projet a besoin en tant que devDependencies dans ce fichier.

Gruntfile : Ce fichier s'appelle Gruntfile.js et est utilisé pour configurer ou définir des tâches et charger des plugins Grunt.

Exemple de package.json :

{
"name": "nom­de­mon­projet",
"version": "0.1.0",
"devDependencies":
{ "grunt": "~0.4.5",
"grunt­contrib­jshint": "~0.10. 0", "grunt­
contrib­nodeunit": "~0.4.1", "grunt­contrib­
uglify": "~0.5.0"
}
}

Exemple de fichier grognement :

module.exports = fonction (grunt) {

//Configuration du projet.
grognement.initConfig({
pkg : grunt.file.readJSON('package.json'), uglify :
{ options :
{ bannière : '/
* ! <%= pkg.name %> <%= grunt.template.today("aaaa­mm­jj") %> */\n' }, build : { src: 'src/<%=

pkg.name
%> .js', destination : 'build/<%=
pkg.name %>.min.js'
}

} });

// Charge le plugin qui fournit la tâche "uglify".


grunt.loadNpmTasks('grunt­contrib­uglify');

// Tâche(s) par défaut.


grunt.registerTask('default', ['uglify']);

Notes de GoalKicker.com Node.js pour les professionnels 163


Machine Translated by Google

Section 43.2 : Installation des grognementsplugins

Ajout de dépendance

Pour utiliser un gruntplugin, vous devez d'abord l'ajouter en tant que dépendance à votre projet. Utilisons le plugin jshint comme exemple.

npm install grunt­contrib­jshint ­­save­dev

L' option ­­save­dev est utilisée pour ajouter le plugin dans le package.json, de cette façon, le plugin est toujours installé après une
installation npm .

Chargement du plugin

Vous pouvez charger votre plugin dans le fichier gruntfile en utilisant loadNpmTasks.

grunt.loadNpmTasks('grunt­contrib­jshint');

Configuration de la tâche

Vous configurez la tâche dans le fichier grunt en ajoutant une propriété appelée jshint à l'objet transmis à grunt.initConfig.

grunt.initConfig({ jshint :
{ all :
['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js']

} });

N'oubliez pas que vous pouvez avoir d'autres propriétés pour les autres plugins que vous utilisez.

Exécuter la tâche

Pour exécuter simplement la tâche avec le plugin, vous pouvez utiliser la ligne de commande.

grognement jshint

Ou vous pouvez ajouter jshint à une autre tâche.

grunt.registerTask('default', ['jshint']);

La tâche par défaut s'exécute avec la commande grunt dans le terminal sans aucune option.

Notes de GoalKicker.com Node.js pour les professionnels 164


Machine Translated by Google

Chapitre 44 : Utiliser WebSocket avec Node.JS

Section 44.1 : Installation de WebSocket


Il existe plusieurs façons d'installer WebSocket sur votre projet. Voici quelques exemples:

npm install ­­save ws

ou dans votre package.json en utilisant :

"dépendances":
{ "ws": "*"
},

Section 44.2 : Ajout de WebSocket à ceux de votre fichier


Pour ajouter ws à votre fichier, utilisez simplement :

var ws = require('ws');

Section 44.3 : Utilisation de WebSocket et de WebSocket Server


Pour ouvrir un nouveau WebSocket, ajoutez simplement quelque chose comme :

var WebSocket = require("ws"); var ws


= new WebSocket("ws://host:8080/OptionalPathName); // Continuez avec
votre code...

Ou pour ouvrir un serveur, utilisez :

var WebSocketServer = require("ws").Server; var ws =


new WebSocketServer({port : 8080, chemin : "OptionalPathName"});

Section 44.4 : Un exemple simple de serveur WebSocket


var WebSocketServer = require('ws').Server
, wss = nouveau WebSocketServer({ port : 8080 }); // Si vous souhaitez également ajouter un chemin, utilisez path :
"Nom du chemin"

wss.on('connexion', function connection(ws) { ws.on('message',


function incoming(message) { console.log('received: %s',
message); });

ws.send('quelque chose'); });

Notes de GoalKicker.com Node.js pour les professionnels 165


Machine Translated by Google

Chapitre 45 : forgeron
Section 45.1 : Créer un blog simple
En supposant que node et npm soient installés et disponibles, créez un dossier de projet avec un package.json valide.
Installez les dépendances nécessaires :

npm install ­­save­dev metalsmith guidon metalsmith­in­place

Créez un fichier appelé build.js à la racine de votre dossier de projet, contenant les éléments suivants :

var forgeron = require('forgeron'); var guidon =


require('handlebars'); var inPlace = require('metalsmith­in­
place');

Metalsmith(__dirname) .use(inPlace('handlebars')) .build(function(err) { if (err) throw err; console.log('Build finish!'); });

Créez un dossier appelé src à la racine de votre dossier de projet. Créez index.html dans src, contenant les éléments suivants :

­­­
titre : Mon super blog
­­­

{{ titre }}

L’exécution de node build.js construira désormais tous les fichiers dans src. Après avoir exécuté cette commande, vous aurez index.html
dans votre dossier de build, avec le contenu suivant :

<h1>Mon super blog</h1>

Notes de GoalKicker.com Node.js pour les professionnels 166


Machine Translated by Google

Chapitre 46 : Analyse des arguments de ligne de commande

Section 46.1 : Passer une action (verbe) et des valeurs


const options = require("commandant");

options .option("­v, ­­verbose", "Soyez verbeux");

options .command("convert") .alias("c") .description("Convertit le


fichier d'entrée en fichier de sortie") .option("­i, ­­in­file
<file_name>", "Fichier d'entrée") . option("­o, ­­out­file <nom_fichier>",
"Fichier de sortie") .action(doConvert);

options.parse(process.argv);

if (!options.args.length) options.help();

fonction doConvert(options){
//faire quelque chose avec options.inFile et options.outFile

Section 46.2 : Passage de commutateurs booléens


const options = require("commandant");

options .option("­v, ­­
verbose") .parse(process.argv);

if (options.verbose)
{ console.log("Faisons du bruit !");
}

Notes de GoalKicker.com Node.js pour les professionnels 167


Machine Translated by Google

Chapitre 47 : Communication client­serveur Section 47.1 : /w Express,

jQuery et Jade
//'client.jade'

//un bouton est posé ; similaire en HTML


bouton(type='button', id='send_by_button') Modifier les données

#modifier l'expéditeur Lorem ipsum

//chargement de jQuery ; cela peut également être fait à partir d'une source en ligne
script(src='./js/jquery­2.2.0.min.js')

//Requête AJAX utilisant le script


jQuery
$(function () { $
('#send_by_button').click(function (e) {
e.preventDefault();

//test : le texte entre parenthèses doit apparaître en cliquant sur ledit bouton //window.alert('Vous
avez cliqué sur moi. ­ jQuery');

//une variable et un JSON initialisés dans le code var


predeclared = "Katamori"; données var
={
Titre : "Name_SenderTest",
Nick : prédéclaré,
Prénom : "Zoltan",
Nom de famille: "Schmidt"

//une requête AJAX avec les paramètres donnés

$.ajax({ type : 'POST',


data : JSON.stringify(data),
contentType : 'application/json', url : 'http://
localhost:7776/domaintest',

//en cas de succès, les données reçues sont utilisées comme « données » pour
la fonction d'entrée réussie :
function (data) { window.alert('Demande envoyée ; données reçues.');

var jsonstr = JSON.stringify(données); var


jsonobj = JSON.parse(jsonstr);

//si le membre 'nick' du JSON n'est pas égal à la chaîne prédéclarée (telle qu'elle a été initialisée),
alors le script backend a été exécuté, ce qui signifie que la communication a été établie

if(data.Nick != prédéclaré){
document.getElementById("modify").innerHTML = "JSON modifié !\n" +
jsonstr;

}
});

}); });

//'domaintest_route.js'

Notes de GoalKicker.com Node.js pour les professionnels 168


Machine Translated by Google

var express = require('express'); var routeur


= express.Router();

//un routeur Express écoutant les requêtes GET ­ dans ce cas, il est vide, ce qui signifie que rien ne s'affiche lorsque vous
atteignez 'localhost/domaintest' router.get('/', function(req,
res, next) { });

// idem pour les requêtes POST ­ remarquez comment la requête AJAX ci­dessus a été définie comme
POST router.post('/', function(req, res) {
res.setHeader('Content­Type', 'application/json');

//contenu généré ici var


some_json = {
Titre : "Test",
Objet : « Caisse »

var résultat = JSON.stringify(some_json);

//le contenu a obtenu 'client.jade'


var sent_data = req.body;
sent_data.Nick = "ttony33";

res.send(sent_data);

});

module.exports = routeur ;

//basé sur un résumé utilisé personnellement : https://gist.github.com/Katamori/5c9850f02e4baf6e9896

Notes de GoalKicker.com Node.js pour les professionnels 169


Machine Translated by Google

Chapitre 48 : Fondamentaux de la conception Node.js

Section 48.1 : La philosophie Node.js


Petit noyau, petit module :

Créez des modules petits et à usage unique, non seulement en termes de taille de code, mais également en termes de portée qui sert un seul objectif.
but

a ­ "Petit est beau" b ­ "Faites


en sorte que chaque programme fasse bien une chose."

Le modèle de réacteur

Le modèle Reactor est au cœur de la nature asynchrone de node.js. Permet au système d'être implémenté en tant que processus
monothread avec une série de générateurs d'événements et de gestionnaires d'événements, à l'aide d'une boucle d'événements qui
s'exécute en continu.

Le moteur d'E/S non bloquant de Node.js – libuv ­

Le modèle Observer (EventEmitter) maintient une liste de dépendants/observateurs et les informe

var événements = require('événements');


var eventEmitter = new events.EventEmitter();

var ringBell = fonction ringBell() {

console.log('tring tring tring');

} eventEmitter.on('doorOpen', ringBell);

eventEmitter.emit('doorOpen');

Notes de GoalKicker.com Node.js pour les professionnels 170


Machine Translated by Google

Chapitre 49 : Se connecter à Mongodb


MongoDB est un programme de base de données orienté document multiplateforme gratuit et open source. Classé comme programme de base de
données NoSQL, MongoDB utilise des documents de type JSON avec des schémas.

Pour plus de détails, rendez­vous sur https://www.mongodb.com/

Section 49.1 : Exemple simple pour connecter mongoDB à partir


de Node.JS
MongoClient.connect('mongodb://localhost:27017/myNewDB',function (err,db) {
if(err)
"
console.log("Impossible de se connecter à la base de données. + euh)

Erreur : else console.log('Connecté à la base de données');

db.close();
});

myNewDB est le nom de la base de données, s'il n'existe pas dans la base de données, il sera créé automatiquement avec cet appel.

Section 49.2 : Un moyen simple de connecter mongoDB au noyau


Node.JS
var MongoClient = require('mongodb').MongoClient;

//connexion avec mongoDB


MongoClient.connect("mongodb://localhost:27017/MyDb", function (err, db) {
//vérifie la connexion
si(erreur){
console.log(" échec de la connexion.");
}autre{
console.log("Connecté avec succès à mongoDB.");
});

Notes de GoalKicker.com Node.js pour les professionnels 171


Machine Translated by Google

Chapitre 50 : Défis de performances


Section 50.1 : Traitement des requêtes de longue durée avec Node
Étant donné que Node est monothread, une solution de contournement est nécessaire s'il s'agit de calculs de longue durée.

Remarque : il s'agit d'un exemple "prêt à fonctionner". N'oubliez pas d'obtenir jQuery et d'installer les modules requis.

Logique principale de cet exemple :

1. Le client envoie la demande au serveur.


2. Le serveur démarre la routine dans une instance de nœud distincte et renvoie une réponse immédiate avec l'ID de tâche associé.
3. Le client envoie continuellement des chèques à un serveur pour les mises à jour de l'état de l'ID de tâche donné.

Structure du projet :

projet
│ package.json
│ index.html │

├───js
main.js
jquery­1.12.0.min.js

│ │ │ └───srv

│ app.js
├─── modèles
│ tâche.js
└─── tâches
processeur de données.js

app.js :

var express = exiger('exprimer');


application var = exprimer();
var http = require('http').Server(app);
var mangouste = require('mangouste');
var bodyParser = require('body­parser');

var childProcess= require('child_process');

varTâche _ = require('./models/tâche');

app.use(bodyParser.urlencoded({ extended : true }));


app.use(bodyParser.json());

app.use(express.static(__dirname + '/../'));

app.get('/', fonction(demande, réponse){


réponse.render('index.html');
});

//route pour la requête elle­même


app.post('/long­running­request', function(requête, réponse){
//crée un nouvel élément de tâche pour le suivi du statut
var t = new Task({ status: 'Starting ...' });

Notes de GoalKicker.com Node.js pour les professionnels 172


Machine Translated by Google

t.save(fonction(erreur, tâche){
//crée une nouvelle instance de nœud pour exécuter une tâche distincte dans un autre thread
taskProcessor = childProcess.fork('./srv/tasks/data­processor.js');

//traite les messages provenant du processeur de tâches


taskProcessor.on('message', function(msg){ task.status
= msg.status;

task.save(); }.bind(this));

//supprime l'instance de nœud précédemment ouverte lorsque nous avons


terminé taskProcessor.on('close', function(msg)
{ this.kill();
});

//envoyer quelques paramètres à notre tâche


distincte var
params = { message : 'Bonjour du fil principal'

taskProcessor.send(params);
réponse.status(200).json(tâche);
});
});

//route à vérifier si la requête est terminée, les calculs app.post('/is­ready',


function(request, réponse){
Tâche

.findById(request.body.id) .exec(function(err, task){ réponse.status(200).json(task);


});
});

mangouste.connect('mongodb://localhost/test');
http.écouter('1234');

tâche.js :

mangouste du Var = require('mangouste');

var taskSchema = mongoose.Schema


({ statut :
{ type : chaîne
}
});

mangouste.model('Tâche', taskSchema);

module.exports = mangouste.model('Tâche');

processeur de données.js :

process.on('message', function(msg){ init =


function()

{ processData(msg.message); }.bind(this)();

function processData(message){ //
envoyer la mise à jour du statut à l'application
principale process.send({ status: 'Nous avons commencé à traiter vos données.' });

Notes de GoalKicker.com Node.js pour les professionnels 173


Machine Translated by Google

// calculs longs ..
setTimeout(function()
{ process.send({ status: 'Done!' });

//notifie le nœud que nous avons terminé cette tâche


process.disconnect(); },
5000);
}
});

process.on('uncaughtException',function(err)
{ console.log("Une erreur s'est produite : " + err.message + "\n" + err.stack + ".\n"); console.log("
Terminer gracieusement la routine.");
});

index.html :

<!DOCTYPEhtml>
<html>
<head>
<script src="./js/jquery­1.12.0.min.js"></script> <script src="./js/
main.js"></script> </head> < body> <p>Exemple
de

traitement des requêtes de nœuds de longue durée.</p> <button id="go"


type="button">Exécuter</button>

<br />

<p>Journal :</
p> <textarea id="log" rows="20" cols="50"></textarea> </body> </
html>

main.js :

$(document).on('prêt', fonction(){

$('#go').on('cliquez', function(e){
//effacer le
journal $("#log").val('');

$.post("/long­running­request", {some_params: 'params' }) .done(function(task)


{ $("#log").val( $("#log").val()
+ '\n' + tâche.status);

//fonction pour suivre l'état de la tâche function updateStatus()


{ $.post("/is­ready", {id: task._id })

.done(function(response){ $
("#log").val( $("#log").val() + '\n' + réponse.status);

if(response.status != 'Terminé !')


{ checkTaskTimeout = setTimeout(updateStatus, 500);
}
});
}

//commence à vérifier la tâche


var checkTaskTimeout = setTimeout(updateStatus, 100);
});

Notes de GoalKicker.com Node.js pour les professionnels 174


Machine Translated by Google

});
});

package.json :

{
"name": "nodeProcessor",
"dependencies":
{ "body­parser": "^1.15.2",
"express": "^4.14.0", "html":
"0.0.10", "mongoose" :
"^4.5.5"
}
}

Avertissement : cet exemple est destiné à vous donner une idée de base. Pour l'utiliser dans un environnement de production, il nécessite
des améliorations.

Notes de GoalKicker.com Node.js pour les professionnels 175


Machine Translated by Google

Chapitre 51 : Envoyer une notification Web

Section 51.1 : Envoyer une notification Web à l'aide de GCM (Google Cloud Messaging
System)

Un tel exemple est largement répandu parmi les PWA (Progressive Web Applications) et dans cet exemple, nous allons envoyer une simple notification de

type Backend en utilisant NodeJS et ES6 .

1. Installer le module Node­GCM : npm install node­gcm

2. Installez Socket.io : npm install socket.io

3. Créez une application compatible GCM à l'aide de Google Console.

4. Saisissez votre identifiant d'application GCM (nous en aurons besoin plus tard)

5. Saisissez votre code secret d'application GCM.

6. Ouvrez votre éditeur de code préféré et ajoutez le code suivant :

« utiliser strict » ;

const express = require('express'); const app


= express(); const gcm =
require('node­gcm'); app.io =
require('socket.io')();

// [*] Configuration de notre canal GCM.


const sender = new gcm.Sender('Project Secret'); const
regTokens = []; let message
= nouveau gcm.Message({ data : { key1 :
'msg1'

}
});

// [*] Configuration de nos fichiers statiques.


app.use(express.static('public/'));

// [*] Configuration des itinéraires.


app.get('/', (req, res) =>
{ res.sendFile(__dirname + '/public/index.html');
});

// [*] Configuration de notre connexion Socket.


app.io.on('connection', socket =>
{ console.log('nous avons une nouvelle connexion...');
socket.on('new_user', (reg_id) => {
// [*] Ajout de notre jeton d'enregistrement de notification utilisateur à notre liste généralement cachée dans
un endroit secret.
if (regTokens.indexOf(reg_id) === ­1)
{ regTokens.push(reg_id);

// [*] Envoi de nos messages push


sender.send(message,
{ RegistrationTokens: regTokens },
(err, réponse) => { if (err)
console.error('err', err); else
console.log(response );
});

Notes de GoalKicker.com Node.js pour les professionnels 176


Machine Translated by Google

}
})
});

module.exports = application

PS : j'utilise ici un hack spécial afin de faire fonctionner Socket.io avec Express car tout simplement cela ne fonctionne pas en dehors des sentiers
battus.

Créez maintenant un fichier .json et nommez­le : Manifest.json, ouvrez­le et collez ce qui suit :

{
"name": "Nom de l'application",
"gcm_sender_id": "ID du projet GCM"
}

Fermez­le et enregistrez­le dans le répertoire ROOT de votre application .

PS : le fichier Manifest.json doit être dans le répertoire racine sinon il ne fonctionnera pas.

Dans le code ci­dessus, je fais ce qui suit :

1. J'ai configuré et envoyé une page index.html normale qui utilisera également socket.io.

2. J'écoute un événement de connexion déclenché depuis le front­end, c'est­à­dire ma page index.html (il sera déclenché une fois par jour).

nouveau client connecté avec succès à notre lien prédéfini)

3. J'envoie un jeton spécial connu comme jeton d'enregistrement de mon index.html via l'événement socket.io new_user , ce jeton sera le code d'accès

unique de notre utilisateur et chaque code est généralement généré à partir d'un navigateur prenant en charge l' API de notification Web ( en savoir
plus ici.

4. J'utilise simplement le module node­gcm pour envoyer ma notification qui sera traitée et affichée plus tard à l'aide de Service Workers`.

C'est du point de vue de NodeJS . dans d'autres exemples, je montrerai comment nous pouvons envoyer des données personnalisées, des icônes ..etc dans

notre message push.

PS : vous pouvez trouver la démo complète fonctionnelle ici .

Notes de GoalKicker.com Node.js pour les professionnels 177


Machine Translated by Google

Chapitre 52 : Débogage à distance dans Node.JS


Section 52.1 : Utiliser le proxy pour le débogage via le port sous Linux
Si vous démarrez votre application sous Linux, utilisez le proxy pour le débogage via le port, par exemple :

socat TCP­LISTEN:9958,fork TCP:127.0.0.1:5858 &

Utilisez alors le port 9958 pour le débogage à distance.

Section 52.2 : Configuration d'exécution de NodeJS


Pour configurer le débogage à distance du nœud, exécutez simplement le processus du nœud avec l' indicateur ­­debug . Vous pouvez ajouter un port
sur lequel le débogueur doit s'exécuter en utilisant ­­debug=<port>.

Lorsque votre processus de nœud démarre, vous devriez voir le message

Débogueur écoutant sur le port <port>

Ce qui vous dira que tout est prêt.

Ensuite, vous configurez la cible de débogage distant dans votre IDE spécifique.

Section 52.3 : Configuration d'IntelliJ/Webstorm


1. Assurez­vous que le plugin NodeJS est activé 2. Sélectionnez
vos configurations d'exécution (écran)

3. Sélectionnez + > Débogage à distance Node.js

Notes de GoalKicker.com Node.js pour les professionnels 178


Machine Translated by Google

4. Assurez­vous de saisir le port sélectionné ci­dessus ainsi que le bon hôte

Une fois ceux­ci configurés, exécutez simplement la cible de débogage comme vous le feriez normalement et elle s'arrêtera sur vos points d'arrêt.

Notes de GoalKicker.com Node.js pour les professionnels 179


Machine Translated by Google

Chapitre 53 : Base de données (MongoDB avec


Mangouste)
Section 53.1 : Connexion avec la mangouste
Assurez­vous que MongoDB soit exécuté en premier ! mongod ­­dbpath données/

package.json

"dépendances":
{ "mangouste": "^4.5.5",
}

serveur.js (ECMA 6)

importer une mangouste à partir de « mangouste » ;

mongoose.connect('mongodb://localhost:27017/stackoverflow­example'); const db =
mangouste.connection; db.on('erreur',
console.error.bind(console, 'Erreur de connexion à la base de données !'));

serveur.js (ECMA 5.1)

var mangouste = require('mangouste');

mongoose.connect('mongodb://localhost:27017/stackoverflow­example'); var db =
mangouste.connection; db.on('erreur',
console.error.bind(console, 'Erreur de connexion à la base de données !'));

Article 53.2 : Modèle


Définissez votre (vos) modèle(s) :

app/models/user.js (ECMA 6)

importer une mangouste à partir de « mangouste » ;

const userSchema = new mongoose.Schema ({ nom :


chaîne, mot de
passe : chaîne
});

const User = mangouste.model('Utilisateur', userSchema);

exporter l'utilisateur par défaut ;

app/model/user.js (ECMA 5.1)

var mangouste = require('mangouste');

var userSchema = new mongoose.Schema ({ nom :


chaîne, mot de
passe : chaîne
});

var Utilisateur = mongoose.model('Utilisateur', userSchema);

Notes de GoalKicker.com Node.js pour les professionnels 180


Machine Translated by Google

module.exports = Utilisateur

Article 53.3 : Insérer des données


ECMA6 :

const user = nouvel utilisateur


( { nom : 'Stack' ,
mot de passe : 'Overflow' } ) ,
;

user.save ( (err ) => { if (err )


throw err ;

console.log ('Utilisateur enregistré !' ) ;


});

ECMA5.1 :

var user = nouvel utilisateur


( { nom : 'Stack' ,
mot de passe : 'Overflow' } ) ,
;

user.save (function (err ) { if (err )


throw err ;

console.log ('Utilisateur enregistré !' ) ;


});

Section 53.4 : Lire les données


ECMA6 :

User.findOne
( { nom : 'stack' } ,
(err , user ) => { if (err )
throw err ;

if ( !user )
{ console.log ('Aucun utilisateur n'a été
trouvé' ) ; }
else { console.log ("L'utilisateur a été trouvé" ) ;
}
});

ECMA5.1 :

User.findOne
( { nom : 'stack'
} , function (err , user ) { if (err )
throw err ;

if ( !user )
{ console.log ('Aucun utilisateur n'a été
trouvé' ) ; }
else { console.log ("L'utilisateur a été trouvé" ) ;
}

Notes de GoalKicker.com Node.js pour les professionnels 181


Machine Translated by Google

});

Notes de GoalKicker.com Node.js pour les professionnels 182


Machine Translated by Google

Chapitre 54 : Bon style de codage


Article 54.1 : Programme de base pour l'inscription
A travers cet exemple, il sera expliqué comment diviser le code node.js en différents modules/dossiers pour une meilleure
compréhension. Suivre cette technique permet aux autres développeurs de comprendre plus facilement le code, car ils peuvent se
référer directement au fichier concerné au lieu de parcourir l'intégralité du code. L'utilisation principale est que lorsque vous travaillez
en équipe et qu'un nouveau développeur se joint à un stade ultérieur, il lui sera plus facile de se familiariser avec le code lui­même.

index.js : ce fichier gérera la connexion au serveur.

//Importer des bibliothèques


var express = require('express'), session =
require('express­session'), mangouste =
require('mangouste'), request = require('request');

//Importer des modules


personnalisés var userRoutes = require('./app/routes/userRoutes'); var config
= require('./app/config/config');

//Connectez­vous à la base de
données Mongo mongoose.connect(config.getDBString());

//Créez une nouvelle application Express et configurez­la var app = express();

//Configurer les routes


app.use(config.API_PATH, userRoutes());

//Démarrez le serveur
app.listen(config.PORT);
console.log('Le serveur a démarré à ­ '+ config.URL+ ":" +config.PORT);

config.js : ce fichier gérera tous les paramètres liés à la configuration qui resteront les mêmes tout au long.

var config =
{ VERSION : 1,

CONSTRUCTION : 1, URL : 'http://


127.0.0.1', API_PATH : '/
api', PORT : process.env.PORT || 8080, DB :
{ //
Configuration MongoDB HÔTE :
'localhost', PORT : '27017',
BASE DE DONNÉES :
'db'
},

/*
* Obtenez la chaîne de connexion DB pour vous connecter à la base de données MongoDB
*/
getDBString : fonction(){
return 'mongodb://'+ this.DB.HOST +':'+ this.DB.PORT +'/'+ this.DB.DATABASE;
},

/*
* Obtenez l'URL http

Notes de GoalKicker.com Node.js pour les professionnels 183


Machine Translated by Google
*/
getHTTPUrl : fonction(){
return 'http://' + this.URL + ":" + this.PORT;
}

module.exports = config;

user.js : fichier modèle où le schéma est défini

var mangouste = require('mangouste'); var


Schema = mangouste.Schema;

//Schéma pour
l'utilisateur var UserSchema = new

Schema({ name :
{ type : String, obligatoire : true

// }, email :
{ tapez : chaîne
},
mot de passe :
{ type : Chaîne, //
obligatoire : vrai
},
dob :
{ type : Date, //
obligatoire : vrai
},
genre :
{ type : Chaîne, // Homme/Femme
// } obligatoire : vrai

});

//Définissez le modèle pour


l'utilisateur
var User ; si (mangouste.models.User)
Utilisateur = mangouste.model('Utilisateur');
sinon
User = mongoose.model('User', UserSchema);

//Exporter le modèle utilisateur


module.exports = User;

userController : ce fichier contient la fonction d'inscription de l'utilisateur

var Utilisateur = require('../models/user'); var


crypto = require('crypto');

//Contrôleur pour l'utilisateur


var UserController = {

//Créer un utilisateur
create: function(req, res){ var
repassword = req.body.repassword; var mot de
passe = req.body.password; var userEmail
= req.body.email;

//Vérifiez si l'adresse e­mail existe déjà User.find({"email":


userEmail}, function(err, usr){

Notes de GoalKicker.com Node.js pour les professionnels 184


Machine Translated by Google

if(usr.length > 0){ //L'e­


mail existe

res.json('L'e­mail existe déjà'); retour;

} autre
{
//Nouveau courriel

//Vérifiez les mêmes mots de


passe if(password != repassword)
{ res.json('Les mots de passe ne correspondent
pas'); retour;
}

// Générer un hachage de mot de passe basé


sur sha1 var shasum = crypto.createHash('sha1');
shasum.update(req.body.password); var
passwordHash = shasum.digest('hex');

//Créer un
utilisateur var user = new
User(); nom d'utilisateur =
req.body.name ; utilisateur.email =
req.body.email; user.password =
passwordHash ; utilisateur.dob = Date.parse(req.body.dob)
|| "" ; utilisateur.gender = req.body.gender;

//Valider l'utilisateur
user.validate(function(err){ if(err)

{ res.json(err); return; }
else{ //
Enfin
enregistrer l'utilisateur
user.save(function(err){ if(err) {

res.json(err);
retour;
}

// Supprimez le mot de passe avant d'envoyer les détails de


l'utilisateur user.password =
undefined ;
res.json(utilisateur); retour;
});
}
});
}
});
}

module.exports = UserController ;

userRoutes.js : c'est l'itinéraire pour userController

var express = require('express');

Notes de GoalKicker.com Node.js pour les professionnels 185


Machine Translated by Google

var UserController = require('../controllers/userController');

//Routes pour l'utilisateur


var UserRoutes = function(app) {

var routeur = express.Router();

router.route('/
users') .post(UserController.create);

routeur de retour ;

module.exports = UserRoutes ;

L'exemple ci­dessus peut sembler trop gros, mais si un débutant sur node.js avec un petit mélange de connaissances expresses
essaie de suivre cela, il le trouvera facile et vraiment utile.

Notes de GoalKicker.com Node.js pour les professionnels 186


Machine Translated by Google

Chapitre 55 : Conception d'API reposante : la meilleure


Les pratiques

Section 55.1 : Gestion des erreurs : OBTENIR toutes les ressources


Comment gérez­vous les erreurs plutôt que de les enregistrer dans la console ?

Mauvaise façon :

Router.route('/') .get((req,
res) => { Request.find((err,
r) => { if(err){ console.log(err) } else
{ res.json(r )

} }) }) .post((req, res) =>


{ const request = new Request({ type :
req.body.type, info :
req.body.info });

request.info.user = req.user ._id; console.log("À


PROPOS DE LA DEMANDE D'ENREGISTREMENT", request);
request.save((err, r) => { if (err)

{ res.json({ message : 'une erreur s'est produite lors de l'enregistrement de votre r' }); }
else
{ res.json(r);

} }); });

Meilleure façon:

Router.route('/') .get((req,
res) => { Request.find((err,
r) => { if(err){ console.log(err) } else
{ return
next(err)

} }) }) .post((req, res) =>


{ const request = new Request({ type :
req.body.type, info :
req.body.info });

request.info.user = req.user ._id; console.log("À


PROPOS DE SAUVEGARDER LA DEMANDE", request);
request.save((err, r) => { if (err)
{ return
next(err) } else {

Notes de GoalKicker.com Node.js pour les professionnels 187


Machine Translated by Google

res.json(r);

} }); });

Notes de GoalKicker.com Node.js pour les professionnels 188


Machine Translated by Google

Chapitre 56 : Livrer du HTML ou tout autre type de fichier

Section 56.1 : Distribuer du HTML au chemin spécifié


Voici comment créer un serveur Express et servir index.html par défaut (chemin vide /) et page1.html pour le chemin /page1 .

Structure des dossiers

racine du projet
server.js | |
____vues |
index.html |
page1.html

serveur.js

var express = require('express'); var chemin


= require('chemin'); var app =
express();

// délivre index.html si aucun fichier n'est demandé


app.get("/", function (request, réponse)
{ response.sendFile(path.join(__dirname, 'views/index.html')); });

// délivre page1.html si la page1 est demandée app.get('/


page1', function(request, réponse)
{ réponse.sendFile(path.join(__dirname, 'views', 'page1.html', function(error) {
if (error) { //
faire quelque chose en cas d'erreur
console.log(err);
réponse.end(JSON.stringify({error:"page not found"}));
}
});
});

app.listen(8080);

Notez que sendFile() diffuse simplement un fichier statique en réponse, n'offrant aucune possibilité de le modifier. Si vous diffusez un fichier HTML
et souhaitez y inclure des données dynamiques, vous devrez alors utiliser un moteur de modèle tel que Pug, Moustache ou EJS.

Notes de GoalKicker.com Node.js pour les professionnels 189

Vous aimerez peut-être aussi