NodeJS basics
NodeJS #2
NodeJS en bref...
- Créé par Ryan Lienhart Dahl en 2009,
- Utilise la machine virtuelle V8,
- Serveur http intégré,
- Permet de faire du JS côté serveur,
- Léger et rapide,
- I/O non bloquants et asynchrone,
- Single threaded.
V8 JS Engine
V8 JavaScript engine est un moteur JavaScript libre et open source développé par Google au Danemark. Il est notamment utilisé dans les navigateurs Chromium et Google Chrome, ainsi que sur la plateforme node.js.
V8 est écrit en C++
Quand utiliser ?
Quand NE PAS
utiliser ?
NodeJS étant mono-thread, il faut éviter de l'utiliser pour des tâches qui font un usage intensif du CPU
Il y a des jobs ?
According to indeed.com Node jobs are growing faster than other languages
Qui s'y intéresse ?
Selon Google Trends
C'est trop jeune pour
de la prod ?
En tous cas, eux l'utilisent !
+ Netflix, Uber, Linked In, ...
What else ?
Premier essai : Page "mon compte"
Développement de la même chose en Java en parallèle (minimiser le risque).
- Développement 2 fois plus rapide en NodeJS
- 33% de lignes de code en moins en NodeJS
- 40% de fichiers en moins en NodeJS
Performance
- Deux fois plus de requêtes par seconde en NodeJS.
- Pages servies 200ms plus vite avec NodeJS.
Paypal aujourd'hui
The new Wordpress.com
Projet "calypso"
Refonte de l'interface d'admin WP.com en NodeJS, React, ...
https://developer.wordpress.com/calypso/
NodeJS a permis de réaliser un client web mais aussi utilisable sous forme d'app desktop (electron)
NodeJS est monothread
NodeJS est asynchrone
<?php
// Heure actuelle
echo date('h:i:s') . "\n";
// Stoppe pour 10 secondes
sleep(10);
// retour !
echo date('h:i:s') . "\n";
?>
Synchrone (PHP)
// On passe par une fonction de callback
setTimeout(function() {
console.log("s'affiche après 1 seconde");
}, 1000);
console.log("s'affiche directement");
Asynchrone (JS)
Installation
Télécharger l'installeur sur https://nodejs.org
(ou alors brew install, apt-get, ...)
LTS schedule
Vérifions
node -v
npm -v
REPL
read–eval–print loop
Hello World
exercice
// 1) Créer un fichier helloworld.js
// 2) Faire en sorte qu'il affiche "Hello World"
// en éxecutant `node helloworld.js`
NPM (modules)
Gestionnaire de paquets NodeJS
(www.npmjs.com)
NPM packages
# ----------- Dans la console
# installation d'un paquet local
npm install <package_name>
# chercher des modules
npm search postgresql
# vérifier l'installation
ls node_modules
# installation d'un paquet global
sudo npm install -g <package_name>
# Mettre à jour les paquets locaux
npm update
# ----------- Dans un fichier .js
const PackageName = require('package_name');
Utiliser des modules
NPM packages
# ----------- Dans la console
# Création du package.json
npm init
# ----------- Dans un fichier .js
exports.printMsg = function() {
console.log("This is a message from the demo package");
}
# ----------- Publication
// ==> https://docs.npmjs.com/getting-started/publishing-npm-packages
Créer des modules
NPM packages
{
"name": "my_package",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "ag_dubs",
"license": "ISC",
"repository": {
"type": "git",
"url": "https://github.com/ashleygwilliams/my_package.git"
},
"bugs": {
"url": "https://github.com/ashleygwilliams/my_package/issues"
},
"homepage": "https://github.com/ashleygwilliams/my_package"
}
package.json
NPM packages
package.json (2)
- Semantic versioning : http://semver.npmjs.com
- Scripts : https://docs.npmjs.com/misc/scripts
- Must have : "name" and "version"
- "dependencies": paquets requis en production (--save flag).
- "devDependencies": paquets nécessaires pour le développement (--save-dev flag).
Node modules
exercice
// 1) Dans un nouveau dossier, initialiser un projet NodeJS avec :
// * le module "lodash",
// * le module "prompt",
// 2) Dans le prompt, demander d'entrer une phrase
// * ex: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
// 3) La console doit retourner le nombre de mots de la phrase
// * ex: "La phrase contient x mots"
// 4) Faire en sorte que la commande "npm start" lance le script
// BONUS) N'autoriser que les lettres et les caractères espace (exception sinon)
Global objects
setInterval(cb, ms) // Exécute le callback toutes les ms millisecondes
setTimeout(cb, ms) // Exécute le callback après ms millisecondes
require() // Charger des modules
module // Référence au module courant
exports
console
__dirname // Nom du dossier courant du fichier éxécuté
__filename // Nom du fichier courant
process // Process object
Exports
// getset.js
let content;
exports.setContent = function(thing) {
content = thing;
}
exports.getContent = function() {
return content;
}
// index.js
const GetSet = require('getset');
GetSet.setContent('truc');
GetSet.getContent(); // ==> truc
exports vs module.exports
// greetings.js
// var exports = module.exports = {};
exports.sayHelloInEnglish = function() {
return "HELLO";
};
exports.sayHelloInSpanish = function() {
return "Hola";
};
/*
* this line of code re-assigns
* module.exports
*/
module.exports = "Bonjour";
Process
Global object
Process object est une instance d'EventEmitter
process.env // Environnement utilisateur
process.argv // CLI arguments
process.arch // Architecture processeur
process.pid // PID
process.version // Node version
process.memoryUsage() // Usage mémoire
process.nextTick(callback[, arg][, ...])
process.send(message[, sendHandle][, callback]) // Send message
process.uptime() // In seconds
https://nodejs.org/api/process.html
Process.nextTick()
Global object
Plus efficace que setTimeout(..., 0);
console.log('start');
process.nextTick(() => {
console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback
Appeler la fonction au prochain traitement de la pile d'événements.
Events
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a) => {
console.log('an event occurred: ' + a);
});
myEmitter.emit('event', 'a');
// myEmitter.once
https://nodejs.org/api/events.html
Une grande partie de l'API de base Node.js est construit autour d' une architecture événementielle asynchrone
Events
exercice
// 1) Compléter la définition de classe
class Car {
// 2) Doit émettre un événement "starting" (avec l'heure en argument)
start() {}
// 3) Doit émettre un événement "stoping" (sans argument)
stop() {}
}
const car = new Car();
// 4) Ecouter l'événement "starting" et loguer "starting car at XX:XX"
// 5) L'événement "starting" doit être logué une seule fois (malgré 3x)
// 6) Ecouter l'événement "stoping" et loguer "stoping car"
car.start();
car.start();
car.start();
car.stop();
File System
const fs = require('fs');
// Async
fs.unlink('/tmp/hello', (err) => {
if (err) throw err;
console.log('successfully deleted /tmp/hello');
});
// Sync
const fs = require('fs');
fs.unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');
https://nodejs.org/api/fs.html
Wrappers synchrones et asynchrones wrappers autour des fonctions standard POSIX
File System
fs.exists('/etc/passwd', (exists) => {
console.log(exists ? 'it\'s there' : 'no passwd!');
});
Tester l'existence d'un fichier (fs.exists)
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("Asynchronous read: " + data.toString());
});
Lire le contenu d'un fichier (fs.readFile)
File System
Dans le cas d'un readFile par ex, on reçoit un buffer !
Un buffer est un tableau de bits. La classe Buffer possède différentes méthode pour encoder et décoder un buffer.
File System
fs.stat('input.txt', function (err, stats) {
// Check file type
console.log("isFile ? " + stats.isFile());
console.log("isDirectory ? " + stats.isDirectory());
});
Des informations sur un fichier (fs.stat)
fs.writeFile('input.txt', 'Simply Easy Learning!', function(err) {
if (err) {
return console.error(err);
}
console.log("Data written successfully!");
});
Ecrire dans un fichier (fs.writeFile)
File System
fs.rename(oldPath, newPath, callback) // Renomer un fichier
fs.rmdir(path, callback) // Supprimer un dossier
fs.mkdir(path[, mode], callback) // Créer un dossier
fs.watch(filename[, options][, listener]) // Observer les changements
// https://nodejs.org/api/fs.html
Mais aussi...
File System
exercice
// Grâce à un script NodeJS:
// 1) Créer un dossier nommé "foo",
// 2) Ajouter un fichier nommé "foo.txt",
// 3) Ecrire une phrase à l'intérieur de ce fichier.
OS
const os = require('os');
os.cpus() // CPU / cores
os.freemem() // Mémoire libre
os.homedir() // Dossier home
os.networkInterfaces() // Interfaces réseau
os.tmpdir() // Dossier tmp
os.totalmem() // Mémoire globale
os.type() // 'Linux' pour Linux, 'Darwin' pour OS X and 'Windows_NT' pour Windows
os.uptime() // Machine uptime
https://nodejs.org/api/os.html
Informations sur la machine
http
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200);
res.end('Hello World');
});
server.listen(8080);
https://nodejs.org/api/http.html
Serveur web intégré
http
exercice
// Grâce à un script NodeJS:
1) Lancer un serveur web sur le port 8080
2) Faire en sorte que l'url "http://localhost:8080" affiche "Hello World"
3) Faire en sorte que les urls:
"http://localhost:8080/sum?a=3&b=5" affiche "3+5 = 8"
"http://localhost:8080/sum?a=22&b=5" affiche "22+5 = 27"
...
4) Toutes les autres pages doivent afficher une erreur 404
Mais aussi...
const util = require('util'); // Utilitaires divers
const cluster = require('cluster'); // Cluster de process
const querystring = require('querystring'); // Pour parser les querystrings
const url = require('url'); // Pour parser les URL's
[NODEJS] NodeJS basics (cours 2)
By Julien Herpin
[NODEJS] NodeJS basics (cours 2)
- 1,002