-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path05-nodejs.html
226 lines (198 loc) · 9.66 KB
/
05-nodejs.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
<section>
<section>
<h2>NodeJS</h2>
</section>
<section>
<h3>Support de l'ES2015</h3>
<p>Les versions récentes de NodeJS (à partir de la version 6) supportent la majorité des fonctionnalités liées à l'ES2015 :</p>
<ul>
<li>const / let</li>
<li>Arrow functions</li>
<li>class</li>
<li>for...of loop</li>
<li>Spread operator</li>
<li><del>import / export</del> (utiliser require)</li>
</ul>
<footer>
<a href="https://node.green" class="info" target="_blank">Tableau des fonctionnalités supportées</a>
</footer>
</section>
<section>
<h3>Command Line Interface (CLI)</h3>
<p>NodeJS dispose d'une commande <code class="language-bash">node</code> permettant de démarrer un serveur NodeJS.</p>
<p>Si cette commande est appelée sans paramètre, une invite de commande s'ouvre dans laquelle il est possible d'écrire du code JavaScript :</p>
<pre class="line-numbers"><code class="language-bash">node
> new Date()
2018-07-29T08:52:37.359Z
</code></pre>
<footer>
<a href="https://nodejs.org/api/cli.html" class="info" target="_blank">CLI documentation</a>
</footer>
</section>
<section>
<h3>Variable globale process</h3>
<p>Node dispose d'une variable globale <code class="language-bash">process</code> permettant d'accéder à différentes informations du processus en cours d'éxecution.</p>
<p>Cette variable est l'équivalent de la variable <code class="language-bash">window</code> côté navigateur.</p>
<pre class="line-numbers"><code class="language-bash">node
> process.pid
11918
</code></pre>
<p>Les variables globales d'une application pourront être définies et accessible via <code class="language-bash">process.env</code>.</p>
</section>
<section>
<h3>Premier script</h3>
<p>Créez un fichier app.js et saisissez le code suivant :</p>
<pre class="line-numbers" id="hello-world"><code class="language-js">setTimeout(function() {
console.log('world');
}, 2000);
console.log('hello');</code></pre>
<p>Executez ensuite ce script :</p>
<pre class="line-numbers"><code class="language-bash">node app.js</code></pre>
</section>
<section>
<h3>Fin du script</h3>
<p>Tant que la stack de l'Event loop contient des traitements à réaliser, le programme continue de s'éxécuter :</p>
<pre class="line-numbers"><code class="language-js">setInterval(function() {
console.log('world');
}, 1000);
console.log('hello');</code></pre>
</section>
<section>
<h3>Paramètres de la commande</h3>
<p>Il est possible de récupérer les paramètres passés à la commande node dans la variable globale <code class="language-js">process.argv</code> :</p>
<pre class="line-numbers"><code class="language-js">console.log(process.argv)</code></pre>
<pre class="line-numbers"><code class="language-bash">node app.js one two three</code></pre>
<div class="instructions">
<ol>
<li>Utilisez un argument pour permettre à l'utilisateur d'afficher le message "Hello John"</li>
</ol>
</div>
</section>
<section>
<h3>Prompt</h3>
<p>Il est également possible de demander à l'utilisateur d'effectuer une saisie dans la console en utilisant le module <strong>readline</strong> :</p>
<pre class="line-numbers"><code class="language-js">const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Quel est votre prénom ?\n', (firstname) => {
console.log(`Bonjour ${firstname}`);
rl.close();
});</code></pre>
</section>
<section>
<h3>Debugger</h3>
<p>Pour debugger votre application, vous pouvez utiliser les fonctionnalités de votre IDE.</p>
<p>Il est également possible d'utiliser le débuggeur de Google Chrome. Pour cela démarrez votre programme avec la commande suivante :</p>
<pre><code class="language-bash">node --inspect</code></pre>
<p>Puis saisissez la ligne suivante dans la barre d'adresse de Google Chrome : <strong>chrome://inspect</strong></p>
</section>
<section>
<h3>Serveur HTTP</h3>
<p>Le module <strong>http</strong> de NodeJS permet de créer un serveur HTTP :</p>
<pre class="line-numbers"><code class="language-js">const http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-type': 'text/plain' });
res.end('Hello world\n');
});
server.listen(8000);</code></pre>
<p><code class="language-js">req</code> contient la requête HTTP et <code class="language-js">res</code> la réponse.</p>
<pre class="line-numbers"><code class="language-bash">curl -i http://localhost:8000</code></pre>
</section>
<section>
<h3>Chunked response</h3>
<p>NodeJS permet par défaut de retourner des données en plusieurs étapes. Cette fonctionnalité peut être utile pour par exemple effectuer un streaming d'une vidéo :</p>
<pre class="line-numbers"><code class="language-js">const http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-type': 'text/plain' });
res.write('hello\n');
setTimeout(function() {
res.end('world\n');
}, 1000);
});
server.listen(8000);</code></pre>
</section>
<section>
<h3>Benchmark</h3>
<p>Nous allons maintenant analyser les performances de notre serveur HTTP en envoyant 100 requêtes en parallèle.</p>
<p>Pour cela, nous pouvons utiliser <a href="https://httpd.apache.org/docs/2.4/programs/ab.html">Apache Benchmark</a> ou encore un package NPM :</p>
<pre class="line-numbers"><code class="language-bash">npm install -g loadtest
loadtest -n 100 -c 100 http://localhost:8000</code></pre>
<p>Le serveur devrait retourner l'ensemble des réponses en ~2s ce qui signifie que chaque requête ne bloquait pas l'exécution du serveur (grâce à l'Event loop).</p>
</section>
<section>
<h3>Nodemon</h3>
<p>Afin d'éviter de devoir stopper puis redémarrer le serveur NodeJS à chaque modification, nous pouvons installer le package <strong>nodemon</strong> :</p>
<pre class="line-numbers"><code class="language-bash">npm init
npm install --save-dev nodemon
./node_modules/.bin/nodemon app.js</code></pre>
<p>Nous pouvons également ajouter un script dans le fichier package.json pour simplifier cette dernière opération :</p>
<pre class="line-numbers"><code class="language-json">"scripts": {
"start": "./node_modules/.bin/nodemon app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},</code></pre>
<p>Vous pouvez maintenant utiliser la commande <code class="language-bash">npm start</code> pour démarrer le serveur.</p>
</section>
<section>
<h3>Modules</h3>
<p>Pour le moment, NodeJS ne supporte pas la syntaxe ES2015 import/export pour la gestion des modules.</p>
<p>NodeJS respecte pour le moment la syntaxe CommonJS.</p>
<p>Cette syntaxe ne permet d'exporter qu'un seul objet.</p>
<pre class="line-numbers"><code class="language-js">// hello.js
module.exports = class Hello {
constructor(name) {
this.name = name;
}
say() {
console.log(`Hello ${this.name}`);
}
}
</code></pre>
<pre class="line-numbers"><code class="language-js">// app.js
const Hello = require('./hello.js');
let hello = new Hello('John');
hello.say();
</code></pre>
</section>
<section>
<h3>Modules</h3>
<p>Il est cependant possible depuis la version 8.9.0 de NodeJS d'activer l'importation de module. Pour cela il faut :</p>
<ul>
<li>Nommer les modules avec l'extension .mjs</li>
<li>Utiliser le flag <code class="language-js">--experimental-modules</code> dans la commande node</li>
</ul>
<hr>
<p>Une autre solution est d'utiliser le package <a href="https://www.npmjs.com/package/esm">esm</a>.</p>
</section>
<section>
<h3>HTTP GET</h3>
<p>Le module <strong>http</strong> permet d'effectuer des requêtes HTTP :</p>
<pre class="line-numbers"><code class="language-js">const https = require('https');
https.get('https://jsonplaceholder.typicode.com/posts/1', function(res) {
let data = '';
res.on('data', function(chunk) {
data += chunk;
});
res.on('end', function() {
const post = JSON.parse(data);
console.log(post.title, post.body);
});
}).on('error', function(error) {
console.log('error: ', error);
});</code></pre>
</section>
<section>
<h3>TP</h3>
<p>A partir des slides précédentes, créez une application dans la console permettant d'afficher les stats d'un repo GitHub (URL : <a href="https://developer.github.com/v3/repos/#get">https://api.github.com/repos/:owner/:repo</a>).</p>
<div class="instructions">
<ol>
<li>Au démarrage, l'application demande à l'utilisateur un username GitHub</li>
<li>Ensuite, l'application affiche l'ensemble des repos de l'utilisateur</li>
<li>Il est alors possible de taper le nom d'un des repos ce qui affichera alors des stats (nombre d'étoiles, de followers et de forks)</li>
<li>Il sera également possible de revenir en arrière et de saisir un autre username</li>
<li>L'utilisateur pourra également quitter l'application en saisissant "exit"</li>
</ol>
</div>
</section>
</section>