Formation « Web Avancé »
JavaScript full-stack – Node.js – Meteor
Février 2016 – Formation ORT 3CSi spécialité développement web
Guillaume MOREL-BAILLY
|
Copyright
Cette présentation est mis à disposition selon les termes de la Licence Creative Commons
Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0
International (CC BY-NC-SA 4.0). http://creativecommons.org/licenses/by-nc-sa/4.0/
Vous êtes autorisé à partager et adapter ce document, selon les conditions suivantes :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 2
Attribution — Vous devez créditer l’œuvre, intégrer un lien vers la licence et indiquer si des
modifications ont été effectuées à l’œuvre.
Pas d’Utilisation Commerciale — Vous n'êtes pas autorisé à faire un usage commercial de cette
œuvre, tout ou partie du matériel la composant.
Partage dans les mêmes conditions — Dans le cas où vous reprenez ou effectuez une modification
de cette œuvre, vous devez la diffuser dans les même conditions, c'est à dire avec la même licence
d’utilisation.
|
Présentation
• Guillaume MOREL-BAILLY
• Développeur web et mobile freelance depuis +5 ans
• Ingénieur en sécurité informatique depuis 1 an pour une
SSII. Sécurisation et maintenance d’une application de BI
pour un acteur mondial de l'acier inoxydable.
• Me contacter :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 3
Qui suis-je ?
linkedin.com/in/guillaumemorelbailly
|
Présentation
• Tour de table pour mieux vous connaitre, cerner vos
attentes et besoins.
• Cursus / formation; expérience(s) professionnelle(s);
technos abordées ou maitrisées; projets futurs, etc. ?
• Qu’attendez-vous de cette formation ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 4
Qui êtes-vous ?
|
Présentation du cours
• Objectif : vous apporter une culture sur les techniques de développement web modernes
orientées JavaScript. Découverte d’architectures et de frameworks client / serveur utilisés en
entreprise.
• Volume horaire : mois de février
• Cours théorique (slides) et pratiques (exercices, TP)
• Documents de cours
• Evaluations : contrôles de connaissance (QCM + devoir sur feuille) + 1 application à développer
de A à Z (mise en situation)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 5
|
Technologies, frameworks, outils… abordés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 6
|
Plan de formation
1) Introduction à JavaScript
2) Développer avec jQuery
3) L’architecture MEAN
4) Node.js
5) Déploiement cloud sur Heroku (aparté)
6) Socket.io
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 7
7) Express
8) MongoDB
9) Angular
10) MEAN.JS
11) METEOR
Partie 1
Introduction à JavaScript
Eléments de base du langage et concepts avancés
|
JavaScript Histoire
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 9
|
JavaScript – Pourquoi ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 10
|
JavaScript – Histoire
• 1993 : apparition du navigateur web NCSA Mosaic qui a rendu le World Wide Web populaire.
Distribué gratuitement par le NCSA (National Center for Supercomputing Applications).
• NCSA : un centre de recherche universitaire américain précurseur sur les technologies web.
Développement par exemple du serveur web HTTPd (qui servira de base à Apache).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 11
• 1994 : création de la Netscape Communications Corporation, puis apparition
de Netscape Navigator un an plus tard, suite au débauchage des
développeurs de Mosaic.
• 1995 : Netscape détient plus de 90 % de part de marché, Microsoft lance
Internet Explorer 1.0.
|
JavaScript – Histoire
• Netscape voulait que le langage de programmation Scheme soit
intégré au sein de son navigateur. Scheme est un langage de script très
épuré créé dans les années 70.
• Brendan Eich est embauché par Netscape pour cette mission, mais
finalement on lui demande de créer un nouveau langage de
programmation.
• Le cahier des charges était strict : il devait créer ce langage en 10 jours
pour respecter la date de sortie de la version beta 2.0 de Netscape
Navigator. Il fallait aussi s’inspirer de Java.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 12
|
JavaScript – Histoire
"There was some pressure from management to make the syntax look like
Java. There was also some pressure to make it not too big, because after all,
people should use Java if they're doing any real programming.
This is just Java's dumb little brother. But if I put classes in, I’d be in big
trouble.“
Brendan Eich
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 13
|
JavaScript – Histoire
• Brendan Eich s’est alors inspiré du langage de
programmation Self, basé sur le concept de prototypes.
• Le langage Mocha est créé, renommé ensuite en LiveScript.
Quelques mois plus tard, en septembre 1995, Netscape
opte pour un nom plus vendeur, JavaScript, après un
partenariat signé avec Sun Microsystems.
• Attention, malgré son nom et quelques similarités
syntaxiques superficielles, JavaScript n’est pas Java !
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 14
|
JavaScript – Histoire
• 1996 : JavaScript est rapidement adopté pour le développement web orienté client. Netscape
soumet JavaScript à l’organisme de standardisation ECMA International.
• Microsoft réagit en développant JScript inclus dans Internet Explorer 3.
• 1997 : adoption du nouveau standard ECMAScript. Les spécifications sont rédigées dans le
document Standard ECMA-262.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 15
|
ECMAScript
Tout est histoire de
standardisation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 16
|
JavaScript – ECMAScript
• Ecma International est une organisation européenne de standardisation informatique (au sens
large). On pourrait le comparer au consortium W3C, mais qui est chargé uniquement des
technologies du World Wide Web.
• JavaScript est standardisé par Ecma International.
• Le nom ECMAScript réfère au langage de programmation de type script standardisé. Le standard
ECMAScript est documenté avec la spécification ECMA-262.
• ECMAScript ne décrit pas le Document Object Model (DOM) qui est standardisé par le W3C.
• Les spécifications du standard sont mises en œuvre dans différents langages de script. Les
implémentations les plus connus étant JavaScript, Jscript et ActionScript.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 17
|
JavaScript – ECMAScript
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 18
|
JavaScript – ECMAScript
• ECMAScript Edition 5 (ES5) : version actuellement intégrée dans les moteurs de scripts des
navigateurs web  version qu’on utilisera dans le reste de ce cours
• ECMAScript Edition 6 (ES6) : publié en juin 2015, ES6 (appelé aussi ES2015) n’est pas encore
pleinement supporté par les navigateurs. On peut utiliser un transcompilateur comme Babel ou
Traceur vers ES5 pour développer dés maintenant en ES6.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 19
Dernières versions d’ECMAScript :
Tester la compatibilité ES6 de votre navigateur
sur : kangax.github.io/compat-table/es6/
|
JavaScript – ECMAScript
• JavaScript, implémentation du standard ECMAScript n’a pas évolué depuis 2009. Depuis, de plus
en plus d’applications web utilisent massivement JavaScript côté client. Le développement natif en
JavaScript devient complexe et des manques se font sentir.
• ECMAScript 6 est une mise à jour majeure du langage de script standardisé (liste complète des
nouveautés sur : https://github.com/lukehoban/es6features/blob/master/README.md,
comparaison de code ES5 vs ES6 sur http://es6-features.org/).
• Le langage de programmation TypeScript est publié en 2012 par Microsoft. C’est un langage à
part entière de JavaScript mais qui permet de transpiler le code TypeScript en JavaScript. Il a été
créé pour apporter une réponse aux manques de ECMAScript 5.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 20
ECMAScript 6 (ES2015)
|
ECMAScript 6 (ES2015)
class Shape {
constructor (id, x, y) {
this.id = id;
this.move(x, y);
}
move (x, y) {
this.x = x;
this.y = y;
}
}
ECMAScript 5
var Shape = function (id, x, y) {
this.id = id;
this.move(x, y);
};
Shape.prototype.move = function (x, y) {
this.x = x;
this.y = y;
};
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 21
JavaScript – ECMAScript
|
JavaScript – ECMAScript
• Langage de programmation open-source développé en 2012 par Microsoft, comme un sur-
ensemble de JavaScript (tout code JavaScript peut être utilisé dans TypeScript).
• Développé dans le but d’améliorer le code JavaScript (face aux manquements d’ECMAScript 5) :
typage, interfaces, classes, modules, mixin, etc.
• Le code TypeScript est transcompilé / transpiler vers JavaScript.
• TypeScript supporte la spécification ECMAScript 6. Son intérêt est limité depuis l’arrivée
d’ECMAScript 6.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 22
TypeScript
|
Moteurs de
script et de
rendu
Comprendre le fonctionnement et
les composants de nos
navigateurs web.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 23
|
JavaScript – Moteurs de script
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 24
|
JavaScript – Moteurs de script
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 25
Moteur de rendu
(HTML + CSS)
Moteur de script
(JavaScript)
Plugins
(Flash, Silverlight,
Applets Java, etc.)
|
JavaScript – Moteurs de script
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 26
|
JavaScript – Moteurs de script
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 27
|
JavaScript – Moteurs de script
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 28
Moteur de rendu
(HTML + CSS)
Moteur de script
(JavaScript)
|
JavaScript – Moteurs de script
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 29
Firefox
Moteur de rendu : Gecko
Moteur de script : SpiderMonkey
Google Chrome
Moteur de rendu : Blink
Moteur de script : V8
Internet Explorer
Moteur de rendu : Trident
Moteur de script : Chakra
Safari
Moteur de rendu : WebKit
Moteur de script : Nitro
Opera
Moteur de rendu : Blink
Moteur de script : V8
|
JavaScript – Moteurs de script
• Projet open-source développé par Google et écrit en C++.
• Développé à l’origine pour Google Chrome, mais utilisé dans de nombreux autres
projets, dont Node.js (cette technologie sera abordée dans un prochain chapitre).
• Un moteur JavaScript très moderne sur plusieurs aspects.
• V8 compile directement le JavaScript en langage machine (langage natif du
processeur) avant de l’exécuter. Alors que les autres moteurs de script interprètent
du bytecode, ou compilent le code en langage machine avant de l’exécuter.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 30
V8 : le moteur de script « next gen » de Google
|Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 31
JavaScript – Chargement d’une page par le navigateur
|
Le langage
JavaScript
Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 32
|
JavaScript – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 33
|
JavaScript – Présentation
• JavaScript est un langage de script, multi-plateforme et orienté web, piloté par les évènements.
• Il fait partie d’un environnement hôte, le plus souvent un navigateur web, pour qu’il puisse être utilisé
sur les objets de cet environnement.
• Fonctionnalités centrales et native de JavaScript :
• Bibliothèque standard d’objets (Array, Date, Math, etc.)
• Eléments de langage : opérateurs, structures de contrôles, instructions, etc.
• Fonctionnalités étendues (côté client) : contrôle du navigateur et du DOM. Le DOM définit la façon dont
les documents HTML sont exposés aux scripts.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 34
JavaScript, c’est quoi ?
|
JavaScript – Présentation
• Notion de « first-class functions » (objet de première classe).
• Les fonctions JavaScript sont des objets de première classe, ce qui veut dire que les fonctions et les objets sont
traités exactement de la même manière. Toute opération faite sur un entier, un string, un array ou un objet
générique peut être fait sur une fonction. A l’inverse seule une fonction peut être appelée.
• De manière concrète :
• Une fonction peut avoir des propriétés
• On peut affecter une fonction à une variable : var foo = function() {…};
• On peut passer une fonction comme paramètre à une autre fonction
• Une fonction peut retourner une autre fonction
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 35
JavaScript, c’est quoi ?
|
JavaScript – Présentation
var square = function(x) {
return x * x;
},
mult = function (f1, f2) {
return function(n) {
return f1(n) * f2(n);
}
},
foo = mult(square, square),
value = foo(2);
console.log(value); // 16
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 36
JavaScript, c’est quoi ?
|
JavaScript vs Java (ou tout autre langage comparable : C#, C++, etc.)
• JavaScript est interprété : le code est traité
par le moteur de script du navigateur lors de
l’exécution (ce qui le rend indépendant de
toute plate-forme).
Cas particulier : le moteur de script V8 de
Google (inclus dans Chrome, Opera) qui
compile JavaScript en code machine natif
avant de l’exécuter.
• Java est un langage compilé et interprété (le
code source est compilé vers un bytecode, la
machine virtuelle Java interprète ce bytecode).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 37
JavaScript – Présentation
|
JavaScript vs Java (ou tout autre langage comparable : C#, C++, etc.)
• JavaScript est un langage de programmation
objet orienté prototype. Les prototypes sont
utilisés pour représenter les liens entre les
objets.
Les prototypes permettent d'avoir un
héritage dynamique. Ainsi, les
caractéristiques héritées par un objet
peuvent varier dans le temps.
• Java est un langage de programmation objet
orienté classe. Il est entièrement basé sur
l’utilisation de classes et de méthodes.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 38
JavaScript – Présentation
|
JavaScript vs Java (ou tout autre langage comparable : C#, C++, etc.)
• JavaScript est faiblement typé (typage
dynamique). Seul le type var existe.
NB : Avec ECMAScript 6, les types let et const sont
introduits. TypeScript permet d’avoir un typage fort.
• Java est fortement typé (typage statique) :
char, byte, short, int, long, float,
double, boolean et string.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 39
JavaScript – Présentation
var name = "John";
var now = new Date();
var p = new Person(name, now);
String name = "John";
Date now = new Date();
Person p = new Person(name, now);
Person p = "Jake";
// throws ClassCastException
|
JavaScript – Ecrire du code côté client
• La balise script permet d’intégrer du code JavaScript dans une page.
• Attributs de script :
• type : indique le type MIME du contenu  "text/javascript" . Note : depuis HTM5 il n’est
plus nécessaire de spécifier le type.
• src : indique que le code se situe dans un fichier externe
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 40
Balise HTML script
|
JavaScript – Ecrire du code côté client
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 41
Code JavaScript « inline »
<script type="text/javascript">
function helloWorld() {
alert("Hello World");
}
</script>
• Conseil : déplacer le code JavaScript dans un fichier externe et utiliser le moins possible du code
inline dans un fichier HTML pour favoriser la maintenabilité et séparer clairement les
responsabilités (l’affichage des traitements).
|
JavaScript – Ecrire du code côté client
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 42
Fichier externe
<!DOCTYPE html>
<html lang="fr">
<head>...</head>
<body>
...
<script src="main.js"></script>
</body>
</html>
• Conseil : charger les fichiers externes JavaScript en bas de page (juste avant la balise fermante
body). Le navigateur web interprète la page reçue ligne par ligne : le chargement d’une ressource
JavaScript est bloquante.
|
JavaScript – Ecrire du code côté client
• Sur la majorité des navigateurs web : touche F12
• Firefox intègre même une console avancée : Développement > Ardoise JavaScript (Maj + F4)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 43
Console du navigateur
|
Le langage
JavaScript
Eléments de base
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 44
|
JavaScript
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 45
|
JavaScript – Les opérateurs
Types d’opérateurs Code d’exemple
var var foo;
new new Foo;
Assignation foo = {bar: "a value"}
foo.bar = "value";
delete delete foo.bar;
Membres foo.bar;
foo[‘bar’];
Appel bar();
foo.bar();
Comparaison == ou ===
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 46
|
JavaScript – Les variables
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 47
Déclarations
Type de déclaration ECMAScript
var ES5 On déclare une variable, éventuellement en initialisant sa valeur.
let
ES6
On déclare une variable dont la portée est celle du bloc courant,
éventuellement en initialisant sa valeur.
const ES6 On déclare une constante nommée, accessible en lecture seule.
var x;
var y = 42;
var foo = "hello";
bar = "world";
|
JavaScript – Les variables
• Une variable déclarée grâce à l'instruction var ou let sans valeur initiale définie vaudra undefined.
• Tenter d'accéder à une variable qui n'a pas été déclarée lèvera l’exception ReferenceError.
• On utilise undefined pour déterminer si une variable possède une valeur : if (foo === undefined)…
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 48
Evaluation des variables
var a;
console.log("La valeur de a est " + a); // le log contient "La valeur de a est undefined"
console.log("La valeur de b est " + b); // signale une exception ReferenceError
|
JavaScript – Les variables
• Valeur undefined dans un contexte booléen : convertie en false
• Valeur undefined dans un contexte numérique : convertie en NaN
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 49
Evaluation des variables
var monTableau = new Array();
if (!monTableau[0]){ // false
maFunction();
}
var a;
a + 2; // NaN
|
JavaScript – Les variables
• Valeur null dans un contexte numérique : convertie en 0 (zéro)
• Valeur null dans un contexte booléen : convertie en false
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 50
Evaluation des variables
var n = null;
console.log(n * 32); // Le log affichera 0
|
JavaScript – Types de données
• 6 types de données primitifs en ECMAScript 5:
• Type booléen : Boolean (avec les valeurs true ou false)
• Type nul : null
• Type pour les valeurs indéfinies : undefined
• Type pour les nombres : Number (par exemple 42 ou 3.14159)
• Type pour les chaines de caractère : String (par exemple "Hello World")
• 5 type pour les objets : Object, Array, Date, RegExp, Function
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 51
|
JavaScript – L’instruction typeof
• Comme JS est faiblement typé, on a parfois le besoin de savoir avec qu’elle type de valeur on
travaille.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 52
|
JavaScript – Conversion de types de données
• D’après vous, le code suivant lève t’il une erreur ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 53
var answer = 42;
answer = "Thanks for all the fish...";
JavaScript utilisant un typage dynamique, cette dernière instruction ne renverra pas d'erreur.
|
JavaScript – Conversion de types de données
• Lorsque des expressions impliquent des chaînes de caractères et des valeurs numériques ainsi
que l'opérateur "+", JavaScript convertit les nombres en chaînes de caractères :
• Attention, avec des instructions impliquant d'autres opérateurs (comme le signe "-", JavaScript ne
convertit pas nécessairement les valeurs numériques en chaînes de caractères. Ainsi, on aura :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 54
x = "La réponse est " + 42; // "La réponse est 42"
y = 42 + " est la réponse"; // "42 est la réponse"
foo = "37" - 7; // 30
bar = "37" + 7; // "377"
|
JavaScript – Conversion de chaînes en nombres
• parseInt effectue une conversion en valeur entière
• Number effectue une conversion numérique plus stricte
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 55
parseInt(""); // NaN
parseInt(42.5); // 42
parseInt("42"); // 42
parseInt("077"); // 63 (= 7 + 7*8)
parseInt("123foo"); // 123
parseInt("0xF", 16); // 15 car on est en base hexa
Number("foo"); // NaN
Number("001"); // 1
|
JavaScript – Conversion de chaînes en nombres
• parseFloat effectue une conversion d’une chaine de caractère en nombre flottant
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 56
parseFloat("42.5"); // 42.5
parseFloat("1.45kg"); // 1.45
parseFloat("77.3"); // 77.3
parseFloat("077.3"): // 77.3
parseFloat("0x77.3"): // 0
parseFloat(".3"); // 0.3
parseFloat("0.1e6"); // 100000
|
JavaScript – Opérateur de comparaison
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 57
|
JavaScript - Commentaires
// un commentaire sur une ligne
/* un commentaire plus
long sur plusieurs lignes
*/
/* Par contre on ne peut pas /* imbriquer des commentaires */ SyntaxError */
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 58
|
JavaScript - Objets
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 59
• Liste d’une ou plusieurs paires de propriétés nom / valeur
• Ces paires sont délimitées par des accolades : { }
• On peut également pour imbriquer un objet dans un autre
var person = {
firstName: "John",
lastName: "Honda",
age: 29,
foo: {
bar: "test"
}
};
|
JavaScript - Objets
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 60
var sales = "Toyota";
function carTypes(name) {
if (name === "Honda") {
return name;
} else {
return "Sorry, we don't sell " + name + ".";
}
}
var car = { myCar: "Saturn", getCar: carTypes("Honda"), special: sales };
console.log(car.myCar); // Saturn
console.log(car.getCar); // Honda
console.log(car.special); // Toyota
|
JavaScript – Tableaux (Arrays)
• Les tableaux JavaScript sont des objets semblables à une liste
• Ils possèdent plusieurs méthodes incorporées pour exécuter des opérations de parcours et de
modification.
• Syntaxes pour créer un array :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 61
Description et syntaxe
[element0, element1, ..., elementN]
new Array(element0, element1[, ...[, elementN]])
new Array(arrayLength)
var fruits = ["Apple", "Banana"];
|
JavaScript – Tableaux (Arrays)
• Le premier élément d'un tableau a 0 pour indice
• La position du dernier élément est donnée par length moins 1.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 62
Accéder aux éléments d’un tableau
var arr = ["this is the first element", "this is the second element"];
console.log(arr[0]); // logs 'this is the first element'
console.log(arr[1]); // logs 'this is the second element'
console.log(arr[arr.length - 1]); // logs 'this is the second element‘
var fish = ["Lion", , "Angel"];
console.log(fish[0]); // logs ‘Lion'
console.log(fish[1]); // logs ‘undefined'
console.log(fish[2]); // logs ‘Angel ‘
|
JavaScript – Tableaux (Arrays)
• Les éléments d'un tableau sont simplement des propriétés d'objets.
• Normalement on accède à une propriété d’objet avec la notation en point (object.property)
• Cependant il n’est pas possible d’accéder aux propriétés dont le nom commence par un chiffre. Il
est nécessaire d'utiliser la syntaxe avec les crochets.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 63
Accéder aux éléments d’un tableau
var years = [1950, 1960, 1970, 1980, 1990, 2000, 2010];
console.log(years.0); // a syntax error
console.log(years[0]); // works properly
|
JavaScript – Tableaux (Arrays)
• De façon semblable, les propriétés nommées avec des mots-clés réservés ne peuvent être
consultées qu'en utilisant la syntaxe avec crochets :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 64
Accéder aux éléments d’un tableau (aparté)
// An object
var promise = {
'var' : 'text',
'array': [1, 2, 3, 4]
};
Console.log(promise.array); // syntax error
console.log(promise['array']); // works properly
|
JavaScript – Objet natif : exemple de Math
• L’objet Math est un objet natif dont les méthodes et propriétés permettent l'utilisation de
constantes et fonctions mathématiques.
• Cet objet n'est pas une fonction !
• Toutes les propriétés et les méthodes de Math sont statiques.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 65
console.log(Math.e); // 2.718 (nombre d’Euler)
Console.log(Math.PI); // 3.14159…
Console.log(Math.min(2, 58)); // 2
Console.log(Math.ceil(42.3)); // 43 : plus petit entier supérieur
Console.log(Math.floor(42.8)); // 42 : plus petit entier inférieur
|
JavaScript - Instructions conditionnelles
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 66
Instruction if...else
if (condition_1) {
statement_1;
} else if (condition_2) {
statement_2;
} else if (condition_n) {
statement_n;
} else {
statement_last;
}
|
JavaScript - Instructions conditionnelles
• Lors d'un test, les valeurs suivantes seront considérées comme équivalentes à false :
• False
• Undefined
• Null
• 0
• NaN
• La chaine de caractère vide ("")
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 67
Instruction if...else
|
JavaScript - Instructions conditionnelles
• Attention à ne pas confondre les valeurs booléennes « primitives » true et false avec les valeurs
crées grâce à un objet Boolean. Par exemple, on aura :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 68
Instruction if...else
var b = new Boolean(false);
if (b) // this condition evaluates to true
if (b == true) // this condition evaluates to false
|
JavaScript - Instructions conditionnelles
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 69
Instruction switch
switch (fruittype) {
case "Oranges":
console.log("Oranges are $0.59 a pound.");
break;
case "Apples":
console.log("Apples are $0.32 a pound.");
break;
case "Bananas":
console.log("Bananas are $0.48 a pound.");
break;
default:
console.log("Sorry, we are out of " + fruittype + ".");
}
console.log("Is there anything else you'd like?");
|
JavaScript – Boucles et itérations
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 70
Instruction for
for (var i = 0; i < 9; i++) {
console.log(i);
// more statements
}
var i = 0;
for (;;) {
if (i > 3) break;
console.log(i);
i++;
}
|
JavaScript – Boucles et itérations
• Permet d'itérer sur l'ensemble des propriétés énumérables d'un objet, dans un ordre arbitraire.
• Ne doit pas être utilisée pour parcourir un Array lorsque l'ordre des éléments est important !
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 71
Instruction for…in
var obj = {a:1, b:2, c:3};
for (var prop in obj) {
console.log("obj." + prop + " = " + obj[prop]);
}
// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"
|
JavaScript – Boucles et itérations
• Permet d'exécuter une instruction tant qu'une condition donnée est vérifiée.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 72
Instruction while
while (i < 10) {
text += "The number is " + i;
i++;
}
|
JavaScript – Boucles et itérations
• Permet de répéter un ensemble d'instructions jusqu'à ce qu'une condition donnée ne soit plus vérifiée.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 73
Instruction do…while
do {
i += 1;
console.log(i);
} while (i < 5);
|
JavaScript – Concepts avancés
• Il est possible de lever (c’est-à-dire signaler) des exceptions avec l'instruction throw et de les
gérer (les intercepter) avec des instructions try...catch.
• En JavaScript, n'importe quel objet peut être signalé comme une exception : throw "Erreur2";
• Cependant, afin de respecter certaines conventions et de bénéficier de certaines informations, on
préférera les exceptions de base ECMAScript ou DOMException / DOMError si on manipule le
DOM.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 74
Gestion des exceptions
Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 75
Gestion des exceptions
// Lever une erreur générique
try {
throw new Error("Ouups !");
} catch (e) {
console.log(e.name + ": " + e.message);
}
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 76
Gestion des exceptions
// Gérer une erreur spécifique
try {
foo.bar();
} catch (e) {
if (e instanceof EvalError) {
console.log(e.name + ": " + e.message);
} else if (e instanceof RangeError) {
console.log(e.name + ": " + e.message);
}
// ... etc
}
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 77
Gestion des exceptions
// On crée un nouvel objet, héritage par prototype depuis le constructeur de type Error
function MyError(message) {
this.name = 'MyError';
this.message = message || 'Default Message';
this.stack = (new Error()).stack;
}
MyError.prototype = Object.create(Error.prototype);
MyError.prototype.constructor = MyError;
try {
throw new MyError('custom message');
} catch (e) {
console.log(e.name); // 'MyError'
console.log(e.message); // 'custom message'
}
|
JavaScript – Fonctions
• Les fonctions font partie des briques fondamentales de JavaScript.
• Rappel de la partie « Présentation » : les fonctions sont des objets de première classe. Cela
signifie qu'elles peuvent être manipulées et échangées, qu'elles peuvent avoir des propriétés et
des méthodes, comme tous les autres objets JavaScript.
• Une fonction est une procédure JavaScript, un ensemble d'instructions effectuant une tâche ou
calculant une valeur.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 78
var x = myFunction(4, 3); // Function is called, return value will end up in x
function myFunction(a, b) {
return a * b; // Function returns the product of a and b
}
|
JavaScript – Fonctions
• Déclaration d’une fonction
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 79
function add(a, b) {
var c = a+b;
return c;
}
var add = function (a, b) {
var c = a+b;
return c;
};
• On peut également assigner une fonction à une variable
|
JavaScript – Fonctions
• On peut aussi rendre une fonction auto exécutable :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 80
(function() {
console.log('Hello World!');
})();
// Affichera Hello World! à l’ouverture de la page
|
JavaScript – Fonctions
• Les paramètres donnés lors de l'appel d'une fonction sont appelés les arguments de la fonction.
• Les arguments sont passés par valeur. Si la fonction modifie la valeur d'un argument, ce
changement ne se répercute pas en dehors de la fonction.
• Cas spécifique : passage par référence d’un objet. Si la fonction modifie les propriété de l'objet
de la référence, ce(s) changement(s) seront perceptibles en dehors de la fonction.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 81
NB: Les notions de porté, passage par valeur et référence seront étudiées plus en détail dans le chapitre suivant.
|
JavaScript – Fonctions
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 82
// Declare the function 'myFunc'
function myFunc(theObject) {
theObject.brand = "Toyota";
}
var mycar = {
brand: "Honda",
model: "Accord",
year: 1998
};
console.log(mycar.brand); // Log 'Honda‘
myFunc(mycar); // Pass object reference to the function
// Logs 'Toyota' as the value of the 'brand' property of the object, as changed to by the function
console.log(mycar.brand);
|
Le langage
JavaScript
Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 83
|
JavaScript – Manipulation du DOM
• JavaScript contient une bibliothèque standard d'objets tels que Array, Date, et Math, ainsi qu'un
ensemble d'éléments de langage (on vient de les voir).
• Ces fonctionnalités centrales et natives de JavaScript peuvent être étendues de plusieurs façons
en fournissant d'autres objets.
• JavaScript côté client étend ces éléments de base en fournissant des objets pour contrôler le
navigateur et le Document Object Model (DOM).
• Le DOM définit la façon dont les documents HTML sont exposés aux scripts. C’est une API,
standardisée par le W3C et exploitée par les navigateurs web (entre autre).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 84
|
JavaScript – Manipulation du DOM
• De manière simplifiée, le DOM :
• fournit une représentation structurée d’un document HTML ou XML;
• codifie la manière dont un script peut accéder à cette structure.
• Le DOM parcourt une hiérarchie d’éléments.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 85
|
JavaScript – Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 86
|
JavaScript – Manipulation du DOM
• L’API DOM est accessible par JavaScript via l’objet « document »
• Plusieurs méthodes :
• document.createElement()
• document.getElementById()
• document.getElementByTagName()
• document.getElementByName()
• Plusieurs propriétés :
• innerHTML
• innerText
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 87
|
JavaScript – Manipulation du DOM
• Créer une page HTML composée des éléments suivantes :
• Un titre de niveau h1
• Un paragraphe contenant du texte (contenant des mots en « strong », un lien, etc.)
• Une liste de type ul ou ol
• Le tout englobé dans un div
• Utiliser document pour mettre en couleur le paragraphe
• Créer un bouton permettant d’afficher une popup contenant l’attribut href du lien contenu dans le paragraphe.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 88
Exercice n°1 : objectif
|
JavaScript – Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 89
Exercice n°1 : correction
<div id="wrapper">
<h1>Hello World!</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In suscipit,
metus et aliquam convallis, orci est blandit metus, vel fringilla erat ex
sit amet odio. Nunc consectetur aliquet odio, sit amet suscipit orci.
Maecenas <a href="http://www.google.fr" title="Google" id="link">finibus</a> ipsum.</p>
<ul>
<li>Lorem ipsum</li>
<li>Dolor sit amet</li>
<li>Foo bar</li>
</ul>
<button id="myButton">Get href</button>
</div>
|
JavaScript – Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 90
Exercice n°1 : correction
<script>
var elements = document.getElementsByTagName("p");
var length = elements.length;
for (var i = 0; i < length; i++)
{
elements[i].style.color= "red";
}
var myLink = document.getElementById("link");
var myButton = document.getElementById("myButton");
myButton.addEventListener("click", function(event) {
alert(myLink.getAttribute("href"));
});
</script>
|
JavaScript – Manipulation du DOM
• Créer une fonction JavaScript qui permette d’ajouter une ligne à un tableau au clic sur un bouton.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 91
Exercice n°2 : objectif
<table id="myTable" border="1">
<tr>
<td>Ligne1 cellule1</td>
<td>Ligne1 cellule2</td>
</tr>
<tr>
<td>Ligne2 cellule1</td>
<td>Ligne2 cellule2</td>
</tr>
</table>
|
JavaScript – Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 92
Exercice n°2 : correction
function insertRow() {
var foo = document.getElementById('myTable').insertRow(0);
var cell1 = foo.insertCell(0);
var cell2 = foo.insertCell(1);
cell1.innerHTML = "NvllLigne Cellule1";
cell2.innerHTML = "NvllLigne Cellule2";
}
<button id="insertNewRow" onclick="insertRow">Ajouter une nouvelle ligne</button>
|
JavaScript – Manipulation du DOM
• Créer une page contenant un bouton qui permette de de
générer un nombre aléatoire compris entre 1 et 12.
• Afficher le résultat dans un champ input de type text.
• Le bouton doit changer d’état : au premier chargement,
afficher « Jouer » puis afficher « Rejouer ».
• Astuce : vous pouvez utiliser l’objet Math pour générer un
nombre aléatoire.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 93
Exercice n°3 – « Tirage au sort » : objectif
|
JavaScript – Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 94
Exercice n°3 – « Tirage au sort » : correction
Pour générer le nombre aléatoire entre 1 et 12 :
// Valeur min inclue, max inclue
Math.floor(Math.random() * (max - min + 1)) + min;
-> Math.random : nbr entre 0 et 1
-> (max - min + 1) : 12 - 1 + 1
-> Math.floor = plus grand entier qui est <= à un nbr x
|
JavaScript – Manipulation du DOM
• Créer une fonction JavaScript qui, au clic sur un bouton :
• Demande à l’utilisateur de saisir le nombre de colonnes et le nombre de lignes.
• Créée dynamiquement un tableau en fonction des entrées récupérées (et modifier le nom
de chaque cellule créée).
• Astuce : utiliser window.prompt()
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 95
Exercice n°4 : objectif
|
JavaScript – Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 96
Exercice n°4 : correction
<table id="theTable" border="1"></table>
<button onclick="create">Créer un tableau</button> // ou via fonction anonyme
function create() {
nbRow = window.prompt("Nombre de ligne", 1);
nbCell = window.prompt("Nombre de colonnes", 1);
for (var r = 0; r < parseInt(nbRow, 10); r++) {
var x = document.getElementById(‘theTable').insertRow(r);
for (var c = 0; c < parseInt(nbCell, 10); c++) {
var y = x.insertCell(c);
y.innerHTML=« Ligne "+ r +« , colonne "+ c;
}
}
}
|
JavaScript – Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 97
Exercice n°5 : objectif
• Créer une liste HTML (select) puis ajouter quelques éléments à cette liste (option).
• Ajouter un bouton qui permettre de supprimer l’élément sélectionné de la liste.
• Astuce : selectedIndex permet de récupérer l’élément sélectionné d’une liste HTML
|
JavaScript – Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 98
Exercice n°5 : correction
<select id="fruits">
<option>Orange</option>
<option>Mandarine</option>
<option>Banane</option>
<option>Kiwi</option>
</select>
<input type="button" id="myButton" value="Supprimer ce fruit">
var myButton = document.getElementById("myButton");
myButton.addEventListener("click", function(event) {
var fruitsList = document.getElementById("fruits");
fruitsList.remove(fruitsList.selectedIndex);
});
|
JavaScript – Manipulation du DOM
• Ecrire un programme qui permette d’afficher une image aléatoire après un clic sur un bouton. Attention : ces images
doivent être préchargées lors du premier clic (pour améliorer l’UI).
• Pour vous aider, voici quelques étapes :
• Créer un objet contenant vos images avec quelques propriétés, ex : url, hauteur, largeur.
• Précharger les images avec new Image(), les stocker dans un tableau.
• Créer une fonction permettant de générer un nombre aléatoire (pour charger l’image aléatoirement dans votre
objet) compris entre 0 et la taille de votre tableau de buffer. Vous pouvez vous baser sur l’exercice précédent.
• Retourner l’élément correspondant à ce nombre aléatoire à partir du tableau de buffer (on reçoit une « instance »
de Image).
• Afficher l’image (en remplaçant la précédente).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 99
Exercice n°6 – « Chargement d’images » : objectif
|
JavaScript – Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 100
Exercice n°6 – « Chargement d’images » : correction
// Tableau de nos images
var imgs = [{
src: "file:///C:/Users/user/Desktop/image1.jpeg",
width: "256",
height: "256"
},{
src: "file:///C:/Users/user/Desktop/image2.jpg",
width: "435",
height: "474"
},{
src: "file:///C:/Users/user/Desktop/image3.jpg",
width: "330",
height: "330"
},{
src: "file:///C:/Users/user/Desktop/image4.jpg",
width: "320",
height: "330"
}
];
|
JavaScript – Manipulation du DOM
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 101
Exercice n°6 – « Chargement d’images » : correction
// L’instanciation de Image, va automatiquement lancée une requête HTTP GET
var imgBuffer = [];
for (var i = 0, j = imgs.length; i < j; i++) {
imgBuffer[i] = new Image();
imgBuffer[i].src = imgs[i].src;
imgBuffer[i].width = imgs[i].width;
imgBuffer[i].height = imgs[i].height;
}
// getRandNb retourne un objet Image
// attribut de la méthode : valeur min, max => voir exercice précédent (compteur)
var randomImg = getRandNb(0, preBuffer.length - 1);
// Remplacer l’image existante
var newImage = getRandomInt(0, imgBuffer.length - 1);
var container = document.getElementById('container');
container.innerHTML = '';
container.appendChild(newImage);
|
JavaScript – Manipulation du DOM
• Analyser et comprendre le code existant (dispo sur l’espace partagé).
• Améliorer l'interface utilisateur : par exemple, modifier l'état du bouton
"Démarrer le jeu" après avoir démarrer une partie.
• Le jeu devra gérer trois niveaux différents. Chaque niveau augmentant la
complexité du puzzle et modifiant l'image de fond.
• Le jeu devra garder les scores ainsi que les noms des joueurs par rapport
au temps mis pour faire le puzzle et au nombre de mouvements réalisés.
Il affichera les cinq meilleurs scores à la fin d'une partie, pour le niveau
joué, dans un canevas (même principe que le texte de départ). Si les
niveaux sont tous passés, afficher le classement global.
• Soyez force de proposition !
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 102
Exercice n°7 – « Puzzle glissant » : objectif Exercice noté
Basé sur l’application de Brad
Manderscheid développée pour
TutsPlus.com
|
Le langage
JavaScript
AJAX
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 103
|
JavaScript – AJAX
Asynchronous JavaScript And XML
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 104
Format d’échange de données en le client
et le serveur. Historiquement du XML, puis
progressivement remplacé par du JSON.
On peut également échanger du texte brut.
Une requête AJAX est
asynchrone (non bloquante
côté client).
Le client écoute en
parallèle une éventuelle
réponse du serveur.
Langage de script utilisé côté client pour initier les
requêtes AJAX et éventuellement traiter la
réponse du serveur. Manipulation du DOM pour
mettre à jour le contenu.
1/
2/
3/
|
JavaScript – AJAX
• AJAX n’est pas un langage mais une architecture qui fait appel à plusieurs technologies.
• Permet de dynamiser tout ou partie d’une page web pour enrichir l’expérience utilisateur en ne
forçant plus le rechargement complet d’une page.
• Première apparition du terme « AJAX » en 2005 dans un article du Web Adaptive Path rédigé par
l’architecte Jesse James Garrett. Depuis, AJAX a rapidement été adopté par les développeurs.
• Le concept de rechargement dynamique d’une page web est apparu dés 1996 via l’utilisation d’iframe
et de l’élément HTML layer (abandonné depuis) : souvent regroupé sous le terme DHTML.
• Une solution plus élégante a été introduite par Microsoft en 1998 : MSRS (pour Microsoft Remote
Scripting) qui fonctionnait via un applet Java auquel on pouvait donner dynamiquement des données
par le biais d'un module JavaScript.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 105
|
JavaScript – AJAX
• Microsoft a ensuite introduit l’objet XMLHttpRequest dans Internet Explorer 5 et dans Outlook
Web Access (une sorte de webmail disponible avec Microsoft Exchange Server).
• L’utilisation d’un applet Java dans MSRS a été remplacé par celui de l’objet XMLHttpRequest dans
les années 2000.
• Entre 2002 et 2005, l’objet XMLHttpRequest a été introduit dans le standard ECMAScript, le
rendant utilisable par l’ensemble des navigateurs web du marché.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 106
|
JavaScript – AJAX
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 107
Modèle d’application web classique
|
JavaScript – AJAX
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 108
Modèle d’application web dynamique
|
JavaScript – AJAX
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 109
Modèle d’application web dynamique
(or JSON)
|
JavaScript – AJAX
• Objet natif de JavaScript pouvant être utilisé par l’ensemble des moteurs de script (car
standardisé dans l’ECMAScript).
• Cependant, il y a quelques différences d’implémentation selon le moteur et la version du
navigateur de l’utilisateur. AJAX étant très demandé, c’est l’une des raisons pour laquelle jQuery a
rapidement gagné en popularité.
• XMLHttpRequest permet d'envoyer des requêtes synchrones ou asynchrones en HTTP. Mais il est
généralement utilisé que pour l’envoi de requêtes asynchrones (c’est là tout son intérêt).
• Donc l’objet XMLHttpRequest != AJAX (qui est une architecture, un semble de technologies).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 110
L’objet XMLHttpRequest
|
JavaScript – AJAX
• XMLHttpRequest permet d'envoyer des requêtes HTTP (GET, POST, PUT, etc.) de manière très
simple. Il suffit de créer une instance de l'objet, d’attacher éventuellement une fonction de
callback, de lier une URL, et d'envoyer la requête.
• Il existe plusieurs fonctions natives que nous allons voir dans les slides suivants.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 111
L’objet XMLHttpRequest
|
JavaScript – AJAX
• Les navigateurs modernes (Chrome, IE 7+, Firefox, etc.) supportent l’objet XMLHttpRequest. On
abordera pas la gestion de l’AJAX pour les anciennes versions de ces navigateurs.
• La syntaxe pour créer un objet XMLHttpRequest est la suivante :
• A partir de cette instance, on peut utiliser les fonctions de XMLHttpRequest.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 112
L’objet XMLHttpRequest – Création d’un objet
var xhttp = new XMLHttpRequest();
|
JavaScript – AJAX
• Pour envoyer une requête HTTP à un serveur, on utilise les fonctions open() et send().
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 113
L’objet XMLHttpRequest – Envoyer une requête à un serveur
xhttp.open('POST', 'foo.php', true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); // Optionnel
Xhttp.send('firstName=John&lastName=Doe');
Fonction Description
open(method, url, async) Spécifie le type de requête HTTP.
send() Envoi la requête à un serveur.
send(string) Envoi la requête à un serveur et transmet des données (typiquement, pour une
requête HTTP de type POST).
|
JavaScript – AJAX
• Si une requête asynchrone (c’est-à-dire non bloquante) a été initiée, il faut spécifier la fonction
JavaScript qui sera appelée lors de la réponse du serveur. C’est ce qu’on appelle une fonction de
callback.
• On utilisera l’évènement onreadystatechange de l’objet XMLHttpRequest
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 114
L’objet XMLHttpRequest – Recevoir une requête du serveur
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
var response = xhttp.responseText;
}
};
xhttp.open("GET", "foo.php", true);
xhttp.send();
Réponse retournée par le serveur
Utiliser xhttp.responseXML si du XML est retourné par le serveur.
|
JavaScript – AJAX
Propriété Description / valeurs
onreadystatechange Enregistre une fonction qui devra être appelée automatiquement à chaque
fois que la propriété readyState change. Généralement on passe une fonction
anonyme.
readyState Statut de la requête XMLHttpRequest :
0 : request not initialized
1 : server connection established
2 : request received
3 : processing request
4 : request finished and response is ready
status 200 : « OK »
404 : Page non trouvée
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 115
L’objet XMLHttpRequest – Recevoir une requête du serveur
|
JavaScript – AJAX
• On a vu qu’on pouvait utiliser l’évènement onreadystatechange ainsi que la propriété readyState
pour surveiller la progression d’une requête asynchrone.
• Une évolution de l’API permet maintenant d’utiliser la fonction addEventListener (implémentant
l’interface ProgressEvent) pour intercepter les notifications de progression périodiques, de
notifications d’erreur, etc.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 116
L’objet XMLHttpRequest – Recevoir une requête du serveur
oReq.addEventListener("progress", updateProgress, false);
oReq.addEventListener("load", transferComplete, false);
oReq.addEventListener("error", transferFailed, false);
oReq.addEventListener("abort", transferCanceled, false);
oReq.open();
|
JavaScript – AJAX
• Historiquement le format XML était utilisé pour échanger des données entre le client et le serveur.
• Cependant ce format est lourd et difficile à parser en JavaScript.
• JSON (JavaScript Object Notation) est un format de données léger destiné à la transmission de
données. Il est indépendant de tout langage, bien qu’il se rapproche de la syntaxe objet de
JavaScript.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 117
XML ou JSON ?
|
JavaScript – AJAX
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 118
XML ou JSON ?
{"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]}
<employees>
<employee>
<firstName>John</firstName> <lastName>Doe</lastName>
</employee>
<employee>
<firstName>Anna</firstName> <lastName>Smith</lastName>
</employee>
<employee>
<firstName>Peter</firstName> <lastName>Jones</lastName>
</employee>
</employees>
|
JavaScript – AJAX
• L'objet natif JSON contient des méthodes pour convertir des valeurs en JSON et pour convertir
des données JSON en valeurs JavaScript.
• La méthode JSON.stringify() permet de convertir une valeur en JSON, et éventuellement de
remplacer des valeurs grâce à une fonction de remplacement ou en ne filtrant que certaines
propriétés données.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 119
XML ou JSON ?
JSON.stringify({}); // '{}'
JSON.stringify(true); // 'true'
JSON.stringify("toto"); // '"toto"'
JSON.stringify({x: 5, y: 6}); // '{"x":5,"y":6}'
|
JavaScript – AJAX
• La méthode JSON.parse() interprète une chaîne de caractères comme du JSON, transformant de
façon optionnelle la valeur produite et ses propriétés, puis retourne la valeur.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 120
XML ou JSON ?
var text = '{"name":"John Johnson","street":"Oslo West 16","phone":"555 1234567"}';
var obj = JSON.parse(text);
document.getElementById("demo").innerHTML =
obj.name + "<br>" +
obj.street + "<br>" +
obj.phone;
|
JavaScript – AJAX
• L’architecture AJAX est utilisée massivement dans les sites et applications web. Généralement
utilisée pour dynamiser quelques éléments comme la validation et l’envoi d’un formulaire, la
pagination d’éléments, etc.
• On développe également des applications « full-ajax » : le code peut devenir vite complexe, lourd,
difficile à maintenir.
• D’autres technologies ont émergées en remplacement ou complément de Ajax, par exemple les
WebSocket ou le concept de « binding » (pour lier de manière automatique un élément du DOM
à une source de données) utilisé par exemple par AngularJS ou EmberJS.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 121
AJAX : Aujourd’hui et demain
|
Le langage
JavaScript
Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 122
|
JavaScript – Concepts avancés
• La portée est un des éléments fondamentaux de JavaScript, et peut être le plus difficile à maitriser
car il diffère beaucoup des autres langages de programmation. La portée s’applique aux variables
comme aux fonctions.
• Afin d'utiliser une fonction, il est nécessaire de l'avoir auparavant définie au sein de la portée dans
laquelle on souhaite l'appeler.
• On ne peut pas accéder aux variables définies dans une fonction en dehors de cette fonction : ces
variables n'existent que dans la portée de la fonction.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 123
Fonctions : portée
|
JavaScript – Concepts avancés
• En revanche, une fonction peut accéder aux différentes variables et fonctions qui appartiennent à
la portée dans laquelle elle est définie.
• Une fonction définie dans une autre fonction peut également accéder à toutes les variables de la
fonction « parente » et à toute autre variable accessible depuis la fonction « parente ».
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 124
Fonctions : portée
|
Fonctions : portée
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 125
JavaScript – Concepts avancés
// The following variables are defined in
// the global scope
var num1 = 20,
num2 = 3,
name = "Licorne";
// This function is defined in the global scope
function multiply() {
return num1 * num2;
}
multiply(); // Returns 60
// A nested function example
function getScore () {
var num1 = 2,
num2 = 3;
function add() {
return name + " scored " + (num1 + num2);
}
return add();
}
getScore(); // Returns "Chamahk scored 5"
|
JavaScript – Concepts avancés
• Comme on l’a vu, JavaScript permet d'imbriquer des fonctions et la fonction interne aura accès
aux variables et paramètres de la fonction parente. À l'inverse, la fonction parente ne pourra pas
accéder aux variables liées à la fonction interne.
• On crée ce qu’on appelle une closure (fermeture en français) lorsque la fonction interne est
disponible en dehors de la fonction parente.
• Une closure est un objet spécial qui combine : une fonction + l’environnement dans lequel la
fonction a été créée.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 126
Fonctions : closures
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 127
Fonctions : closures
var animal = function(nom) { // La fonction externe utilise un paramètre "nom"
var getNom = function () {
// La fonction interne accède à la variable "nom" de la fonction externe
return nom;
}
// Renvoie la fonction interne pour la rendre disponible
// en dehors de la portée de la fonction parente
return getNom;
}
monAnimal = animal("Licorne");
monAnimal(); // Renvoie "Licorne"
Exemple 1 :
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 128
Fonctions : closures
function createFunction() {
var name = "Hello";
function displayName() {
alert(name);
}
return displayName;
};
var myFunction = createFunction();
myFunction();
Exemple 2 :
• L'intérêt de ce code est que la fonction displayName()
a été renvoyée depuis la fonction parente avant d'être
exécutée.
• Normalement, les variables locales d'une fonction
n'existent que pendant l'exécution d'une fonction. Une
fois que createFunction() aura fini son exécution, on
peut penser que la variable name ne sera plus
accessible.
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 129
Fonctions : closures
function createFunction() {
var name = "Hello";
function displayName() {
alert(name);
}
return displayName;
};
var myFunction = createFunction();
myFunction();
• Cependant, le code continue à fonctionner : la variable
est donc accessible d'une certaine façon.
• La solution est la suivante : createFunction est
devenue une closure.
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 130
Fonctions : closures
function createFunction() {
var name = "Hello";
function displayName() {
alert(name);
}
return displayName;
};
var myFunction = createFunction();
myFunction();
• Pour rappel : closure = fonction + environnement dans
lequel la fonction a été créée.
• L'environnement est composé de toutes les variables
locales de la portée présente lorsque la fermeture a été
créée.
• Ici myFunction est une fermeture qui contient la
fonction displayName et la chaîne de caractères "Hello"
qui existait lorsque la closure a été créée.
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 131
Fonctions : closures
function faireAddition(x) {
return function(y) {
return x + y;
};
};
var ajout5 = faireAddition(5);
var ajout10 = faireAddition(10);
console.log(ajout5(2)); // 7
console.log(ajout10(2)); // 12
Exemple 3 :
• faireAddition permet de créer d'autres fonctions (qui
font la somme de leur argument et d'un nombre fixe).
• On crée deux fonctions, la première qui ajoute 5 à
l'argument et la deuxième qui ajoute 10.
• ajout5 et ajout10 sont des closures. Ils partagent la même
définition de fonction mais des environnements différents.
• Dans l'environnement de ajout5, x vaut 5. Pour ajout10, x
vaut10.
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 132
Fonctions : closures
function getCounter() {
var i = 0;
return function () {
return i++;
}
}
var counter1 = getCounter();
var counter2 = getCounter();
console.log(counter1()); // 1
console.log(counter1()); // 2
console.log(counter2()); // 1
console.log(counter2()); // 2
console.log(counter1()); // 3
console.log(counter1()); // 4
Exemple 4 :
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 133
Fonctions : closures
var sayHello = function (name) {
var text = 'Hello, ' + name;
return function () {
console.log(text);
};
};
sayHello('Todd');
Exemple 5 : que fait ce code ?
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 134
Fonctions : closures
var sayHello = function (name) {
var text = 'Hello, ' + name;
return function () {
console.log(text);
};
};
var helloTodd = sayHello('Todd');
helloTodd(); // will call the closure and log 'Hello, Todd'
Exemple 5 : que fait ce code ?
|
JavaScript – Concepts avancés
Exercice d’application :
• Soit le code HTML suivant :
• Créer un script qui permette de changer le texte d’aide (par défaut « Des aides seront affichées
ici ») au clic sur un champ input.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 135
Fonctions : closures
<span id="helper">Des aides seront affichées ici</span>
<p>Email : <input type="text" id="email" /></p>
<p>Nom : <input type="text" id="name" /></p>
<p>Âge : <input type="text" id="age" /></p>
|
JavaScript – Concepts avancés
• Dans une fonction JavaScript on aura l’objet suivant :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 136
Fonctions : closures
var helpers = [
{'id': 'email', 'helper': 'Votre adresse e-mail'},
{'id': 'name', 'helper': 'Votre prénom et nom'},
{'id': 'age', 'helper': 'Votre age (vous devez avoir au moins 18 ans)'}
];
• Aide : faire une boucle sur cet objet et manipuler le DOM avec la fonctions
document.getElementById() pour sélectionner un élément HTML via son id. Utiliser « innerHTML »
pour modifier le contenu d’un élément, et onfocus pour créer un évènement au focus.
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 137
function showHelp(help) {
document.getElementById('helper').innerHTML = help;
}
function setupHelp() {
var helpText = [
{'id': 'email', 'helper': 'Votre adresse e-mail'},
{'id': 'name', 'helper': 'Votre prénom et nom'},
{'id': 'age', 'helper': 'Votre age (vous devez avoir au moins 18 ans)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.helper);
}
}
}
setupHelp();
|
JavaScript – Concepts avancés
• Problème : le code précédent ne fonctionne pas. Quelque soit le champ sur lequel on se situe, le
message d'aide concernant l'âge est le seul qui s'affiche.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 138
Fonctions : closures
|
JavaScript – Concepts avancés
• Explications : les fonctions attachées aux gestionnaires d'événements sont des closures et que
l'environnement qui leur est rattaché est le même pour les trois : il provient de la portée de la
fonction setupHelp.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 139
Fonctions : closures
function setupHelp() {
...
for (var i = 0; i < texteAide.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.helper);
}
}
}
Closure
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 140
Fonctions : closures
function makeHelpCallback(help) {
return function() {
showHelp(help);
};
}
function setupHelp() {
...
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
}
}
|
JavaScript – Concepts avancés
• On ne peut pas accéder aux variables définies dans une fonction en dehors de cette fonction : ces
variables n'existent que dans la portée de la fonction.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 141
Portée des fonctions et variables
// code here can not use carName
function myFunction() {
var carName = "Volvo";
// code here can use carName
console.log(carName); // Volvo
}
console.log(carName); // Uncaught ReferenceError: carName is not defined
|
JavaScript – Concepts avancés
• Si on assigne une valeur à une variable qui n’a pas été déclarée (avec var), cette variable aura
automatiquement une portée globale.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 142
Portée des fonctions et variables
// code here can use carName
function myFunction() {
carName = "Volvo";
// code here can use carName
}
|
JavaScript – Concepts avancés
• Une fonction peut accéder aux différentes variables et fonctions qui appartiennent à la portée
dans laquelle elle est définie.
• Une variable déclarée en dehors d’une fonction a une portée globale.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 143
Portée des fonctions et variables
var carName = "Volvo";
// code here can use carName
function myFunction() {
// code here can use carName
}
|
JavaScript – Concepts avancés
• Une fonction définie dans une autre fonction (= closure) peut également accéder à toutes les
variables de la fonction « parente » et à toute autre variable accessible depuis la fonction «
parente ».
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 144
Portée des fonctions et variables
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 145
Portée des fonctions et variables
// Variables globales
var num1 = 20,
num2 = 3,
nom = "Licorne";
// Fonction définie dans la portée globale
function multiplier() {
return num1 * num2;
}
multiplier(); // Renvoie 60
function getScore () {
var num1 = 2,
num2 = 3;
function ajoute() {
return nom + " a marqué " + (num1 + num2);
}
return ajoute();
}
getScore(); // "Licorne a marqué 5"
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 146
Portée et this
var myFunction = function () {
console.log(this); // this = global, [object Window]
};
myFunction();
var myObject = {};
myObject.myMethod = function () {
console.log(this); // this = Object { myObject }
};
var nav = document.querySelector('.nav'); // <nav class="nav">
var toggleNav = function () {
console.log(this); // this = <nav> element
};
nav.addEventListener('click', toggleNav, false);
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 147
Portée et this
var nav = document.querySelector('.nav'); // <nav class="nav">
var toggleNav = function () {
console.log(this); // <nav> element
setTimeout(function () {
console.log(this); // [object Window]
}, 1000);
};
nav.addEventListener('click', toggleNav, false);
• Même au sein de la même fonction, le scope peut être changé et la valeur de this peut l’être
également.
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 148
Portée et this
var nav = document.querySelector('.nav'); // <nav class="nav">
var toggleNav = function () {
var that = this;
console.log(that); // <nav> element
setTimeout(function () {
console.log(that); // <nav> element
}, 1000);
};
nav.addEventListener('click', toggleNav, false);
• Même au sein de la même fonction, le scope peut être changé et la valeur de this peut l’être
également.
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 149
Créer un scope privé
(function () {
var myFunction = function () {
// do some stuff here
};
})();
myFunction(); // Uncaught ReferenceError: myFunction is not defined
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 150
Module Pattern : namespace + scope privé et public
// Définition du module
var Module = (function () {
var privateMethod = function () {
...
};
return {
myMethod: function () {
console.log('myMethod has been called.');
},
someOtherMethod: function () { ... }
};
})();
// call module + methods
Module.myMethod();
|
JavaScript – Concepts avancés
• L'élévation est peut-être l'élément le plus surprenant et celui qui peut causer le plus de soucis en
termes de portée. Le hoisting est fait de manière transparente par JavaScript.
• La principale chose à garder en mémoire est la suivante (pour ECMAScript 5) : pour toute
définition d'une variable, il y a une déclaration de cette variable au début de sa portée et
une affectation à l'endroit de sa définition.
• Les déclarations de fonctions sont également remontées dans le code. Par contre ce n’est pas le
cas des expression de fonctions.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 151
Hoisting (élévation)
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 152
Hoisting (élévation)
var state; // variable declaration
state = "ready"; // variable definition (assignment)
var state = "ready"; // declaration plus definition
• Il faut toujours visualiser une variable comme étant constituée de deux parties : la déclaration puis
la définition.
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 153
Hoisting (élévation)
• On a vu qu’une variable déclarée dans un scope appartient à ce scope (cette portée).
• Mais ce qu’on a pas encore vu, c’est que peut importe où la variable est déclarée dans ce scope,
toutes les déclarations de variables sont remontées en haut de leur scope (global ou local). C’est
ce qu’on appel l’élévation.
• Note : l’élévation déplace seulement la déclaration de la variable. L’assignement n’est pas déplacé.
console.log(state); // output: undefined
var state = "ready";
var state; // moved to the top
console.log(state);
state = "ready"; // left in place
|
JavaScript – Concepts avancés
• JavaScript peut parfois se révéler déroutant, notamment pour les développeurs habitués à des
langages fonctionnant avec des classes.
• JavaScript ne fournit pas d'implémentation de classe.
• Le mot-clé class a été introduit avec ECMAScript 6 mais ne fournit qu'un sucre syntaxique, JavaScript
continue d'avoir un modèle d'héritage basé sur les prototypes.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 154
Prototypes : présentation
|
JavaScript – Concepts avancés
• Mais alors, quid de l’héritage ?
• Dès lors qu'on aborde l'héritage, JavaScript n'utilise qu'un seul concept : les objets (souvenez-
vous, tout est objet en JavaScript !).
• Chaque objet possède un lien, interne, vers un autre objet, appelé prototype.
• Cet objet prototype possède lui aussi un prototype et ainsi de suite, jusqu'à ce que l'on aboutisse
à un prototype null. null, n'a, par définition, aucun prototype et forme donc le dernier maillon de
la chaîne des prototypes.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 155
Prototypes : présentation
|
JavaScript – Concepts avancés
• On sait déjà que les objets JavaScript sont des conteneurs de propriétés. On vient de voir que
chaque objet possède un lien vers un objet prototype.
• Lorsqu'on souhaite accéder à une propriété d'un objet, on recherche :
• d'abord parmi les propriétés propres de l'objet,
• puis parmi celles de son prototype,
• puis parmi celle du prototype du prototype,
• et ainsi de suite jusqu'à ce qu'une propriété correspondante soit trouvée ou qu'on ait
atteint la fin de la chaîne de prototypes.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 156
Prototypes : héritage de propriété
|
JavaScript – Concepts avancés
• En JavaScript, toute fonction peut être rattachée à un objet en tant que propriété.
• Une fonction héritée agit comme n'importe quelle autre propriété (voir slide précédent).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 157
Prototypes : héritage de fonctions
|
JavaScript – Concepts avancés
• Le but est de créer la chaine de prototypes suivante :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 158
Prototypes : héritage de fonctions
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 159
Prototypes : héritage de fonctions
Animal = function(name) { this.name = name; }
Animal.prototype.eats = function() {
return this.name + " is eating";
}
Chordate = function(name) { this.name = name; }
Chordate.prototype = new Animal();
Chordate.prototype.has_spine = true;
Mammal = function(name) { this.name = name; }
Mammal.prototype = new Chordate();
Mammal.prototype.has_hair = true;
m = new Mammal('cat');
|
JavaScript – Concepts avancés
• Remarque : lorsqu'une fonction héritée est exécutée, la valeur de this pointe vers l'objet qui hérite.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 160
Prototypes : héritage de fonctions (et portée)
var o = {
a: 2,
m: function(b){
return this.a + 1;
}
};
console.log(o.m()); // 3
// Appelle de o.m : 'this' fait référence à o
var p = Object.create(o);
// p est un objet héritant de o
p.a = 12; // crée une propriété 'a' pour p
console.log(p.m()); // 13
// lorsque p.m est appelé, 'this' fait référence
à p.
|
JavaScript – Concepts avancés (mémoire)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 161
Références
var me = {
name: {
first: "John"
}
};
var foo = me.name;
foo = {first: "Alexis"};
console.log(me.name.first);
|
JavaScript – Concepts avancés (mémoire)
• var str : on déclare simplement un
pointeur. La valeur de str est pour
l’instant sur undefined
• str = "hi" : on prend un pointeur
et on lui assigne une adresse sur cette
variable en mémoire
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 162
Références
|
JavaScript – Concepts avancés (mémoire)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 163
Références
var obj = {};
obj.txt = "hi";
|
JavaScript – Concepts avancés (mémoire)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 164
Références
var obj = {};
obj.txt = "hi";
|
JavaScript – Concepts avancés (mémoire)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 165
Références
var obj = {};
obj.txt = "hi";
|
JavaScript – Concepts avancés (mémoire)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 166
L’opérateur delete
var me = {
name: {
first: "Justin"
}
},
foo = me.name;
delete me.name;
console.log(foo.first);
window
me
name
first
"justin"
|
JavaScript – Concepts avancés (mémoire)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 167
L’opérateur delete
var me = {
name: {
first: "Justin"
}
},
foo = me.name;
delete me.name;
console.log(foo.first);
window
me
name
first
"justin"
foo
|
JavaScript – Concepts avancés (mémoire)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 168
L’opérateur delete
var me = {
name: {
first: "Justin"
}
},
foo = me.name;
delete me.name;
console.log(foo.first);
window
me
first
"justin"
foo
|
JavaScript – Concepts avancés (mémoire)
• L'opérateur delete permet de retirer une propriété d'un objet.
• Contrairement à ce qu'on pourrait croire, l'opérateur delete n'a strictement rien à voir avec de la
libération de mémoire directe  il ne libère la mémoire qu'indirectement, en supprimant des
références.
• Si l'opération de delete est bien effectuée, la propriété sera retirée de l'objet.
• Remarque : delete fonctionne uniquement pour les propriétés d'un objet. Il n'a aucun effet sur les
variables ou les noms de fonctions.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 169
L’opérateur delete
|
JavaScript – Concepts avancés (mémoire)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 170
Références (suite)
var me = {
name: {
first: "Justin"
}
},
foo = me.name;
window
me
name
first
"Justin"
foo
|
JavaScript – Concepts avancés (mémoire)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 171
Références (suite)
var me = {
name: {
first: "Justin"
}
},
foo = me.name;
foo = {
first: “Alexis"
}
window
me
name
first
"Justin"
foo
first
"Alexis"
|
JavaScript – Concepts avancés
21
undefined
undefined
21
{}
NaN
true
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 172
Les opérateurs de comparaison expliqués
"21"
null
null
21
{}
NaN
{valueOf: function() {return "1"}}
==
==
===
===
===
===
==
vrai
vrai
faux
vrai
faux
faux
vrai
|
JavaScript – Concepts avancés
• Opérateur === avec des types primitifs.
• Ce code va rechercher ces deux primitifs en
mémoire et va chercher à comparer leurs valeurs.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 173
Les opérateurs de comparaison expliqués
var str1 = "hi";
var str2 = "hi";
str1 === str2 vrai
Adresse Valeur
… …
x1001 call-object
x1002 str1
x1003 x2001
x1004 str2
x1005 x2101
… …
x2001 STRING
x2002 hi
… …
x2101 STRING
x2102 hi
|
JavaScript – Concepts avancés
• Opérateur === avec des objets.
• Ce code va rechercher ces deux objets en mémoire
et va comparer leurs pointeurs (car ce ne sont pas
des primitifs). C’est une comparaison « par
référence ».
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 174
Les opérateurs de comparaison expliqués
var obj1 = {};
var obj2 = {};
obj1 === obj2 faux
Adresse Valeur
… …
x1001 call-object
x1002 obj1
x1003 x2001
x1004 obj2
x1005 x2101
… …
x2001 OBJECT
x2002 0
… …
x2101 OBJECT
x2102 0
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 175
Les opérateurs de comparaison expliqués – x == y
Types identiques ?
Tous les deux null ou undefined ?
string == number ?
boolean == anything ?
Object == string ou Number ?
===
true
==
==
false
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 176
true == ({toString: function() {return "1"}})
Types identiques ?
Tous les deux null ou undefined ?
string == number ?
boolean == anything ?
Object == string ou Number ?
===
true
1 == ({toString: function(){return "1"}})
==
false
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 177
1 == ({toString: function() {return "1"}})
Types identiques ?
Tous les deux null ou undefined ?
string == number ?
boolean == anything ?
Object == string ou Number ?
===
true
false
1 == "1"
==
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 178
1 == "1"
Types identiques ?
Tous les deux null ou undefined ?
string == number ?
boolean == anything ?
Object == string ou Number ?
===
true
1 == 1
==
false
|
JavaScript – Concepts avancés
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 179
1 == 1
Types identiques ?
Tous les deux null ou undefined ?
string == number ?
boolean == anything ?
Object == string ou Number ?
true
==
false
===
==
C’est pour ça que le
comparateur == est
gourmand en performance !
Il faut plutôt privilégier
l’opérateur ===.
|Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 180
Partie 2
Développer avec jQuery
Write less, do more
|
jQuery – Présentation
• jQuery est une bibliothèque JavaScript open-source et multi-plateforme créée
entre autre pour faciliter la manipulation du DOM, la gestion des
évènements et l’utilisation de l’Ajax.
• On peut étendre les fonctionnalités de jQuery par l’ajout du plugins. Il existe
par exemple plusieurs centaines de plugins permettant d’implémenter une
galerie d’image.
• Première version lancée par John Resig en 2006.
• On distingue 2 branches en production :
• version 1.x (dernière en date 1.12.0) : support anciennes version IE
• version 2.x (dernière en date 2.2.0) : plus légère
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 182
|
Avantages
• Facilite grandement la manipulation du DOM
(l’utilisation de l’API document par JavaScript
reste compliquée dés qu’il s’agit de manipuler
des éléments précis du DOM).
• On écrit souvent 2x moins de lignes de codes
avec jQuery qu’en JavaScript natif. Gain de
temps; maintenabilité accrue; etc.
• Plugins : éviter de réinventer la roue !
Inconvénients
• jQuery est une couche d’abstraction à
JavaScript, si bien que certains développeurs
« développent » en jQuery sans même
connaitre JavaScript.  peut être
problématique.
• Nécessite de charger la bibliothèque (qui est
de plus en plus lourde au fil du temps…).
• Passer par les fonctions natives du langages
JavaScript sera toujours plus rapide (en terme
de charge / temps d’exécution).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 183
jQuery – Présentation
|
jQuery – Présentation
• jQuery UI : collection d'éléments utiles dans le développement d'une interface utilisateur riche et
interactive. La bibliothèque est découpée en 4 parties complémentaires : interactions (par
exemple gestion du drag’n’drop), widgets (Datepicker, ProgressBar, Slider…), effets et les thèmes.
jQuery UI a passé son âge d’or… il est en perte de vitesse depuis. On recommandera plutôt
d’utiliser des fameworks UI en HTML5 (comme Bootstrap).
• jQuery Mobile : première version sortie en octobre 2010, permet de développer facilement des
interfaces mobiles. La bibliothèque a perdu de son intérêt depuis l’apparition de frameworks
mobiles « modernes » plus performants. PhoneGap le maintien en vie.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 184
Projets connexes
|
jQuery – Présentation
• En fonction du projet sur lequel vous travaillez et des impératifs du cahier
des charges (support des anciens navigateurs, ou utilisation d’un plugin
jQuery basé sur une ancienne version, etc. ?), choisissez la version de jQuery
correspondante.
• Pour de nouveaux projets « from scratch », on conseillera la branche 2.x.
• Chargement de la bibliothèque (version minifiée) en local ou via un CDN.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 185
Chargement de la bibliothèque
<script src="jquery.min.js"></script>
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
|
jQuery – Sélecteurs
• Les sélecteurs jQuery permettent de sélectionner des éléments du DOM sur lesquels on souhaite
effectuer des opérations (par exemple récupérer la valeur d’un champ input, ou changer l’opacité
d’un div).
• En JavaScript natif on passe par l’API document qui permet l’accès et la manipulation directe du
DOM. Cette API fournit des méthodes comme getElementById() ou getElementsByTagName() qui
sont pratiques pour sélectionner des éléments simples et précis. Pour des usages plus poussés,
ces méthodes montrent vite leurs limites.
• jQuery permet de sélectionner très facilement des éléments du DOM en utilisant la fonction $().
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 186
|
jQuery – Sélecteurs
• La fonction $() n’est en fait qu’un alias vers la fonction jQuery().
• La fonction $() créé un nouveau objet jQuery qui référence le(s) élément(s) sélectionné(s).
• Note : on peut également utiliser des fonctions de jQuery sans forcément sélectionner un
élément du DOM en amont. C’est par exemple le cas de $.ajax().
• Syntaxe de base : $(selector).action();
• Le sélecteur peut être vue comme une requête de sélection permettant d’identifier le ou les
éléments HTML à manipuler.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 187
|
jQuery – Sélecteurs
• Tout est question de contexte.
• Par défaut, les sélecteurs effectuent leurs recherchent dans le DOM à partir de la racine du
document (la page web). Toutefois, un contexte alternatif peut être donné en utilisant le second
attribut optionnel de la fonction $().
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 188
$("div.foo").click(function() {
$("span").addClass("bar");
});
$("div.foo").click(function() {
$("span", this).addClass("bar");
});
Recherche d’un élément « span » dans le DOM à partir de
la racine du document.
Recherche d’un élément « span » dans le DOM à partir du
nœud div.foo. C’est-à-dire que seul les éléments span
enfants de .foo seront sélectionnés.
|
jQuery – Sélecteurs
• En interne, la sélection d’un contexte différent est implémenté avec la fonction .find().
• Donc $("span", this) est équivalent à $(this).find("span").
• De la même manière, on peut passer un sélecteur en 2nd argument :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 189
// Sélectionner tous les éléments p enfant de #bar
$("p", "#bar");
// Equivalent à :
$("#bar").find("p");
|
jQuery – Sélecteurs
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 190
Sélecteur Exemple Sélectionnera…
this $(this) L’élément courant
* $("*") Tous les éléments de la page
#id $("#foo") Les éléments avec l’id “foo"
.class $(".foo") Les éléments avec la classe “foo"
.class,.class $(".foo, .bar") Tous les éléments avec la classe “foo" ou “bar"
element $("p") Tous les éléments <p>
el1,el2,el3 $("h1, div, p") Tous les éléments <h1>, <div> et <p>
:first $("p:first") Le premier élément <p>
:last $("p:last") Le dernier élément <p>
:even $("tr:even") Tous les éléments <tr> pairs (even)
|
jQuery – Sélecteurs
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 191
Sélecteur Exemple Sélectionnera…
parent > child $("div > p") Tous les éléments <p> qui sont enfant direct d’un élément <div>
parent descendant $("div p") Tous les éléments <p> qui sont descendant d’un élément <div>
element + next $("div + p") Le premier élément <p> qui sera à la suite d’éléments <div>
:focus $(":focus") L’élément qui a actuellement le focus
:contains(text) $(":contains('Hello')") Tous les éléments qui contiennent le texte « Hello »
:has(selector) $("div:has(p)") Tous les éléments <div> qui ont un élément <p>
:empty $(":empty") Tous les éléments vides
:parent $(":parent") Tous les éléments qui sont parents d’un autre élément
:hidden $("p:hidden") Tous les éléments <p> qui sont cachés (visibilité)
:visible $("table:visible") Tous les éléments <table> qui sont visibles
|
jQuery – Sélecteurs
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 192
Sélecteur Exemple Sélectionnera…
[attribute] $("[href]") Tous les éléments avec un attribut href
[attribute=value] $("[href=‘foo.htm']") Tous les élements avec un attribut href égal à “foo.htm"
[attribute!=value] $("[href!=‘foo.htm']") Tous les éléments avec un attribut href different de “foo.htm"
[attribute$=value] $("[href$='.jpg']") Tous les éléments avec un attribut href finissant par ".jpg"
[attribute^=value] $("[title^='Tom']") Tous les éléments avec un attribut titre commençant par "Tom"
[attribute*=value] $("[title*=‘foo']") Tous les éléments avec un attribute titre contenant le mot “foo"
|
jQuery – Sélecteurs
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 193
Sélecteur Exemple Sélectionnera…
:input $(":input") Tous les éléments input
:text $(":text") Tous les éléments input de type "text"
:checkbox $(":checkbox") Tous les éléments input de type "checkbox"
:submit $(":submit") Tous les éléments input de type "submit"
:enabled $(":enabled") Tous les éléments input activés
:disabled $(":disabled") Tous les éléments input désactivés
:selected $(":selected") Tous les éléments input sélectionnés
:checked $(":checked") Tous les éléments input cochés
|
jQuery – Sélecteurs
• Soit le code HTML ci-dessous, sélectionner en jQuery le titre de niveau h1 et passer le texte en
majuscule (vous pouvez utiliser la fonction css() pour manipuler les styles). Sélectionner le premier
élément li de la liste et passer le texte en rouge.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 194
Exercice d’application rapide
<div id=wrapper>
<h1>Lorem ipsum dolor sit amet</h1>
<p>Un paragraphe de test</p>
<ul>
<li>Element 1</li>
<li>Element 2</li>
<li>Element 3</li>
</ul>
</div>
|
jQuery – Sélecteurs
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 195
Exercice d’application rapide
<div id="wrapper">
<h1>Lorem ipsum dolor sit amet</h1>
<p>Un paragraphe de test</p>
<ul>
<li>Element 1</li>
<li>Element 2</li>
<li>Element 3</li>
</ul>
</div>
<script>
$(function() { // ou $(document).ready(function() {
$('h1').css('text-transform', 'uppercase');
$('li:first-child').css('color', 'red');
});
</script>
Bien penser à charger
jQuery dans vote page !
|
jQuery – La fonction $() (notion avancée)
• Nous avons vu que la fonction $() permet de sélectionner un ou des éléments du DOM en fonction
d’une requête.
• On peut aussi utiliser la fonction $() avec les objets JavaScript natifs.
• Dans ce cas, seules les fonctions jQuery data(), prop(), on() et trigger() sont disponibles.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 196
// Define a plain object
var foo = { foo: "bar", hello: "world" };
// Pass it to the jQuery function
var $foo = $(foo);
// Test accessing property values
var test1 = $foo.prop("foo"); // bar
|
jQuery – La fonction $() (notion avancée)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 197
// Execute la fonction quand le DOM est prêt à être utilisé
// C’est-à-dire quand la page sera entièrement chargée
$(function() {
// Document is ready
});
• Dernier usage de la fonction $() : l’utilisation d’une fonction de callback.
// Utilisation d’un alias (exemple d’utilisation: utilise lorsqu’on travaille avec WordPress, ou seul
// le mot clé jQuery est disponible
jQuery(function( $ ) {
// On peut maintenant utiliser le signe $ comme alias à la function "jQuery"
});
|
jQuery – La fonction $() (notion avancée)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 198
$(document).ready(function(){
// Document is ready
});
• La fonction $(function() { ... }); est équivalente à la notation :
|
jQuery – L’objet jQuery (notion avancée)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 199
• Quand la fonction jQuery (ou l’alias $) est invoquée avec une sélecteur CSS, elle retournera un
objet jQuery enveloppant tout élément(s) correspondant à ce sélecteur. Une « collection » est
retournée. Attention, ce n’est pas un array JavaScript !
• Par exemple, en écrivant :
var headings = $("h1");
• La variable headings est maintenant un élement jQuery contenant tous les éléments <h1> de la
page au moment où la ligne a été interprétée par JavaScript. On peut vérifier ça en appelant la
propriété length :
alert(headings.length);
|
jQuery – L’objet jQuery (notion avancée)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 200
• La fonction eq() permet de retourner un élément précis de la collection jQuery :
var firstHeading = headings.eq( 0 );
• La fonction get() permet de retourner un élément DOM précis de la collection jQuery. Donc au
lieu de retourner un élément du DOM « jQuerisé », on retourne l’élement DOM lui-même (comme
on l’aurait fait avec les fonctions de sélection natives de JavaScript) :
var firstHeadingElem = $( "h1" ).get( 0 );
• Par contre on ne peut plus utiliser les fonctions natives de jQuery sur cette variable.
|
jQuery – L’objet jQuery (notion avancée)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 201
• Détail important : à chaque sélection d’un élément, un objet jQuery différent est retourné (même
si cet objet fait référence au même élément du DOM).
// Créé 2 objets jQuery totalement distinct pour le même élément
var logo1 = $("#logo");
var logo2 = $("#logo");
// Pour s’en assurer, on peut comparer ces objets :
console.log(logo1 === logo2); // false
• Par contre, ils contiennent (référencent) le même élément DOM :
var logo1Elem = logo1.get(0);
var logo2Elem = logo2.get(0);
console.log(logo1Elem === logo2Elem); // true
|
jQuery – L’objet jQuery (notion avancée)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 202
• Pour bien distinguer un objet jQuery d’un élément du DOM, il est d’usage de préfixer les variables
référant à un objet jQuery avec le signe « $ ».
• Il n’y a aucune magie derrière cette pratique : c’est juste une convention de nommage (à suivre ou
non… mais soyez constant dans l’écriture de votre code).
// Comparaison d’éléments du DOM (mais avec des nom de variable plus explicites)
var $logo1 = $("#logo");
var logo1 = $logo1.get(0);
var $logo2 = $("#logo");
var logo2 = $logo2.get(0);
console.log(logo1 === logo2); // true
|
jQuery – L’objet jQuery (notion avancée)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 203
• Les objets jQuery ne sont pas dynamique : dans le sens ou la collection retournée par un sélecteur
ne changera pas, même si des éléments correspondant au sélecteur son supprimés ou ajoutés
dans le DOM.
• Si le document a peut-être changé depuis la création initiale de l'objet jQuery, la collection doit
être mise à jour en créant un nouveau objet jQuery. Tout simplement en ré-exécutant le même
sélecteur :
var allParagraphs = $("p");
// On ajoute un nouveau paragraphe dans le DOM pour un raison X ou Y. allParagraphs n’est pas MAJ.
// On doit mettre à jour manuellement la sélection précédente :
allParagraphs = $("p");
|
jQuery – Fonctions
• Une fois qu’un élément a été identifié (c’est-à-dire sélectionné), on peut utiliser des fonctions
jQuery sur cet élément. La plupart de ces fonctions sont dites « utilitaires » dans le sens où elles
permettent de simplifier leur manipulation.
• Les fonctions jQuery ne concernent pas uniquement la manipulation du DOM ou la mise en
forme CSS.
• Syntaxe : $(selector).action();
• On peut « chainer » la plupart des fonctions : $(selector).action().action2().action3();
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 204
|
jQuery – Fonctions
• addClass() : ajoute une ou plusieurs classes aux éléments sélectionnés
• removeClass(): retire une ou plusieurs classes aux éléments sélectionnés
• toggleClass() : ajoute la classe si elle n’existe pas, sinon retire cette classe (toggle = bascule)
• hasClass() : vérifie si l’un des éléments sélectionné contient cette classe
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 205
Manipulation des classes CSS
$("p:first").addClass("intro");
if ($("p:first").hasClass("intro")) {
$("#result").append(“Le paragraphe a la classe CSS intro");
}
|
jQuery – Fonctions
• append() : insert du contenu à la fin des éléments sélectionnés
• appendTo() : insert un élément HTML à la fin / suite des éléments sélectionnés
• before() : insert du contenu avant les éléments sélectionnés
• insertAfter() : insert un élément HTML après les éléments sélectionnés
• insertBefore() : insert un élément HTML avant les éléments sélectionnés
• prepend() : insert un contenu au début des éléments sélectionnés (en leur sein)
• prependTo() : insert un élément HTML au début des éléments sélectionnés (en leur sein)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 206
Insertion
|
jQuery – Fonctions
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 207
Insertion : exemple de prependTo()
<h2>Greetings</h2>
<div class="container">
<div class="inner">Hello</div>
<div class="inner">Goodbye</div>
</div>
$("<p>Test</p>").prependTo(".inner");
<h2>Greetings</h2>
<div class="container">
<div class="inner">
<p>Test</p>Hello
</div>
<div class="inner">
<p>Test</p>Goodbye
</div>
</div>
|
jQuery – Fonctions
• attr() : définit un attribut, ou retourne des attributs de l’élément sélectionné
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 208
D’autres fonctions…
$("img").attr("width", "500");
• clone() : fait une copie de l’élément sélectionné
$("p").clone().appendTo("body");
• css() : définit ou retourne un ou plusieurs styles CSS pour l’élément sélectionné
$("p").css("color", "red");
$("p").css({"background-color": "yellow", "font-size": "200%"}); // multiples propriétés
|
jQuery – Fonctions
• empty() : supprime les éléments enfant (du nœud DOM) de l’élément sélectionné
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 209
D’autres fonctions…
$("div").empty();
• height() : définit ou retourne la hauteur de l’élément sélectionné
$("div").height(); … $("#foo").height(30);
• offset() : retourne la position (x/y) de l’élément à l’écran. Utiliser offsetParent() pour la position par
rapport à l’élément parent.
var positions = $(".bar").offset(); // Accès aux propriétés : positions.left et positions.top;
|
jQuery – Fonctions
• text() : définit ou retourne le contenu texte de l’élément sélectionné
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 210
D’autres fonctions…
$("p").text("Hello world!"); // <p>Hello world!</p>
• val() : définit ou retourne la valeur de l’élément sélectionné
$("input:text").val("Hello World");
• find() : recherche un élément correspond au contexte de l’élément sélectionné
$(this).find("p");
|
jQuery – Evènements
• Il existe plus de 30 évènements en jQuery…
• Par exemple pour intercepter un clic sur un élément :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 211
$("#foo").click(function(){
console.log(“foo clicked”);
});
• On passe une fonction anonyme à la fonction click() de jQuery. Le sélecteur $("#foo") fait que
l’évènement click sera attaché à cet élément du DOM.
• L’équivalent en JavaScript serait :
document.getElementById(‘#foo’).addEventListener(‘click’, function() {…})
|
jQuery – Evènements
• Cependant la fonction click() pose problème si notre DOM est susceptible de changer dans le futur.
L’évènement click sera attaché uniquement au éléments du DOM existant lors de l’appel de click().
• Pour lever cette limitation, la fonction live() a été introduite en jQuery 1.6 : déprécié en 1.7 et
supprimée en 1.9. ATTENTION : ne plus l’utiliser !
• On passera plutôt par la fonction on() :
• Utilise moins de mémoire (car délégation)
• Fonctionne avec des éléments ajoutés dynamiquement
NB : click() est un alias vers trigger(‘click’), tandis que click(data, fn) est un alias vers on(‘click’, null, data, fn).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 212
|
jQuery – Evènements
• Avec la syntaxe « on » dynamique :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 213
$("#foo").on("click", function(){
console.log("foo clicked");
});
|
jQuery – Evènements
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 214
• Exercice d’application : attacher un évènement « click » pour chaque paragraphe du div parent.
Dans la méthode de callback, modifier la couleur du texte en rouge. Commencer par utiliser click()
puis on().
• Attacher un second évènement « click » pour le bouton « create_element ». L’action sur ce bouton
doit ajouter un nouveau paragraphe dans le div parent (vous pouvez utiliser la méthode
append()).
<div id="wrapper">
<p>First paragraph</p>
<p>Second paragraph</p>
</div>
<button id="create_element">Create new paragraph</button>
|
jQuery – Evènements
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 215
$(function() {
// Evènement non dynamique (à ne pas utiliser…)
/*$('#wrapper p').click(function() {
$(this).css('color', 'red');
});*/
$('#wrapper').on('click', 'p', function() {
$(this).css('color', 'red');
});
$('#create_element').click(function() {
$('#wrapper').append("<p>New element</p>");
});
});
• Exercice d’application : correction
|
jQuery – Evènements
• A savoir qu’on peut également déclencher manuellement la soumission d’un formulaire en lever
l’évènement submit :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 216
L’évènement submit() pour l’envoi d’un formulaire
$("#myForm").submit(function(e) {
e.preventDefault();
console.log("Le formuaire myForm a été envoyé");
});
$("#foo").click(function() {
$("#myForm").submit();
});
|
jQuery – Evènements
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 217
L’évènement resize() pour surveiller la redimension d’une fenêtre
$(window).resize(function() {
console.log("La fenêtre a été redimensionnée par l’utilisateur");
});
• Attention, cet évènement est envoyé à l’élement « window ».
• On devra donc attacher l’évènement resize sur un sélecteur de window :
|
jQuery – AJAX
• L’utilisation de l’architecture AJAX en jQuery est plus simple qu’en JavaScript natif, surtout quand il
s’agit de supporter les navigateurs d’ancienne génération.
• Si on veut avoir un contrôle maximum sur la requête jQuery et la gestion des évènements, on
passera par la fonction / l’interface bas niveau $.ajax() :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 218
$.ajax({
method: "POST",
url: "foo.php",
data: { name: "John", location: "Boston" },
dataType: "json",
success: function(resp) { ... },
error: function(req, status, err) { ... }
});
|
jQuery – AJAX
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 219
var jqxhr = $.ajax( "example.php" )
.done(function() {
alert("success");
})
.fail(function() {
alert("error");
})
.always(function() {
alert("complete");
});
• On peut aussi utiliser cette notation depuis jQuery >= 1.5 :
|
jQuery – AJAX
• Pour plus de simplicité, on peut également utiliser des fonctions raccourcies.
• $.get() permet de charger des données d’un serveur en utilisant le verbe HTTP GET :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 220
// Requêter la page server.php en transmettant des données additionnelles
// Utiliser l’évènement done() en attachant une function de callback
$.get("server.php", { name: "John", time: "2pm" })
.done(function(data) {
console.log("Data Loaded: " + data);
}
);
|
jQuery – AJAX
• Pour plus de simplicité, on peut également utiliser des fonctions raccourcies.
• $.post() permet de charger des données d’un serveur en utilisant le verbe HTTP POST :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 221
// Requêter la page server.php en transmettant des données additionnelles
// Utiliser l’évènement done() en attachant une function de callback
$.post("server.php", { name: "John", time: "2pm" })
.done(function(data) {
console.log("Data Loaded: " + data);
}
);
$.post("server.php", $("#myForm").serialize());
|
jQuery – AJAX
• Exercice d’application : soit le code HTML suivant, on cherche à soumettre ce formulaire de recherche
via une requête HTTP POST en utilisant l’architecture AJAX. Créer également la partie serveur (en PHP
par exemple). Retourner un objet JSON (en php : return json_encode([‘result’ => ‘…’]);) et parser le
résultat côté client.
• Aide : ajouter un évènement pour écouter la soumission du formulaire
 utiliser .submit(callback); sur le sélecteur correspond au formulaire searchForm. Utiliser par exemple
une fonction anonyme et passer « e » comme argument.
 utiliser la méthode preventDefault() pour stopper la propagation du clic.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 222
<form action="search.php" id="searchForm">
<input type="text" name="s" placeholder=“Rechercher...">
<input type="submit" value="Search">
</form>
<div id="result"></div>
|
jQuery – AJAX
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 223
$("#searchForm").submit(function(e) {
e.preventDefault();
var $form = $(this),
term = $form.find("input[name='s']").val(),
url = $form.attr("action");
// Envoi paramètre "s" en POST
var posting = $.post(url, { s: term });
// Afficher le résultat dans un div
posting.done(function(data) {
data = $.parseJSON(data);
$("#result").empty().append(data.result);
});
});
<?php
header('Content-Type: application/json');
$search = $_POST["s"];
echo json_encode([
'result' => "Votre recherche : $search"
]);
|
jQuery – Effets et animations
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 224
• jQuery propose des fonctions d'animations et de transitions qui peuvent être appliquées sur les
éléments du DOM.
• On distingue deux groupes d’effets et animations :
• Les animations prédéfinies dans jQuery comme les effets de « fade » ou de « slide »
• Les animations manuelles que l’on paramètre soit même en appelant la fonction animate()
|
jQuery – Effets et animations
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 225
Effet sur la visibilité des éléments : hide / show
• hide(speed, callback) : permet de masquer un élément. Les deux paramètres de la fonction sont
optionnels. Le premier permet de définir le temps de l’animation (en ms ou en passant par
slow/fast), le second affecte une fonction de callback qui sera appelée à la fin de l’animation.
// Au clic sur le bouton, masquer l’élement #foo
// puis afficher un message de confirmation dans la console
$("#myButton").click(function() {
$("#foo").hide("slow", function() {
console.log("Animation complete");
});
});
|
jQuery – Effets et animations
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 226
Effet sur la visibilité des éléments : toggle
• toggle(speed, callback) : permet de basculer entre les fonctions hide() et show() en fonction
de l’état de l’élément. Par exemple si l’élément est visible, l’appel de toggle() entrainera le
déclenchement de hide().
// Au clic sur le bouton, masquer ou afficher l’élement #foo
// puis afficher un message de confirmation dans la console
$("#myButton").click(function() {
$("#foo").toggle(2000, function() {
console.log("Animation complete");
});
});
|
jQuery – Effets et animations
• fadeIn(speed, callback) : permet d’afficher progressivement un élément masquée (l’opacité de
l’élément cible va passer de 0 à 100 pendant la durée définie dans le paramètre optionnel speed).
Le second paramètre affecte une fonction de callback qui sera appelée à la fin de l’animation.
• fadeOut(speed, callback) : même principe, mais estompe progressivement un élément au lieu
de l’afficher.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 227
Effet sur la visibilité des éléments : fading
$("a").click(function() {
$("div").fadeIn(3000, function() {
$("span").fadeIn(100);
});
return false;
});
|
jQuery – Effets et animations
• fadeToogle(speed, callback) : permet de basculer entre les fonctions fadeIn() et fadeOut() en
fonction de l’état de l’élément. Par exemple si l’élément est visible, l’appel de fadeToggle()
entrainera le déclenchement de fadeOut().
• fadeToogle(speed, opacity, callback) : permet d’afficher progressivement un élément
jusqu’à une opacité donnée. A l’inverse de fadeIn() qui passe l’opacité de 0 à 100.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 228
Effet sur la visibilité des éléments : fading
$("p:first").on("click", function() {
$(this).fadeTo("slow", 0.33);
});
|
jQuery – Effets et animations
• Vous pouvez créer un effet de glissement sur les éléments en utilisant les fonctions slideDown(),
slideUp() ou slideToggle().
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 229
Effets de glissement (slide)
$("#flip").click(function(){
$("#panel").slideToggle();
});
|
jQuery – Effets et animations
• Si aucun effets prédéfinis correspond à votre usage, vous pouvez utiliser la fonction
animate({params}, speed, callback) pour définir votre propre animation.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 230
Animations personnalisées
$("button").click(function(){
$("div.foo").animate({
left: '250px',
opacity: '0.5',
height: '150px',
width: '150px'
}, 2000, function() {
console.log("Animation terminée");
});
});
Remarque : vous pouvez manipuler toutes les
propriétés CSS (sauf color qui nécessite
l’installation du plugin « jQuery Color »).
Cependant, le nom des propriétés doit être en
notation Camel Case.
padding-left  paddingLeft
|
jQuery – Effets et animations
• Comme presque toute fonction jQuery, vous pouvez passer par un chainage de méthodes pour éviter
de dupliquer du code. Dans l’exemple suivant, les animations se succèderons une après une :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 231
Chainage des animations
$("#foo").css("color", "red")
.slideUp(2000)
.slideDown(2000);
|
jQuery – Itérations
• La function jQuery each() est utilisée pour itérer à travers chaque élément d’une collection
d’objets jQuery.
• Pour rappel, on utilise un sélecteur jQuery via la function $() ce qui aura pour effet de retourner
une collections d’objets jQuery correspondant à la requête du sélecteur.
• L’exemple suivant sélectionne chaque div du DOM et affiche l’index et l’ID de chaque div :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 232
$('div').each(function (index, value) {
console.log('div' + index + ':' + $(this).attr('id'));
});
|
jQuery – Itérations
• L’exemple suivant permet d’afficher l’attribut href de chaque lien (élément <a>) du document :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 233
$('a').each(function (index, value){
console.log($(this).attr('href'));
});
// Affichage uniquement des liens externes
$('a').each(function (index, value){
var link = $(this).attr('href');
if (link.indexOf('http://') === 0) {
console.log(link);
}
});
|
jQuery – Itérations
• On peut utiliser la fonction each() directement sur un sélecteur (qui retourne une collection), ou
l’utiliser de manière totalement indépendante du DOM. On utilisera la syntaxe $.each() :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 234
// Tableau JavaScript
var arr = ['one', 'two', 'three', 'four', 'five'];
// Itérer chaque élément du tableau
$.each(arr, function (index, value) {
console.log(value);
// Stopper l’itération après le passage sur la valeur "three"
return (value !== 'three');
});
// Affichera : one two three
|
jQuery – Itérations
• La fonction utilitaire $.each() peut aussi itérer un objet JavaScript :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 235
// Objet JavaScript
var obj = {
one: 1,
two: 2,
three: 3,
four: 4,
five: 5
};
$.each(obj, function (index, value) {
console.log(value);
});
// Affichera : 1 2 3 4 5
|
jQuery – Plugins
• Les plugins permettent d’étendre les fonctionnalités de base de jQuery.
• L’appel d’un plugin se fait toujours de la même manière : $(selector).pluginName(options);
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 236
$('.slider').bxSlider({
slideWidth: 200,
minSlides: 2,
maxSlides: 3,
slideMargin: 10
});
|
jQuery – Création d’un plugin
Structure basée sur https://github.com/jquery-boilerplate/jquery-patterns/blob/master/patterns/jquery.basic.plugin-boilerplate.js
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 237
;(function ( $, window, document ) {
...
})( jQuery, window, document );
Le point virgule avant l’invocation de la
fonction permet d’éviter d’éventuelles
erreurs (par exemple un autre plugin/script
en amont qui n’aurait pas fermé
correctement une instruction.
Trois arguments sont passés dans cette fonction
anonyme :
1) $ pour créer un alias de la fonction jQuery
2) l’objet natif window comme variable locale
3) l’objet natif document comme variable locale
2+3 : légèrement plus performant que d’appeler
les objets globaux window et document; facile la
minification.
|
jQuery – Création d’un plugin
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 238
;(function ($, window, document) {
...
var pluginName = "defaultPluginName",
defaults = {
propertyName: "value"
};
function Plugin(element, options) {
this.element = element;
this.options = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
...
})(jQuery, window, document);
$.extend() : Etend un objet avec un
ou plusieurs autres, et retourne
l'objet original modifié.
La fonction « Plugin » sera utilisée
comme constructeur (voir slide
suivante).
Appel d’une des fonctions publics du
plugin (on verra dans le slide suivante
comment elle est déclarée et rendu
accessible).
|
jQuery – Création d’un plugin
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 239
;(function ($, window, document) {
...
$.fn[pluginName] = function (options) {
return this.each(function() {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(
this,
"plugin_" + pluginName,
new Plugin(this, options)
);
}
});
};
...
})(jQuery, window, document);
Cette fonction agit comme un
Singleton pour éviter de multiples
instanciations du plugin.
Appel du constructeur
(voir slide précédente)
La propriété fn de jQuery est juste un alias
vers la propriété prototype.
De cette manière on étend jQuery en ajoutant
une nouvelle fonction à la chaine de fonction
jQuery.
Cette fonction sera : defaultPluginName();
|
jQuery – Création d’un plugin
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 240
;(function ($, window, document) {
...
$.extend(Plugin.prototype, {
init: function () {
this.yourOtherFunction("foo");
},
yourOtherFunction: function (text) {
// some logic
$(this.element).text(text);
}
});
...
})(jQuery, window, document);
On as vu que la fonction init() était appelée par le
constructeur de notre plugin.
Au sein de cette fonction, on peut déjà accéder au
DOM via this.element, et aux paramètres du plugin
via this.settings.
Comme son nom l’indique, on va pouvoir initier un
certain nombre d’actions, dont l’appel de notre
code métier.
|
jQuery – Création d’un plugin
• L’application web sur laquelle vous travaillez dispose d’un système de gestion des
comptes utilisateurs. Un formulaire permet à un visiteur de se créer un compte
utilisateur : il doit indiquer un nom, prénom, une adresse email et choisir un mot de
passe.
• Pour des raisons de sécurité, on souhaite forcer le choix d’un mot de passe sécurisé.
• On décide de passer par la bibliothèque PHP et JavaScript zxcvbn de Dropbox. Elle
permet de mesurer l’entropie d’un mot de passe en fonction de plusieurs critères.
La fonction native de zxcbn retourne un indice (propriété score) allant de 0 à 4.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 241
Exercice d’application
|
jQuery – Création d’un plugin
• Le but final est d’afficher un indicateur graphique reprenant ce score. Si le score est supérieur ou
égale à 3 on autorisera la soumission du formulaire.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 242
Exercice d’application
Exemple d’implémentation sur
dropbox.com
|
jQuery – Création d’un plugin
• Remarque : pour renforcer le calcul de l’entropie, on passera en paramètre à la fonction zxcvbn les
champs input nom, prénom et adresse email. De cette manière zxcvbn réduira l’entropie si le mot
de passe contient l’une de ces valeurs.
• Cette bibliothèque n’est pas portée sur jQuery. On devra créer un plugin jQuery pour faciliter la
manipulation des fonctions JavaScript fournies par zxcvbn et capitaliser sur le code créé
(réutilisation dans d’autres projets, partage à la communauté, etc.).
• Vous devrez procéder par étapes successives pour mener à bien cette mission.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 243
Exercice d’application
|
jQuery – Création d’un plugin
• En premier lieu, créer un formulaire d’inscription, avec les champs correspondant aux informations
qu’on souhaite récupérer (nom, prénom, email, mot de passe), ainsi qu’un bouton de soumission.
Si vous souhaitez, vous pouvez même créer la partie serveur pour persister la soumission en table,
et même appeler la bibliothèque PHP zxcvbn pour renforcer la sécurité (indispensable en
production).
• Télécharger et intégrer la bibliothèque JavaScript zxcvbn dans votre page. Commencer par utiliser
la fonction native de zxcvbn pour calculer l’entropie.
• En fonction de cette entropie, autoriser ou non la soumission du formulaire.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 244
Exercice d’application
|
jQuery – Création d’un plugin
• Seulement après, baser sur le squelette de plugin pour créer votre propre plugin que vous
nommerez « zxcvbn ». Ce plugin devra :
• Récupérer un certain nombre d’options : l’indice de force minimum attendu, des références
vers les champs input (ou directement les valeurs de ces champs), etc.
• Afficher un indicateur graphique à proximité du champ mot de passe
• Autoriser ou non la soumission du formulaire
Appeler le plugin avec le code : $("#form").zxcvbn({minScore: 3, blacklisted: […]});
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 245
Exercice d’application
|Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 246
Partie 3
L’architecture MEAN : introduction
|
MEAN – Introduction
• Depuis les 20 dernières années, il y a eu des changements conséquents dans le domaine du
développement informatique, et plus particulièrement en développement web.
• Les technologies, langages, et les architectures évoluent rapidement.
• Depuis 2/3 ans, un nouveau engouement pour le langage JavaScript dans la communauté des
développeurs. On a tendance à redécouvrir ce langage (et les possibilités qu’il offre), alors qu’il
existe depuis plus de 20 ans…
• « MEAN » est une architecture (on utilisera aussi le terme anglais « stack »).
• Utilisation massive de JavaScript, côté client et serveur.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 248
|
MEAN – Introduction
• Découverte de l’architecture MEAN et ses composantes (couches et outils utilisés et utilisables).
• L’architecture MEAN n’est pas figée : vous pouvez remplacer un framework par un autre.
• Faible couplage et forte cohésion.
• Attention, MEAN n’est pas une réponse à tous les besoins !
• En développement informatique, l’ordre des opérations est très important. On doit d’abord
comprendre les besoins et problématique, et seulement ensuite choisir les technologies qui
peuvent y répondre.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 249
|
MEAN – Introduction
• MEAN est une architecture à faible couplage et forte cohésion.
• C’est l’un des intérêts majeurs de cette stack.
• Le couplage mesure la dépendance entre système : par exemple entre les couches d’une
architecture (frameworks / modules), ou les classes d’un programme
• La cohésion mesure leurs compréhensibilités. Plus un élément à des responsabilités, plus faible
est sa cohésion.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 250
Faible couplage et forte cohésion.
|
MEAN – L’architecture LAMP
• Pour mieux comprendre ce qu’il y a de si intéressant à propos de l’architecture MEAN, on doit
s’intéresser tout d’abord à l’architecture LAMP.
• Acronyme qui désigne les technologies open-source utilisées pour créer un site ou une
application web. Plusieurs couches : plateforme, serveur web, base de données et middleware/UI.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 251
|
MEAN – L’architecture LAMP
• Faible couplage et forte cohésion : LAMP, WAMP, MAMP, WIMP, LEMP, etc.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 252
Plateforme
(système d’exploitation)
Serveur
web
Base de données
(SGBD)
Langage de programmation
(middleware / UI)
|
MEAN – L’architecture LAMP
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 253
|
MEAN – L’architecture LAMP
• LAMP s’est imposé comme un standard car c’est une architecture open-source, flexible et
rapidement déployable de nos jours.
• On peut facilement interconnecter des technologies entre elles.
• Cependant quelques limitations :
• Transformation des données
• Plusieurs langages de programmation (par exemple JavaScript, PHP et SQL)
• Scalabilité
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 254
|
MEAN – Choisir les bons outils
• A quoi ressemble le développement web de nos jours ?
• Recherche de composants / bibliothèques répondant à nos besoins. On se retrouve souvent avec
des technologies et langages différents au sein d’un même projet.
• Ne pas réinventer la roue : se reposer sur un système éprouvé, diminuer les coûts, etc.
• Nécessite par contre d’avoir des composants avec un faible couplage et une forte cohésion.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 255
|
MEAN – Choisir les bons outils
• Les managers recherchent l’outil ultime, qui permettrait de tout faire.
• Le marteau de Maslow : tentation qui consiste à travestir la réalité d’un problème en le
transformant en fonction des réponses dont on dispose, ou encore le fait de considérer qu’il n’y a
qu’une réponse unique à tous les problèmes.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 256
« Si le seul outil que vous avez est un marteau, vous
tendez à voir tout problème comme un clou ».
Abraham Maslow
|
MEAN – Choisir les bons outils
• Quand vous comparez des frameworks web, quand vous êtes à la recherche d’une solution
pouvant répondre à vos besoins, – et non une solution qui correspondrait exactement aux outils et
technologies que vous maitrisez –, …
• Il faut favoriser l’extensibilité sur la totalité, et les plugins sur les fonctionnalités du core (un
écosystème riche, robuste et actif).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 257
|
MEAN – Découverte de cette architecture
• Le terme « MEAN » est l’acronyme de MongoDB, Express,
Angular et Node.js.
• Architecture nouvelle (moins de 3 ans), en plein développement.
• En 2015 elle a été largement propulsée, profitant du nouvel
engouement pour JavaScript, comme l’architecture « à la mode ».
• Un seule langage de programmation sur toutes les couches ,
JavaScript, et un seul format d’échange de données : JSON.
• On parle alors de solution « full-stack ».
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 258
|
MEAN – Découverte de cette architecture
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 259
Même langage, même objets…
{"_id": ObjectId("278390a08i399"), "username" : "john" }
{"_id": "278390a08i399", "username" : "john" }
{"_id": "278390a08i399", "username" : "john" }
|
MEAN – Découverte de cette architecture
• L’architecture MEAN ne doit pas être confondue avec l’architecture LAMP (ou ses dérivées).
• L’architecture MEAN est similaire dans le sens où :
• elle est également basée sur des technologies open-source,
• c’est une architecture à forte cohésion et à faible couplage.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 260
|
MEAN – Découverte de cette architecture
LAMP ≠ MEAN
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 261
≠
≠
≠
≠
Linux
Apache
MySQL
PHP
MongoDB
Express
Angular
Node.js
|
MEAN – Découverte de cette architecture
LAMP  NEMA ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 262




Linux
Apache
MySQL
PHP
Node.js
Express
MongoDB
Angular
(plateforme)
(serveur web)
(persistance)
(interface utilisateur)
|
MEAN – Découverte de cette architecture
• Donc on a vu que Node.js n’est pas un serveur web.
• Node.js est « simplement » une plateforme qui inclue des modules réseau comme NET, HTTP,
HTTPS et UPD. Mais ont peut également charger des modules de plus haut niveau comme
Socket.io qui permet de gérer les WebSockets, ou bien SMTP pour créer un serveur d’envoi
d’emails…
• Cela signifie qu’on ramène ces services dans notre application, plutôt que de déployer notre
application sur un conteneur externe (comme un serveur).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 263
|
MEAN – Découverte de cette architecture
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 264
LAMP MEAN
Linux Node.js
Navigateur
MySQL
MongoDBApache
Application
(PHP)
Application
Express.js
Application
Angular
|
MEAN – Découverte de cette architecture
• Tout comme LAMP, on se retrouve avec de nombreuses technologies devant cohabiter.
• Le faite d’avoir toutes ces couches ne signifie pas pour autant qu’on va devoir interagir avec
chacune d’entre elles !
• Existe-t-il un framework permettant de réunir / connecter ces technologies avec un peu plus
d’aisance, de commodité en apportant une génération de code (scaffolding), des tests
d’intégration, des scripts de déploiement, etc. ?
• MEAN.JS et MEAN.io (voir la partie 8 dédiée à ces frameworks)
• Avoir une architecture MEAN pleinement fonctionnelle en quelques minutes.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 265
Partie 4
Node.js
Event-driven I/O server-side
JavaScript environment based on V8
|
Node.js
Présentation de Node.js : histoire,
usages, concepts clés et
architectures.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 267
|
Node.js – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 268
|
Node.js – Présentation
• Node.js est une plateforme open-source, piloté par les évènements,
pour développer des applications web côté serveur en utilisant le
langage JavaScript. On parle aussi de Node.js comme un environnement
d’exécution JavaScript.
• A l’origine Node.js pouvait seulement être installé sur Linux. Aujourd’hui,
des applications Node.js peuvent être exécutées également sur Windows
et Mac OS X.
• Moteur de script : machine virtuelle V8 de Google.
• Création : mai 2009 par Ryan Dahl.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 269
|
Node.js – Présentation
• Nous avons vu que JavaScript est par nature asynchrone. La plupart des opérations I/O en
JavaScript sont non bloquantes : requêtes HTTP, requêtes AJAX, lecture / écriture sur le système
de fichier, etc.
• Cela signifie que les opérations s’exécutent de manière linéaire sans attendre la fin de l’opération
précédente. Les fonction de callback permettent de récupérer la réponse d’une opération.
• La programmation concurrente est un paradigme de programmation qui permet d’exécuter
plusieurs opérations au cours de période de temps qui se chevauchent simultanément, au lieu
d’exécuter ces opérations séquentiellement (attente de la fin d’une opération pour exécuter la
suivante).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 270
Environnement non bloquant
|
Node.js – Présentation
• La programmation concurrente fait appel à des threads. Des langages comme Java ou
l’environnement .NET permettent de créer des applications multi-thread pour gérer la
concurrence en leur sein.
• Cependant, manipuler les threads n’est pas simple ! Communication inter-thread compliquée,
risque d’étreinte mortelle / deadlocks (interblocage de données), ralentissement parallèle,
problème de montée en charge, etc.
• Des mécanismes de synchronisation permettent de réduire ces problèmes.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 271
Environnement non bloquant
|
Node.js – Présentation
• Les langages comme Java ou l’environnement .NET ne sont pas asynchrone. Les opérations d’I/O
ne sont pas non plus asynchrone.
• C’est pour ça qu’on doit obligatoirement passer par l’utilisation de thread si on ne veut pas
bloquer l’exécution de l’application.
• Dans un serveur web comme Apache, c’est le même problème : un thread est créé pour chaque
nouvelle connexion HTTP initiée par un client.
• Dans un contexte très concurrentiel, le modèle de programmation multi-threading atteint
rapidement ses limites. Dans le cas d’un serveur web, on a par exemple un nombre maximum de
thread en simultané (donc de thread disponible).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 272
Environnement non bloquant
|
Node.js – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 273
Environnement non bloquant
|
Node.js – Présentation
• Le problème ne se pose pas dans Node.js, car on profite de la puissante du langage JavaScript qui
est asynchrone.
• D’ailleurs, Node.js est single-threaded, c’est-à-dire que la programmation multi-thread est
impossible.
• Par exemple, dans le cas d’un serveur web créé avec Node.js, la nature non bloquante des
opérations I/O permet de gérer de très nombreuses connexions simultanées sans que cela
impacte les performances de l’application.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 274
Environnement non bloquant
|
Node.js – Présentation
• De manière plus concrète, Node.js dispose en son sein d’une boucle d’évènements (event loop)
qui va continuellement traiter les évènements reçus.
• Dans le cas d’un serveur web avec Node.js, le serveur va conserver une pile de fonctions à
exécuter (dites de callback) lors de la réception d’évènements précis.
• L’unique thread de Node.js va ainsi traiter les évènements apparaissant dans la queue
d’évènements les uns après les autres, au fil des requêtes et fin d’IO.
• Permettre de traiter des milliers de requêtes simultanées en consommant très peu de mémoire.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 275
Environnement non bloquant
|
Node.js – Présentation
• Seul inconvénient de ce modèle single-threaded : on ne profite pas de la puissance complète du
processeur s’il dispose de plusieurs cœurs.
• Pour ce faire, il faut lancer les applications Node.js en mode cluster (accessible via le module
« Cluster » de Node.js).
• Pour faire simple, ce module permet de partager des sockets entre processus pour mettre en
place du load balancing entre les cœurs du processeur.
• Plus d’informations sur la documentation : https://nodejs.org/api/cluster.html
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 276
Environnement non bloquant
|
Node.js – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 277
Environnement non bloquant
|
Node.js – Présentation
• Piloté par les évènements.
• Modèle d’entrées / sorties (I/O) asynchrone non bloquant en passant par l’utilisation de callbacks.
• Tout à l’intérieur de Node.js est traité par un seul et unique thread.
• Approche réactive implémentée par le boucle d’évènements (voir schéma précédent).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 278
Particularités de Node.js
|
Node.js – Présentation
• Node.js à un cycle de développement très rapide.
• Disclaimer : certaines fonctions de cette présentation
seront peut être dépréciés dans quelques mois…
• Généralement il y a au minimum 2 versions publiées
chaque mois.
• Des modifications importantes entre les versions :
attention aux outils dépréciés et aux tutoriels qui ne
sont plus à jour sur le web.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 279
Cycle de développement et versions
|
Node.js – Présentation
• On distingue deux cycles de développement différents : les versions dites « LTS » et les versions
dites « Stable ».
• Versions LTS – L'abréviation LTS signifie Long Term Support, ou maintenue à long terme (3 ans).
Ces versions portent des numéros pairs et mettent l’accent sur la stabilité et la sécurité. A
privilégier en environnement de production. Dernière version LTS en date : v4.x.x (nom de code
Argon).
• Versions « Stable » – Ces versions portent de numéros impairs et ont des mises à jour plus
fréquentes du code. Ajout de nouvelles fonctionnalités et amélioration de l’API existante. Le nom
« stable » ne doit pas être compris au sens français du terme. Dernière version en date : v5.x.x.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 280
Cycle de développement et versions
|
Node.js – Présentation
• En décembre 2014, suit à un conflit interne en les développeurs de Node.js un
fork est créé : il s’agit de io.js. En juin 2015 Node.js et io.js se sont regroupés
pour travailler en ensemble.
• Les versions 1.x.x à 3.x.x réfèrent au fork io.js.
• La version 4.x.x de Node.js a été créé suite au regroupement de io.js et Node.js
(qui était en version 0.12.x).
• Attention : on retrouve énormément de tutoriels concernant la version 0.12.x.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 281
Cycle de développement et versions
|
Node.js – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 282
Installation
• Aller sur nodejs.org et installer
Node.js sur votre poste.
• Télécharger la version 5.x.x.
• Exécuter la commande node -v
dans votre terminal pour vérifier
que l’installation s’est bien passée.
|Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 283
|
Node.js – Présentation
• Comment peut on faire tourner JavaScript en dehors d’un navigateur web ?
• On pourrait penser que JavaScript sert seulement à manipuler le DOM d’une page et à interagir
avec les évènements utilisateur via le navigateur (clic souris, etc.).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 284
JavaScript côté serveur ?
JavaScript
Si vous vous êtes fait la représentation
suivante de JavaScript, vous pourriez
être vraiment confus par cette notion
d’utiliser JavaScript en hors d’un
navigateur.
|
Node.js – Présentation
« JavaScript » peut être décomposer en trois
parts égales :
• Le langage en lui-même (éléments de
langage, mots clés, concepts, structure, etc.)
• La plateforme sur lequel il peut tourner : V8,
SpiderMonkey, Chakra, etc.
• Les API : Navigator, Window, Document…
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 285
JavaScript côté serveur ?
JavaScript
Plateforme
APIs
|
Node.js – Présentation
• Ces API dépendent de la plateforme sur
laquelle JavaScript (au sens large) est
exécuté.
• Dans le cas de JavaScript côté client, ces API
sont fournies par le navigateur. Chaque
navigateur gère ces API à sa manière (d’où
parfois des problèmes de compatibilité entre
navigateurs).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 286
JavaScript côté serveur ?
|
Node.js – Présentation
• Si vous voulez exécuter les mêmes instructions sur Node.js, créer un fichier foo.js avec les lignes
suivantes :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 287
JavaScript côté serveur ?
console.log(navigator.appName);
console.log(navigator.appVersion);
• Puis exécutez-le avec Node.js en utilisant la commande « node » suivie de l’emplacement du
fichier (ou de son nom si la console est ouverte dans le même répertoire).
node foo.js
|
Node.js – Présentation
• Avec l’architecture MEAN on utilise la langage JavaScript de bout en bout :
• dans le navigateur,
• sur le serveur pour nos programmes métiers mais aussi dans la couche de persistance.
• Quand vous exécuter du JavaScript sur chacune des couches de l’architecture MEAN
(serveur, persistance, client) vous devez connaitre quelles sont les APIs disponibles.
• JavaScript, le langage est le seul élément qui est consistant dans les couches de notre
architecture.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 288
JavaScript côté serveur ?
|
Node.js – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 289
JavaScript côté serveur ?
|
Node.js – Présentation
• Pour rappel on peut décomposer un navigateur en deux grandes parties : le moteur de rendu et
le moteur de script.
• Ces moteurs peuvent égaler tourner en dehors de l’environnement d’un navigateur. Cela ouvre un
tout nouveau champ de possibilité.
• Mais à quoi ça sert de faire tourner sur un serveur un moteur de rendu qui est sensé permettre
d’afficher à l’écran une page… en dehors d’un navigateur ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 290
JavaScript côté serveur ?
|
Node.js – Présentation
• Reproduire le comportement d’un navigateur sans avoir à charger la page avec un navigateur.
Utilisé pour faire des tests d’intégration.
• Exemple de PhantomJS (pour de rendu WebKit) ou SlimerJS (reproduit Gecko). Et si un test est en
échec, on peut demander la génération d’une capture d’écran.
• On peut également faire tourner un moteur de script côté serveur : c’est ce que fait Node.js via le
moteur V8 de Google.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 291
JavaScript côté serveur ?
|
Node.js – Présentation
Pour faire simple : presque
tout le monde.
Aller sur le wiki du
repository GitHub de
Node.js pour découvrir en
détail les usages faits par
certaines des entreprises
mentionnées ici.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 292
Qui utilise Node.js ?
|
Node.js – Présentation
• Migration de Java (et Java EE pour le site internet) vers JavaScript et Node.js.
• Depuis le passage à Node.js : performances améliorées et coûts d’infrastructure réduits.
• « We now run one quarter of the EC2 instances on Node compared with the legacy Java stack,
whilst serving the same number of subscribers at lower latencies. »
• Gain de productivité pour les développeurs : itérations (développement, tests, build, déploiement)
plus faciles, du fait de la nature dynamique de JavaScript.
• Plus d’infos sur talentbuddy « Building With Node.js At Netflix, an Interview With Yunong J Xiao »
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 293
Qui utilise Node.js ? Le cas
|
Node.js – Présentation
• eBay utilisait Java et les frameworks web Spring et JAX-RS
• Depuis, migration vers JavaScript en Node.js dans le but d’améliorer les performances et de
switcher vers une plateforme moderne vers laquelle les développeurs seraient excités de travailler
avec.
• Le passage en full JavaScript a grandement facilité les itérations.
• Plus d’infos sur talentbuddy « Building With Node.js At eBay, an Interview With John Cline »
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 294
Qui utilise Node.js ? Le cas
|
Node.js – Présentation
• Linkedin était écrit avec le framework Ruby on Rails, mais c’est maintenant l’une des plus
importante application Node.js en production. En complément de Node.js, HTML5 est utilisée
pour la version mobile et l’application mobile.
• « We use a ton of technologies at LinkedIn, but for the mobile server piece, it’s entirely Node-based.”
• Linkedin voulait migrer vers une solution leur apportant plus de flexibilité (par exemple via la
programmation asynchrone et évènementielle).
• Gain en performance et en scalabilité.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 295
Qui utilise Node.js ? Le cas
|
Node.js – Présentation
• Réduction drastique de l’infrastructure serveur :
• « The improvements the team saw were staggering. They went from running 15 servers with 15
instances (virtual servers) on each physical machine, to just four instances that can handle double
the traffic. »
• Plus d’infos sur talentbuddy « Building With Node.js At Linkedin », et VentureBeat.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 296
Qui utilise Node.js ? Le cas
|
Node.js – Présentation
• Node.js est organisé en plusieurs modules.
Chaque module gère une fonctionnalité du
core : système de fichier, réseau (DNS, HTTP,
TCP, UDP et TLS), fonctions
cryptographiques, etc.
• Les modules sont chargés dans le code avec
l’instruction require().
• Documentation complète :
https://nodejs.org/dist/latest-v5.x/docs/api/
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 297
Modules du core
|
Node.js – CommonJS
• Pour charger une bibliothèque dans une page web, on utilise la balise HTML <script>.
• Dans l’environnement Node.js, on utilise l’instruction require() pour charger un module interne
ou externe. Par exemple le code suivant permet de charger le framework web Express :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 298
Chargement d’un module
const http = require('express');
|
Node.js – CommonJS
• Quand nous appelons Express, nous chargeons en fait un module CommonJS dans notre
application. C’est ce qu’on appelle une dépendance.
• Comment être sur que cette dépendance est mise à disposition de notre application ? Nous
définissons les dépendances dans un fichier de configuration appelé « package.json ».
• Cette dépendance doit être téléchargé en amont via une application qu’on appelle « npm ».
• Nous allons voir dans la partie suivante comment ajouter n’importe quelle dépendance dans
Node.js (et pas seulement un serveur web comme Express).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 299
Principe de fonctionnement
|
Node.js – CommonJS
• CommonJS est une API permettant d’écrire des programmes JavaScript s'exécutant ailleurs que
dans un navigateur web. Il permet de gérer des dépendances côté serveur (à l’inverse de
RequireJS).
• CommonJS a de nombreuses implémentations, par exemple dans Node.js.
• Les bibliothèques qui se basent sur l’API CommonJS ne sont pas fortement liées à une plateforme
spécifique.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 300
Principe de fonctionnement
|
Node.js – CommonJS
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 301
Chargement de modules
CommonJS
Exportation du module Express
|
Node.js – CommonJS
• La nature même de JavaScript fait que tout est public et global.
• Les modules donne la possibilité d’avoir des variables et des méthodes privées. En fait tout dans
un module CommonJS est privé, à moins qu’on exporte explicitement ce module.
• Cette possibilité là est très intéressante, car non supportée nativement par les anciennes version
JavaScript (avant ECMAScript 6). CommonJS joue le rôle d’un polyfill.
• Pour rappel (Wikipedia) : « un polyfill est un ensemble de fonctions permettant de simuler sur un
navigateur web ancien des fonctionnalités qui ne sont pas nativement disponibles. »
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 302
Exportation
|
Node.js – CommonJS
• require() charge le module lui-même mais aussi toutes ces dépendances.
• module.exports === public API
• Les variables et fonctions qui ne sont pas dans module.exports sont privées.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 303
Exportation
|
Node.js – Le gestionnaire de paquets npm
• Bien que Node.js ne soit pas un framework JavaScript, la plupart de ses modules sont écrits en
JavaScript. Les développeurs peuvent étendre les fonctionnalités de base de Node.js en
développant des modules en JavaScript.
• On peut facilement installer et partager des modules en utilisant npm (Node Package Manager).
• npm est un gestionnaire de paquets et de dépendances écrit entièrement en JavaScript et qui est
installé automatiquement avec la plateforme Node.js (depuis 2011). Mais on peut l’utiliser en
dehors de Node.js.
• Pour faire une analogie à PHP, le gestionnaire de dépendances Composer se rapproche de npm.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 304
Présentation de npm
|
Node.js – Le gestionnaire de paquets npm
• Attention, npm ne doit pas être confondue avec l’instruction require() de CommonJS.
• npm n’est pas utilisé pour charger du code ou des bibliothèques. Au lieu de ça, il est utilisé pour
installer des modules et gérer les dépendances entre module en ligne de commande.
• « Composer se rapproche de npm » : sauf que Composer permet également de charger les
dépendances dans une application PHP (via un require/include sur le fichier vendor/autoload.php).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 305
Présentation de npm
|
Node.js – Le gestionnaire de paquets npm
• Un module (ou package) est juste un répertoire
disposant d’un ou plusieurs fichiers. Il dispose
également d’un fichier nommé package.json qui
contient des métadata sur le module (nom, version,
dépendances, etc.).
• Une application web typique va dépendre de
plusieurs dizaines de modules.
• Les modules sont souvent petits : l’idée générale est
qu’un module doit avoir une unique responsabilité.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 306
Principe de fonctionnement
|
Node.js – Le gestionnaire de paquets npm
• L’utilisation de npm se fait en ligne de
commandes via la console du système
hôte où est installé Node.js.
• Le site npmjs.com liste les modules qui
sont disponibles. On peut le comparer à
packagist.org pour PHP.
• On retrouve des modules Node.js mais
aussi des modules front-end comme
Angular ou bower.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 307
Principe de fonctionnement
|
Node.js – Le gestionnaire de paquets npm
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 308
Principe de fonctionnement
public
registery
npm publish packageName
npm install packageName
|
Node.js – Le gestionnaire de paquets npm
• Un module peut être téléchargé avec la commande suivante :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 309
Installation d’un module
npm install <package_name>
• Cela créera un répertoire « node_modules » dans le répertoire de votre application (s’il n’existe
pas déjà), et téléchargera le module dans ce répertoire.
• Pensez bien à ajouter le répertoire node_modules dans le fichier .gitignore (pour qu’il ne soit pas
commité dans votre repository). Les développeurs qui travaillent sur le projet devront simplement
exécuter la commande npm update pour télécharger les même dépendances que vous.
|
Node.js – Le gestionnaire de paquets npm
• Quelle version du module est installée ?
• Fichier package.json inexistant : installation de la dernière version
• Fichier package.json existant : installation de la version du module spécifiée dans ce fichier
(si spécifiée, sinon installation de la dernière version).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 310
Installation d’un module
|
Node.js – Le gestionnaire de paquets npm
• Permet de lister les modules dont votre application dépend.
• Permet de spécifier les versions des module que votre projet utilise.
• Facilite grandement le partage de votre application auprès d’autres développeurs.
• Le fichier package.json doit contenir au minimum les propriétés « name » et « version ».
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 311
Le fichier package.json
{
"name": "my-awesome-package",
"version": "1.0.0"
}
|
Node.js – Le gestionnaire de paquets npm
• La bonne pratique consiste à créer un fichier package.json dés la création de votre application en
utilisant la commande suivante :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 312
Le fichier package.json
npm init
• On peut également définir des valeurs par défaut pour éviter de renseigner à chaque fois les
mêmes données à l’exécution de la commande init :
npm set init.author.email "wombat@npmjs.com"
npm set init.author.name "ag_dubs"
npm set init.license "MIT"
|
Node.js – Le gestionnaire de paquets npm
• On peut manuellement modifier le fichier
package.json pour spécifier des dépendances.
• On distingue 2 types de dépendances : celles de
production (dans la propriété « dependencies ») et
de développement (dans la propriété
« devDependencies »).
• Exemple de dépendances en développement : tests
unitaires, minification, transpiler, etc.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 313
Le fichier package.json
{
"name": "my-awesome-package",
"version": "1.0.0",
"license": "MIT",
"author" : "John Doe",
"dependencies": {
"my_dep": "^1.0.0",
"express": "~4.13.0",
"mongoose": "~3.6.1 "
},
"devDependencies" : {
"minify": "^3.1.0"
}
}
|
Node.js – Le gestionnaire de paquets npm
• Pour ajouter des dépendances à votre application, plutôt que de modifier manuellement le fichier
package.json, le plus simple est d’utiliser les commandes suivantes :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 314
Le fichier package.json
npm install <package_name> --save
npm install <package_name> --save-dev
|
Node.js – Le gestionnaire de paquets npm
• De temps en temps, pensez à mettre à jour les modules dont votre application dépend de sorte à
profiter des dernières nouveautés et des corrections de bugs / vulnérabilités. Pour ce faire,
exécuter la commande suivante (au même niveau que package.json) :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 315
Mettre à jour vos dépendances
npm update
|
Node.js – Le gestionnaire de paquets npm
• Pour supprimer une dépendance du répertoire node_modules et du fichier package.json, utiliser
la commande suivante :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 316
Supprimer une dépendance
npm uninstall --save <package_name>
|
Node.js – Le gestionnaire de paquets npm
• Semver (Semantic Versioning) est une gestion sémantique des versions d’un logiciel / modules.
En d’autres termes, une façon de numéroter les versions de manière logique.
• Ce n’est pas une norme, mais une bonne pratique (que je vous recommande d’appliquer)…
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 317
Comprendre les versions (semver)
4.13.2
Version majeure
A incrémenter quand il y a des
changements rétro-incompatibles Version mineur
A incrémenter quand il y a des
changements rétro-compatibles
Correctif / patch
A incrémenter quand il y a des
corrections d’anomalies rétro-
compatibles
|
Node.js – Le gestionnaire de paquets npm
• On renseigne souvent des numéros de versions des dépendances dans le fichier package.json.
Parfois on rencontre la notation ~ (tilde) ou ^ (caret).
• L’opérateur ~ permet de prévenir des changements brutaux alors que ^ est plus permissif.
• Pour le tilde, il va inclure la version mineure la plus récente mais sans changer de branche.
• ~1.2.3 équivaut à >=1.2.3 <1.3.0
• Pour le caret il inclura la version majeure la plus récente.
• ^1.2.3 équivaut à >=1.2.3 <2.0.0
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 318
Comprendre les versions (semver)
|
Node.js – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 319
Architecture interne de Node.js
|
Node.js – Exercices basiques
• Ecrire un programme JavaScript qui permette d’afficher le texte « Hello World » un fois exécuté
dans Node.js.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 320
L’incontournable « Hello World »
|
Node.js – Exercices basiques
• Ecrire un programme JavaScript qui permette d’afficher le texte « Hello World » un fois exécuté
dans Node.js.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 321
L’incontournable « Hello World »
console.log("Hello World!");
Fichier hello.js
$ node hello.js
Hello World!
$ _
Terminal
|
Node.js – Exercices basiques
• Ecrire un programme JavaScript qui permette d’afficher le texte « Bonjour <nom> ». Le nom de
l’utilisateur étant récupéré en argument.
• Aide : utiliser l’objet natif « process ».
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 322
Passage d’arguments
|
Node.js – Exercices basiques
• Ecrire un programme JavaScript qui permette d’afficher le texte « Bonjour <nom> ». Le nom de
l’utilisateur étant récupéré en argument.
• Ecrire un deuxième programme qui permette d’afficher l’ensemble des arguments saisis.
• Aide : utiliser l’objet natif « process » et le tableau argv.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 323
Passage d’arguments
|
Node.js – Exercices basiques
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 324
Passage d’arguments
var name = process.argv[2];
console.log("Hello " + name + "!"");
Fichier helloBis.js
$ node helloBis.js Guillaume
Hello Guillaume!
$ _
Terminal
|
Node.js – Exercices basiques
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 325
Passage d’arguments
var arguments = "";
for (var i=2; i < process.argv.length; i++) {
console.log(process.argv[i]);
}
Fichier displayArgs.js
$ node displayArgs.js Formation ORT 3CSi Lyon
Formation
ORT
3CSi
Lyon
$ _
Terminal
|
Node.js – Exercices basiques
• Sur le même principe des exercices précédents, écrire un programme qui émule une calculatrice
basique. Le premier argument sera le type d’opération (addition, soustraction, multiplication et
division), et les suivants les nombres à calculer.
• Bonnes pratiques : séparer bien votre code en plusieurs fonctions.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 326
Passage d’arguments
|
Node.js Création d’un serveur web
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 327
|
Node.js – Création d’un serveur web
• Node.js n’est pas un serveur web, c’est une
plateforme / environnement d’exécution !
• Cet idée fausse que Node.js serait un serveur
web commence sur le programme d’exemple
« Hello World » qui implémente un serveur
web.
• Ce qu’ils essayent de démontrer c’est que
Node.js est une plateforme, qui peut, dans cet
exemple, permettre de gérer nativement le
protocole HTTP.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 328
|
Node.js – Création d’un serveur web
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 329
const http = require('http');
const hostname = '127.0.0.1';
const port = 1337;
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('Hello World!n');
res.end();
}).listen(port, hostname, () => {
console.log('Server running at http://'+ hostname +':'+ port +'/');
});
|
Node.js – Création d’un serveur web
• Modifier le code précédent pour faire en sorte d’afficher les paramètres GET que l’utilisateur
aurait saisi dans l’URL.
• Vous devrez charger le module « url » pour récupérer les paramètres (utilisez la documentation
https://nodejs.org/api/).
• Astuce : passer par la fonction url.parse()
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 330
Exercice d’application
|
Node.js – Création d’un serveur web
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 331
Exercice d’application
const http = require('http');
const url = require('url');
const hostname = '127.0.0.1';
const port = process.env.PORT || 5000;
http.createServer((req, res) => {
var parsedUrl = url.parse(req.url, true);
var queryAsObject = parsedUrl.query;
res.end(JSON.stringify(queryAsObject));
}).listen(port, hostname, () => {
console.log('Server running at http://'+ hostname +':'+ port +'/');
});
|
Node.js – Création d’un serveur web
• Créer un serveur HTTP avec Node.js qui retourne des données au format JSON quand :
• Il reçoit une requête GET sur l’URI « /api/formatDateFr »
• L’objet JSON doit retourner les propriétés année, mois, jours, heures, minutes ainsi qu’une
propriété retourner la date du type : « Mardi 23 février 2016 à 12h00 ».
• Il reçoit une requête GET sur l’URI « /api/formatDatetime »
• L’objet JSON doit retourner une seule propriété dont la valeur est au format YYYY-MM-DD HH:ii:ss
• Ces deux requêtes acceptent un paramètre GET « time » ayant pour valeur le temps UNIX
(timestamp = nombre de ms écoulée depuis le 1er janvier 1970).
• Retourner une erreur 404 si une autre URI du répertoire /api/ est appelée.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 332
Exercice d’application
|
Aparté
Heroku
Déploiement de vos applications
dans le Cloud.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 333
|
Heroku – Déploiement de vos applications sur le cloud
• Heroku est un service de cloud computing de type PaaS, créé en
2007 puis racheté depuis par Salesforce.com. Il propose des services
de cloud aux entreprises et développeurs (dont une version gratuite,
mais limité à 5 apps).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 334
Présentation
• PaaS = Platform as a Service (Plate-forme en tant que Service)
• l'entreprise cliente maintient les applications proprement dites ;
• le fournisseur cloud maintient la plate-forme d'exécution de ces applications (serveur,
système d’exploitation, sécurité, etc.).
|
Heroku – Déploiement de vos applications sur le cloud
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 335
Présentation
• Le modèle de cloud computing PaaS est à différencier du
modèle SaaS.
• SaaS = Software as a Service (logiciel en tant que service)
• Modèle d'exploitation commerciale des logiciels.
• Les logiciels sont installés sur des serveurs distants
plutôt que sur la machine de l'utilisateur.
• Les clients ne paient pas une licence d’utilisation mais
un abonnement.
|
Heroku – Déploiement de vos applications sur le cloud
• Plusieurs runtimes pris en charge par Heroku : Ruby on Rails, Node.js, Java, Spring, Python, Scala
ainsi que PHP de façon officieuse.
• Ces runtimes tournent dans un stack nommé « Cedar » qui tourne sous Ubuntu.
• Intérêts de Heroku :
• Déploiement très rapide d'applications web dans le cloud
• Prise en charge de nombreux langages / technologies
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 336
Présentation
|
Heroku – Déploiement de vos applications sur le cloud
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 337
Présentation
Les développeurs
déploient le code
(en CLI ou via
GitHub)
Les applications
s’exécutent dans
des « conteneurs »
Vous pouvez gérer les
applications depuis un
tableau de bord.
Gestion de la
persistance des
données : Postgres,
Redis, etc.
Les clients initient des
requêtes qui sont
envoyées et traités par
l’application ciblée.
|
Heroku – Déploiement de vos applications sur le cloud
• Google Cloud Platform permet également de déployer des applications Node.js dans le Cloud.
• Il est plus probable que vous rencontriez Google Cloud Platerform que Heroku en entreprise.
• Il n’y a pas de formule gratuite. Cependant, Google vous offre un crédit de $300 valable pendant
60 jours. Passé ce délais, ce crédit est perdu et votre instance de test est supprimée (vous ne serez
pas facturé passé cette période d’évaluation si vous n’utilisez plus la plateforme).
• Google a créé une bibliothèque d’abstraction qui facilite l’usage de Node.js lors du déploiement.
• Tutoriel : https://cloud.google.com/nodejs/
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 338
Solutions alternatives
|
Heroku – Déploiement de vos applications sur le cloud
• Modulus : cloud pour Node.js, PHP, Java, Meteor, Docker,
Python, etc.
• Remarque : il existe aussi des plateformes Cloud dédiées
au déploiement de votre base de données. C’est le cas de
Google Cloud Datastore, Compose et MongoLab. On
utilisera ce dernier dans la partie relative à MongoDB.
• Votre application peut donc être hébergée entièrement
dans le Cloud en quelques lignes de commandes… !
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 339
Solutions alternatives
|
Heroku – Déploiement de vos applications sur le cloud
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 340
Inscription (gratuite)
• Rendez-vous sur https://signup.heroku.com/
et créer un compte utilisateur gratuit.
• Quelques limitations cependant : l’instance se
mettra en sommeil après 30 minutes
d’inactivités, et devra être stoppée 6h sur une
période de 24 heures.
• Suffisant pour notre usage de test…
|
Heroku – Déploiement de vos applications sur le cloud
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 341
Votre tableau de bord
|
Heroku – Déploiement de vos applications sur le cloud
• Suivez le « Getting Started », partie « Setup » pour installer l’environnement Heroku sur votre
poste : https://devcenter.heroku.com/articles/getting-started-with-nodejs#set-up
• Cet environnement va vous permettre d’utiliser les commandes heroku pour votre terminal.
• Vérifier que l’installation s’est bien terminée en tapant la commande heroku.
• Identifiez-vous avec la commande heroku login.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 342
Déploiement d’une application Node.js
|
Heroku – Déploiement de vos applications sur le cloud
• Nous allons déployer un serveur web basique (dans le même principe que notre premier exercice
Hello World) sur la plateforme Cloud Heroku.
• Si ce n’est pas déjà fait, lancer la commande npm init pour générer un fichier package.json.
• Modifier le fichier package.json généré pour spécifier le script à lancer au déploiement de
l’application. Cela ce fait via la propriété start de l’objet scripts :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 343
Déploiement d’une application Node.js
{
"scripts": {
"start": "node index.js"
}
}
|
Heroku – Déploiement de vos applications sur le cloud
• On doit adapter légèrement le code du serveur web. Le numéro de port sur lequel le serveur web
va écouter ne peut pas être spécifié manuellement sur Heroku. On utilisera donc la variable
d’environnement PORT :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 344
Déploiement d’une application Node.js
const port = process.env.PORT || 5000;
http.createServer((req, res) => {
...
}).listen(port);
|
Heroku – Déploiement de vos applications sur le cloud
• Si ce n’est pas déjà fait : lancer la commande npm install : cela va créer un répertoire
node_modules.
• Pour déployer les application, Heroku utilise GIT. On doit donc initier un repository git avec la
commande git init. Cela va créer un répertoire cache .git à la racine de votre application.
• Exécuter la commande « git add . » (le point est important !) pour ajouter l’ensemble des fichiers
de votre application dans votre nouveau repository. Bien sur, il faut ensuite commiter vos
changement avec la commande git commit –m "Votre message".
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 345
Déploiement d’une application Node.js
|
Heroku – Déploiement de vos applications sur le cloud
• L’idée est en fait de faire un « push » de notre code dans une branche gérer par Heroku nommé
« heroku ».
• Pour créer cette branche et lancer l’écoute active par Heroku, exécuter la commande heroku
create.
• Ensuite on exécutera la commande : git push heroku master. Analyser bien les logs sur votre
terminal, toutes les actions faites par Heroku sont décrites. A la fin du traitement, l’URL de votre
projet dans le cloud s’affichera.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 346
Déploiement d’une application Node.js
|
Heroku – Déploiement de vos applications sur le cloud
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 347
Déploiement d’une application Node.js
$ git push heroku master
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Node.js app detected
remote:
remote: -----> Creating runtime environment
...
remote: -----> Launching...
remote: Released v3
remote: https://secret-forest-98123.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/secret-forest-98426.git
* [new branch] master -> master
|
Heroku – Déploiement de vos applications sur le cloud
• Heroku va attribuer automatiquement une URL unique à votre application.
• Au lieu de copier-coller l’URL de votre app Heroku, utiliser la commande heroku open.
• Cependant, vous pouvez choisir manuellement une URL. Au moment de la création de la branche
heroku dans votre repository GIT, utiliser plutôt la commande suivante (le troisième paramètre
étant le nom que vous souhaitez donné à votre application) :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 348
Déploiement d’une application Node.js
heroku create nodejs-formation-ort
• Vous pouvez aussi utiliser la commande heroku apps:rename si votre app est déjà déployée.
|
Heroku – Déploiement de vos applications sur le cloud
• En cas de modification de votre code source :
• git add <file>
• git commit –m "Message"
• git push heroku master
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 349
Déploiement d’une application Node.js
Cette dernière commande va automatiquement relancer le déploiement
de votre application sur Heroku. La même URL sera conservée : c’est
simplement un remplacement des fichiers modifiés.
|
Node.js
Manipulation de fichier
(le module FileSystem)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 350
|
Node.js – Le module « fs » (File System)
• Le module du core « fs » de Node.js fournit une API qui permet d’interagir avec le système de
fichiers et d'effectuer certaines opérations IO comme créer, lire ou écrire un fichier.
• Comme « fs » est un module du core, nous n’avons pas besoin de la configurer avant de l’utiliser.
Pour le charger, comme tout autre module CommonJS, on utilisera l’instruction require() :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 351
Présentation
var fs = require("fs");
|
Node.js – Le module « fs » (File System)
• Toutes les fonctions de ce module peuvent être utilisées de manière synchrone ou asynchrone.
• Si vous utilisez la forme asynchrone, vous devrez utiliser une fonction de callback.
• Les arguments passés à cette fonction de callback dépendent de la fonction utilisée.
• Cependant, de manière générale, le premier argument est réservé à une exception. Si l’opération
s’est bien passée, la valeur retournée par cet argument sera null ou undefined.
• Les fonctions synchrone reprennent souvent le nom de la fonction asynchrone suivi de « Sync ».
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 352
Synchrone ou asynchrone ?
|
Node.js – Le module « fs » (File System)
• Ce code d’exemple supprime le fichier /tmp/hello. On utilise la fonction unlink() du module « fs ».
Le nom de cette fonction est un héritage de la norme POSIX.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 353
Suppression d’un fichier (asynchrone)
const fs = require('fs');
fs.unlink('/tmp/hello', (err) => {
if (err) {
throw err;
}
console.log('successfully deleted /tmp/hello');
});
|
Node.js – Le module « fs » (File System)
• Quand vous utilisez la version synchrone, les éventuelles exceptions sont immédiatement levees.
Vous devez utilizer le bloc try / catch pour gérer ces exceptions.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 354
Suppression d’un fichier (synchrone)
const fs = require('fs');
fs.unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');
|
Node.js – Le module « fs » (File System)
• Que fait ce code ? Identifiez-vous un problème ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 355
Ordre des opérations
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
console.log('renamed complete');
});
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`);
});
|
Node.js – Le module « fs » (File System)
• Avec des fonctions asynchrones, l’ordre
des opération n’est pas garantie !
• fs.stat pourrait très bien être exécuté
avant fs.rename.
• Donc le code suivant est sujet à erreurs.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 356
Ordre des opérations
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
console.log('renamed complete');
});
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`);
});
|
Node.js – Le module « fs » (File System)
• En programmation asynchrone, vous devez
toujours vous baser sur les callbacks.
• Utiliser une chaine de callback entre
rename et stat.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 357
Ordre des opérations
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) {
throw err;
}
fs.stat('/tmp/world', (err, stats) => {
if (err) {
throw err;
}
console.log(`stats:
${JSON.stringify(stats)}`);
});
});
|
Node.js – Le module « fs » (File System)
• Si vous faites des traitements lourd, vous êtes fortement encourager à utiliser les appels
asynchrones.
• La version synchrone va bloquer le processus entier jusqu’à complétion de sa tâche. Comme
Node.js est mono-threadé, toutes les autres connexions vont être stoppées (voir schéma
d’architecture dans les slides précédentes).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 358
Ordre des opérations
|
Node.js – Le module « fs » (File System)
• Plusieurs methodes pour créer un fichier : write, writeFile ou createWriteStream. Le plus simple est
d’utiliser la function writeFile() du module :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 359
Création d’un fichier
var fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
|
Node.js – Le module « fs » (File System)
• Créer un serveur web avec Node.js. Chaque chargement de page doit incrémenter un compteur
de visite contenu dans un fichier texte. Vous devrez donc : créer le serveur web, créer le fichier
texte s’il n’existe pas, puis lire son contenu et incrémenter le nombre de visite.
• Vous devrez charger les modules natifs « http » et « fs ».
• Utilisez les fonctions asynchrones readFile() et writeFile() du module fs.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 360
Exercice d’application
|
Node.js – Le module « fs » (File System)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 361
Exercice d’application
...
http.createServer(function (request, response) {
fs.readFile("test.txt", 'utf-8', function (error, data) {
response.writeHead(200, { 'Content-Type': 'text/plain‘ });
// Incrémenter le nombre obtenu a partir du fichier
data = parseInt(data) + 1;
// Mettre à jour le fichier (numéro incrémenté)
fs.writeFile('test.txt', data);
response.end(‘Page rafraichie ' + data + ' fois !');
});
}).listen(port);
TODO : vérifier si la
requête est sur le fichier
favicon.ico. Dans ce cas
ne pas incrémenter le
compteur.
|
Node.js – Le module « fs » (File System)
• Créer un programme asynchrone qui affiche sur la console une liste de fichiers dans un répertoire
choisi et filtré par extension.
• 1er argument : le répertoire ciblé
• 2nd argument : l’extension à filtrer (ignorer les fichiers n’ayant pas cette extension).
• Charger les modules « fs » et « path ». Vous pouvez utiliser les fonctions suivantes pour vous aider :
• fs.readdir() pour lire le contenu d’un répertoire
• path.extname() pour récupérer l’extension d’un fichier
• Récupérer les arguments de votre programma via le tableau process.argv[].
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 362
Exercice d’application (2)
|
Node.js – Le module « fs » (File System)
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 363
Exercice d’application (2)
var fs = require('fs');
var path = require('path');
var directory = process.argv[2];
var ext = '.' + process.argv[3];
fs.readdir(directory, function (err, files) {
if (err) {
throw err;
}
files.filter(function (file) {
return fs.statSync(file).isFile();
}).filter(function (file) {
return (path.extname(file) == ext);
}).forEach(function (file) {
console.log("%s (%s)", file, path.extname(file));
});
});
|
Node.js – Le module « fs » (File System)
• La fonction readFile() permet de lire un fichier et d’afficher son contenu.
• Utiliser cette fonction pour récupérer le contenu de fichiers HTML.
• Créer un serveur HTTP avec Node.js, gérer plusieurs routes, et retourner une page HTML
différente en fonction de la route.
• Pensez-bien à adapter le header retourné :
• Content-type : text/html
• Content-length : la taille de la page HTML
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 364
Exercice d’application (3)
|
Node.js Création d’un module
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 365
|
Node.js – Création d’un module
• Un module encapsule du code correspondant au sein d’un même fichier.
• Par exemple pour créer un module « foo » on créera un fichier foo.js. Pour charger le module on
utilisera la fonction require() de CommonJS. On passera en argument le chemin relatif du fichier
par rapport où on écrit ce code :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 366
var foo = require('./foo');
• Si vous utiliser le code suivant, le module « foo » devra être dans le répertoire « node_modules ».
var foo = require('foo');
main.js
main.js
|
Node.js – Création d’un module
• Pour pouvoir utiliser les fonction d’un module dans un autre fichier (par exemple le fichier où on a
fait l’appel de la fonction require()), il faut exporter les fonctions du module = rendre public.
• On utilisera l’objet natif module.exports pour exporter des fonctions.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 367
module.exports.myModuleFunction = function() {
return "Hello World";
};
module.exports.mySecondModuleFunction = function() {
return "Foo Bar";
};
foo.js
|
Node.js – Création d’un module
• Au final, le code suivant…
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 368
var foo = {
myModuleFunction: function() {
console.log("Hello World");
},
mySecondModuleFunction: function() {
console.log("Foo Bar");
}
}
var foo = require('./foo');
• …est équivalent à :
|
Node.js – Création d’un module
• La fonction CommonJS require() retourne un objet qui reference la valeur de module.exports
pour un fichier donné.
• On peut maintenant accéder aux fonctions publics de foo.js via les propriétés rendues accessibles
par la variable locale foo dans main.js.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 369
var foo = require('./foo');
foo.myModuleFunction(); // Affichera « Hello World »
foo.mySecondModuleFunction(); // Affichera « Foo Bar »
main.js
|
Node.js – Création d’un module
• Remarque : si votre module exporte une seule function, vous pouvez directement assigner une
function anonyme à l’objet module.exports.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 370
module.exports = function() {
return "Single module function";
};
foo.js
|
Node.js – Création d’un module
• On va refactoriser l’exercice précédent (qui consistait à lister les fichiers d’un répertoire) en créant
un module.
• Le module devra exporter une seule fonction qui prendra 3 arguments :
• Le chemin du répertoire
• L’extension sur laquelle filtrer
• Une fonction de callback, utilisant la convention de nommage de Node.js : (err, data) :
• err est égale à null s’il n’y a aucune erreur, ou retourne les erreurs de fs.readdir().
• data est un tableau contenant les fichiers filtrés
• Aucun console.log() doit être initié par notre module.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 371
Exercice d’application :
|
Node.js – Création d’un module
• Dans le fichier du module, par exemple module.js, on assignera d’abord une fonction à l’objet
module.exports (pour la rendre disponible).
• Charger le module dans le fichier main.js avec l’instruction require() de CommonJS.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 372
Exercice d’application :
|
Node.js – Création d’un module
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 373
Exercice d’application :
var fs = require('fs');
var path = require('path');
module.exports = function(directory, ext, callback) {
if (err) {
return callback(err);
}
var ext = '.' + ext;
var filesFiltered = files.filter(function (file) {
return fs.statSync(file).isFile() && (path.extname(file) == ext);
});
callback(null, filesFiltered);
};
module.js
|
Node.js – Création d’un module
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 374
Exercice d’application :
var module = require('./module.js');
module(process.argv[2], process.argv[3], function(err, files) {
if (err) {
console.log("Error: " + err);
}
files.forEach(function (file) {
console.log("%s (%s)", file, path.extname(file));
});
});
main.js
|
Node.js
Utiliser les WebSockets avec
Socket.io
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 375
|
Node.js – Socket.io
• Socket.io est une bibliothèque JavaScript pour développer des
applications web en temps réel via l’utilisation des WebSocket.
• Permet la communication temps réel et bidirectionnelle entre un ou
plusieurs clients web et un serveur.
• Socket.io fonctionne en deux parties (avec des API similaires) :
• Une bibliothèque côté client qui s’exécute sur le navigateur
• Une bibliothèque côté serveur pour Node.js
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 376
Présentation
|
Node.js – Socket.io
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 377
Présentation
|
Node.js – Socket.io
• Socket.io est principalement utilisé pour des systèmes de communication en temps réel :
messagerie instantanée, édition collaborative de document (comme Google Docs), streaming de
données binaires (image / vidéo / audio).
• Tout comme AJAX, le protocole WebSocket était géré différemment en fonction du navigateur
utilisé. Socket.io corrige ce problème en apportant un support des différents navigateurs.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 378
Présentation
|
Node.js – Socket.io
• Le web a été construit dans l’idée que : le client requête, le serveur répond.
• Ce modèle est aujourd’hui dépassé : il ne correspond plus à l’usage que l’on se fait du web.
• AJAX : premier pas vers la communication temps réel. Mais AJAX n’est pas en temps réel car il faut
interroger le serveur régulièrement (pooling) pour récupérer des éventuelles modifications. Cette
interrogation se fait via des requêtes AJAX émises chaque X secondes.
• Problème en cas de forte affluence  surcharge du serveur.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 379
Présentation
|
Node.js – Socket.io
• Pour palier à ce problème, une évolution de Ajax à vue le jour sous le terme « Ajax Long Pooling ».
• Si le serveur ne retourne aucune donnée, la connexion du client est laissée ouverte.
• Si aucune réponse après un certain temps (timeout), la connexion sera fermée.
• Si une réponse est retournée par le serveur, la connexion est également fermée.
• Ce modèle n’est toujours pas idéal… ce qui a poussé à l’implémentation des WebSocket.
• Attention : ne pas confondre avec WebRTC (technologie permettant les communications directes entre
navigateurs, sans passer par un serveur – utilisé en VOIP par exemple).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 380
Présentation
|
Node.js – Socket.io
• Standard désignant un protocole réseau permettant de créer des canaux de communication full-
duplex par-dessus une connexion TCP (pour les navigateurs et serveurs web).
• Full-duplex ? Si l’information peut être transporté simultanément dans les 2 sens. Un canal de
communication bidirectionnel n’est pas forcément full-duplex : il peut être half-duplex.
• Ce canal permet de :
• notifier le client d’un changement d’état du serveur,
• d’envoyer des données (push) du serveur vers les clients connectés sans que ces derniers
aient à effectuer la moindre requête.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 381
WebSocket
|
Node.js – Socket.io
• Socket.io est un module CommonJS. Il est disponible sur le catalogue d’application npm.
• Pour installer Socket.io sur Node.js puis le charger :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 382
Installation côté serveur / client
npm install socket.io
• Pour charger Socket.io côté client (une page web par exemple) :
<script src="socket.io.js"></script>
|
Node.js – Socket.io
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 383
Utilisation côté serveur
var http = require('http').createServer(handler)
var io = require('socket.io')(http);
http.listen(8080);
function handler (req, res) { ... }
• On créé ensuite un serveur web avec Node.js et on l’attache à une instance de Socket.io (sans
oublier de définir des callback pour traiter les évènements).
|
Node.js – Socket.io
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 384
Utilisation côté serveur
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
• La dernière étape consiste à utiliser l’évènement « connection » de Socket.io qui est lancée
lorsque le serveur à pu initier une connexion avec un client.
• Dans ce cas là on envoi une donnée via la fonction emit(). Dans cet exemple on écoute également
sur l’évènement « my other event » envoyé par le client.
|
Node.js – Socket.io
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 385
Utilisation côté client
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
• Ensuite il faut indiquer à notre client (une page web par exemple), qu’il va devoir communiquer
avec le serveur Socket.io.
|
Node.js – Socket.io
• Pour interagir avec un serveur Socket.io, il n’est pas forcément nécessaire d’avoir un client sous la
forme d’un navigateur web. On peut utiliser un script Node.js qui jouera le rôle du client…
• Cela ouvre à de nombreuses possibilités !
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 386
Remarque
|
Node.js – Socket.io
• On suivra le guide « Get started : Chat Application » sur http://socket.io/get-started/chat/ pour
créer notre première application temps réel utilisant les WebSocket. Il s’agit d’une application
basique de type « chat ».
• Quand vous aurez terminé, améliorer l’application de base en :
• Donnant la possibilité aux clients de spécifier un nom d’utilisateur.
• Afficher l’indicateur « <user> écrit » lorsqu’un utilisateur compose un message.
• Afficher les personnes en ligne (par exemple dans un sidebar à gauche).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 387
Exercice d’application : création d’un chat temps réel
Partie 5
Express
Node.js web application framework
|
Express – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 389
|
Express – Présentation
• Express est un serveur web pour Node.js. Il étend les fonctionnalités de base du serveur web de
Node.js (module « http » que nous avons vu dans le chapitre précédent).
• Express doit être vu comme un framework dans le sens où il apporte diverses fonctionnalités :
• Serveur web HTTP
• Module de routage (en fonction de l’URI, exécution d’une action précise) : dans le même
principe que les routeurs des framework web modernes : exemples du routeur de Symfony2 ou
Laravel).
• Middleware (fonctions appelées après routage)
• Gestion des erreurs
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 390
|
Express – Installation
• Express est un module CommonJS. Vous pouvez l’installer en passant par le gestionnaire de
paquets npm en exécutant la commande suivante :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 391
npm install express --save
|
Express – Hello World
• Créer un nouveau répertoire pour cette application de test. Bonne pratique : lancer la commande
npm init pour générer un fichier package.json contenant les métadonnées propres à votre
application.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 392
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
• Ajouter Express en dépendance de
votre application (voir slide
précédente).
• Créer un fichier app.js avec le code
ci-contre. Pour lancer votre
application, exécuter la commande
node app.js.
|
Express – Hello World
• On peut noter quelques ressemblances avec l’utilisation native de module http de Node.js.
• Les deux syntaxes suivantes sont identiques :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 393
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000)
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
http.createServer(app).listen(3000);
• Remarque : app n’est en fait qu’une fonction spéciale de Express.
|
Express – Hello World
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 394
|
Express – Générateur d’application
• En complément d’Express, il peut être intéressant d’installer le
générateurs d’applications Express. Cet outil permet de créer
rapidement un squelette d’application.
• Installation :
• La structure d’application créée par le générateur est l’une des
nombreuses manières possibles de structurer les applications Express.
• Vous avez toute latitude pour l’utiliser ou la modifier en fonction de
vos besoins.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 395
.
├── app.js
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── users.js
└── views
├── error.jade
├── index.jade
└── layout.jade
npm install express-generator -g
|
Express – Générateur d’application
• Nous avons installé le générateur avec le flag –g ce qui rend le générateur accessible depuis
n’importe quel répertoire. Il a été installé globalement et non dans le répertoire
« nodes_modules » de l’application.
• La commande suivante va créer une application Express nommée myapp dans le répertoire de
travail en cour :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 396
express myapp
cd myapp
npm install
npm start // Va lancer la commande spécifiée dans la propriété scripts.start du package.json
|
Express – Routage
• Dans des frameworks web moderne comme Symfony ou Laravel (pour ne citer que eux) un
composant appelé « routeur » existe. C’est le point d’entrée de votre application : toutes les
requêtes HTTP initiées par les utilisateurs passeront par le routeur.
• L’idée est de définir les routes de notre applications, c’est-à-dire les URI (partie après l’URL de
base) possibles.
• Le routeur va comparer l’URI de la requête cliente avec celles définies par l’application. Si il y a une
correspondance, les actions définies dans la route est exécutée. Le routage n'est effectué qu'une
seule fois par requête.
• Le routeur d’Express fonctionne sur le même principe.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 397
|
Express – Routage
• Dans des frameworks web moderne comme Symfony ou Laravel (pour ne citer que eux) un
composant appelé « routeur » existe. C’est le point d’entrée de votre application : toutes les
requêtes HTTP initiées par les utilisateurs passeront par le routeur.
• L’idée est de définir les routes de notre applications, c’est-à-dire les URI (partie après l’URL de
base) possibles.
• Le routeur va comparer l’URI de la requête cliente avec celles définies par l’application. Si il y a une
correspondance, les actions définies dans la route est exécutée. Le routage n'est effectué qu'une
seule fois par requête.
• Le routeur d’Express fonctionne sur le même principe.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 398
|
Express – Routage
• Le programme « Hello World » définie une seule route sur l’URI « / ». Toute requête HTTP de type
GET correspondant à cette route va lancer l’exécution de la fonction anonyme.
• Deux paramètres sont passés à la fonction de callback : req pour obtenir des informations sur la
requête initiée et res pour modifier la réponse.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 399
app.get('/', function (req, res) {
res.send('Hello World!');
});
• L’ordre de la définition des routes dans votre application et important.
|
Express – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 400
app.get('/', function (req, res) {
res.send('Requête GET sur la page d’accueil');
});
app.post('/', function (req, res) {
res.send('Requête POST sur la page d’accueil');
});
app.put('/user', function (req, res) {
res.send('Got a PUT request at /user');
});
app.delete('/user', function (req, res) {
res.send('Got a DELETE request at /user');
});
app.all('/foo', function(req, res) { ... });
|
Express – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 401
• Vous pouvez chainer plusieurs routes répondant à la même URI mais à une action HTTP
différente. C’est très utilise dans le cas d’une architecture RESTful.
app.route('/book')
.get(function(req, res) {
res.send('Get a random book');
})
.post(function(req, res) {
res.send('Add a book');
})
.put(function(req, res) {
res.send('Update the book');
});
|
Express – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 402
• Vous pouvez avoir des routes dynamiques. Quelques exemples :
app.get('/article/:id', function(req , res) {
res.render('article' + req.params.id);
});
app.get('/:name(article|article2|article3)?', function(req, res) {
var name = req.params.name;
res.render(name);
});
app.get('/:id', function(req, res) {
var id = req.params.id;
});
Accessible depuis /article, /article2,
/article3 ou / (grâce à l’opérateur ?).
|
Express – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 403
• Vous pouvez effectuer des tests basiques sur les paramètres de vos routes pour vous assurer que
le format est bien celui attendu. Par exemple le regex « d+ » permet de spécifier un nombre
entier.
• Cette possibilité n’est pas encore documentée. Le double slash permet d’échapper le premier.
app.get('/:foo(d+)', function(req, res){
// Get user info based on the user id (int).
}
app.get('/:bar(w+)', function(req, res){
// Get user info based on the user name (string).
}
|
Express – Middleware
• Les middleware sont des fonctions qui gèrent les requêtes. Elles se situent entre la requête brute
et la réponse finale (d’où le nom « middle ware » : entre deux).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 404
|
Express – Middleware
• Le serveur créé avec Express peut avoir une pile de fonctions middleware. Quand une requête
arrive, elle est déléguée à la première fonction middleware de la pile.
• Les fonctions middleware sont toujours invoquées dans l’ordre où elles sont ajoutés.
• Chaque fonction middleware peut accéder aux objets request et response, ainsi qu’à la fonction
middleware suivante dans la pile.
• Chaque fonction middleware peut décider de « répondre » en appelant des méthodes sur l’objet
response, et / ou en passant la requête à la fonction middleware suivante dans la pile en appelant
la fonction next().
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 405
|
Express – Middleware
• De manière schématisée, une fonction middleware ressemble à ça :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 406
function myFunMiddleware(request, response, next) {
// Do stuff with the request and response.
// When we're all done, call next() to defer to the next middleware.
next();
}
• Si une fonction middleware ne termine pas le cycle requête / réponse, elle doit obligatoirement
appeler next() pour passer le contrôle à la fonction middleware suivante.
|
Express – Middleware
• L’application Express suivante va répondre à deux
routes définies : « / » et « /help ».
• Supposons maintenant que nous voulons avoir un
log à chaque fois qu’une requête sur l’une de ces
deux routes est faite.
• Une première approche serait d’ajouter dans
chaque route le code permettant de loguer la
requête (console.log par exemple).
• Ce n’est pas l’idéal : duplication de code.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 407
var app = express();
app.get('/', function(req, res) {
res.send('Hello World!');
});
app.get('/help', function(req, res) {
res.send('Nope.. nothing to see here');
});
|
Express – Middleware
• Au lieu de ça on va utiliser un middleware :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 408
var app = express();
app.use(function(req, res, next) {
console.log('%s %s', req.method, req.url);
next();
});
app.get('/', function(req, res, next) {
res.send('Hello World!');
});
app.get('/help', function(req, res, next) {
res.send('Nope.. nothing to see here');
});
|
Express – Middleware
• Les fonctions middleware peuvent réaliser les tâches suivantes :
• exécuter n’importe quel code,
• modifier les objets requête / réponse (decorator),
• terminer le cycle requête / réponse,
• appeler la prochaine fonction middleware de l’application avec next().
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 409
|
Express – Middleware
• Une application Express peut utiliser les types suivants de middleware :
• Application-level middleware
• Router-level middleware
• Error-handling middleware
• Built-in middleware : 1 seule pour l’instant, static() permettant de servir des fichiers statiques
• Third-party middleware : cookie parse, Passport, etc.
• Nous n’allons pas voir dans cette présentation le détail de chaque type de Middleware. Si besoin,
la documentation officiel donne des exemples précis : http://expressjs.com/en/guide/using-
middleware.html
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 410
|
Express – Middleware
• Exemple de Middleware permettant de gérer les sessions avec Express :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 411
var express = require('express');
var redis = require("redis");
var session = require('express-session');
var redisStore = require('connect-redis')(session);
var client = redis.createClient();
var app = express();
app.use(session({
secret: '...',
store: new redisStore({ host: 'localhost', port: 6379, client: client }),
saveUninitialized: false,
resave: false
}));
Le module « connect-mongo »
fonctionne sur le même principe
mais avec MongoDB
|
Express – Moteur de template
• Express n’est pas un moteur de template, mais il peut faire appel à un moteur de template externe
(un autre module qu’on installera via npm) pour retourner des pages HTML.
• Passer par npm pour utiliser le moteur de template de votre choix.
• Nous allons installer jade via la commande :
• Pour indiquer à Express qu’on utilise ce moteur de rendu, et que les templates sont stockés dans
le répertoire views on doit passer par des instructions set.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 412
npm install jade --save
app.set('view engine', 'jade');
app.set('views', './views')
|
Express – Moteur de template
• Création d’un template Jade (plus d’infos sur la syntaxe sur http://jade-lang.com/) :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 413
html
head
title!= title
body
h1!= message
• Puis, créez une route pour générer le fichier index.jade. Si la propriété view engine n’est pas
définie, vous devez spécifier l’extension du fichier view. Sinon, vous pouvez l’omettre.
app.get('/', function (req, res) {
res.render('index', { title: 'Hey', message: 'Hello there!'});
});
|
Express – Exercices
• Utiliser le générateur pour créer un squelette d’application.
• Nous n’avons pas encore vu comment ajouter une couche de persistance à nos applications. Créer
un tableau JavaScript ayant plusieurs objets correspondant chacun à des articles de blog.
Propriétés : title, content, author, created_at.
• Votre application devra comporter les pages suivantes :
• Page d’accueil qui listes les articles par ordre chronologique (si vous avez le temps,
implémenter une pagination).
• Détail d’un article
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 414
Partie 6
MongoDB
The next-generation database that lets you
create applications never before possible…
|
MongoDB – Présentation
• Nous avons maintenant une plateforme en place (Node.js), ainsi qu’un serveur web (Express).
L’architecture MEAN vue dans la partie 3 prend forme. Cependant, sans moyen de persistance des
données, les applications que nous pouvons développer seront vite limités en fonctionnalités.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 416
• MongoDB est une système de gestion de base de données open source de
type NoSQL.
• Il a été créé en 2009 et est depuis largement utilisé du fait de sa simplicité.
• Il est écrit principalement en JavaScript. L’utilisation de JavaScript et de
JSON pour la représentation des données stockées, fait que MongoDB est
un acteur de choix dans MEAN.
|
MongoDB – Bases de données relationnelles
• Quand on parle de base de donnée, on pense immédiatement
au langage SQL permettant de rechercher, d'ajouter, de
modifier, de supprimer ou de faire des jointures sur des
données dans les bases de données relationnelles.
• Une base de donnée est dite relationnelle quand elle applique
le modèle relationnel introduit par Edgard Codd au début des
années 70, et depuis largement utilisé.
• Dans ce type de base de données, l'information est organisée
dans des tableaux à deux dimensions : ce qu’on appel des
tables.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 417
|
MongoDB – Bases de données relationnelles
• Les données organisées dans les tables s’appellent des enregistrements.
• Les noms des colonnes sont appelées des attributs.
• On parle aussi de relation pour désigner les tables.
• Les opérations d'algèbre relationnelle telles que l'intersection, la jointure ou le produit cartésien
sont utilisées pour faire des rapprochements entre les enregistrements et créer de nouvelles
relations à partir des relations enregistrées dans la base de données.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 418
|
MongoDB – Bases de données relationnelles
• Pour faciliter l’exploitation des données depuis une application, on peut présenter le contenu
d'une base de données relationnelle sous forme d'objets. Cela passe par l’utilisation d’un ORM
(Object Relational Mapping).
• Un ORM donne simplement l'illusion de travailler avec une base de données orientée objet.
Généralement une classe (un « Modèle ») représente une table en base de données. Par exemple
on instancie cette classe pour créer un nouvel enregistrement.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 419
// Création d’un user avec Eloquent (Laravel)
$user = new User;
$user->name = 'John';
$user->age = 30;
$user->save();
// Requêtage et mise à jour d’un vol
Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]);
|
MongoDB – Bases de données relationnelles
• Un ORM est donc une couche d’abstraction : le langage SQL n’est plus manipulé de manière
directe, et la manipulation des modèles est beaucoup plus aisé.
• Mais par fois il est difficile pour un ORM de faire cette connexion entre un système basé sur les
objets et un système relationnel.
• Héritage : c’est la façon dont on définit des relations dans un langage orienté objet. Mais
comment représenter ces relations dans une base de données relationnelle ?
• Vous ne pouvez pas avoir des tables qui héritent d’autres tables.
• Donc au final les ORM doivent forcément faire des compromis…
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 420
|
MongoDB – Bases de données relationnelles
• Dans une base de données relationnelle, il y a plusieurs façon de simuler ce
lien d’héritage :
Soit l’héritage ci-contre :
• Première méthode : ajouter des champs propres aux employés et
managers dans une table personne. Et en fonction de la ressource,
alimenter ou non ces champs.
• Seconde méthode : avoir plusieurs tables Person, Employee, Manager
avec des relations 1-1. Mais par contre ont doit au final gérer des
jointures de tout les côtés.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 421
|
MongoDB – Bases de données relationnelles
• Donc bien qu’a première vue les ORM semblent être simple, ils essayent de connecter
ensemble des systèmes qui sont fondamentalement différents.
• Dans ce cas là, si les bases de données relationnelle ne sont pas adaptés aux langages de
programmation orientés objet, ne devrait t’on pas opter pour une autre solution, un autre
système de représentation des données ?
• Modèle relationnel  Marteau de Maslow ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 422
« Si le seul outil que vous avez est un marteau, vous
tendez à voir tout problème comme un clou ».
Abraham Maslow
|
MongoDB – Vous avez dit NoSQL ?
• Le terme « NoSQL » désigne un type de base de données qui n’utilise pas le modèle
relationnel.
• Généralement le langage SQL n’est pas utilisé pour requête ces bases de données. Le terme
NoSQL est trompeur car il signifie « Not Only SQL » (pas seulement SQL). On aurait plutôt du
l’appeler « Not Only Relational Databases ».
• NoSQL est une mouvance, et non une technologie spécifique ou un produit. Il y a plus de 230
SGBD NoSQL recensés en février 2016 (cf nosql-database.org).
• Des acteurs comme Google, Linkedin, Amazon ou Facebook conçoivent et exploitent des bases de
données de type NoSQL.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 423
|
MongoDB – Vous avez dit NoSQL ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 424
Quelques systèmes de gestion de base de données NoSQL
|
MongoDB – Vous avez dit NoSQL ?
• Vous ne pouvez pas ajouter un enregistrement qui ne correspond pas au schéma.
• Vous devez spécifier la valeur NULL pour les champs non renseignés d’un enregistrement.
• On doit prendre en compte le type de données : vous ne pouvez pas ajouter une chaine de
caractère dans un champ entier.
• Vous ne pouvez pas ajouter des enregistrement dans un champ : vous devez créer une autre table
et utiliser une pair de clé étrangère / clé primaire pour lier ces deux tables, et enfin faire une
jointure pour récupérer les données complètes.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 425
Dans une base de données relationnelle :
|
MongoDB – Vous avez dit NoSQL ?
• Il n’y a pas de notion de schéma : au sein d’une même « table », les « enregistrements » peuvent
avoir une structure totalement différente. Les champs peuvent être ajoutés, modifiés, supprimés
d’un enregistrement à l’autre et ce à n’importe quel moment !
• Il n’y a pas de champs inutilisés.
• Il n’y a pas de type de données (ils sont implicites).
• La plupart des traitements sont fait dans la couche application.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 426
Dans une base de données non relationnelle (= NoSQL) :
|
MongoDB – Vous avez dit NoSQL ?
• Parfait pour les bases de données larges et distribuées.
• On a par fois besoin de stocker des données qui ne sont pas structurées (à la différence de
données insérées dans un table qui doivent correspondre à un schéma bien précis : les différents
champs de la table) ou dont le nombre / type de champs peut varier d’un enregistrement à
l’autre.
• Logs, données scientifiques, pages web, (Champ 1, Champ 2, Champ 3… Champ n), etc.
• Facilité de mise en place et de développement.
• Scalabilité horizontale aisée (= ajout de serveur).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 427
Pourquoi utiliser NoSQL ?
|
MongoDB – Vous avez dit NoSQL ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 428
Pourquoi utiliser NoSQL ?
|
MongoDB – Vous avez dit NoSQL ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 429
Pourquoi utiliser NoSQL ?
|
MongoDB – Vous avez dit NoSQL ?
• NoSQL supprime toute la complexité des requêtes SQL.
• NoSQL fonctionne très bien en cluster.
• NoSQL peut gérer une nombre très important de données (ce qu’on appel le Big Data).
• Les SGBD NoSQL sont en grande partie open source.
• Dans le grande majorité des bases de données NoSQL, aucune gestion des transaction n’est
prévue. Elles doivent être gérées au niveau de la couche applicative.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 430
Particularités
|
MongoDB – Vous avez dit NoSQL ?
• Donc totalement différent du modèle ACID appliqué par les SGBDR :
• Atomicity / atomicité : assure qu'une transaction se fait au complet ou pas du tout. si une
partie d'une transaction ne peut être faite, il faut effacer toute trace de la transaction et
remettre les données dans l'état où elles étaient avant la transaction.
• Consistency / cohérence : assure que chaque transaction amènera le système d'un état
valide à un autre état valide ( par exemple vérification sur les contraintes d’intégrité).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 431
Particularités
|
MongoDB – Vous avez dit NoSQL ?
• Donc totalement différent du modèle ACID appliqué par les SGBDR :
• Isolation / isolation : toute transaction doit s'exécuter comme si elle était la seule sur le
système. Aucune dépendance possible entre les transactions.
• Durability / durabilité : assure que lorsqu'une transaction a été confirmée, elle demeure
enregistrée même à la suite d'une panne d'électricité ou d’un autre problème.
 ACID est pessimiste, alors que NoSQL est optimiste !
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 432
Particularités
|
MongoDB – Vous avez dit NoSQL ?
• Il existe plusieurs types de base de données NoSQL. On peut les classifier par la manière dont ils
traitent les données. Chacune de ces solutions à ses propres forces et faiblesses.
• Key-Value (ce que fait Redis par exemple)
• Document-oriented (utilisé par MongoDB)
• Column-oriented
• Graph
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 433
Types de base de données NoSQL
|
MongoDB – Orienté document
• Les données sont modélisées dans des objets
JavaScript appelés documents.
• Les documents stockés par MongoDB sont de
type BSON. Les objets BSON sont la
représentation binaire des objets JSON en leur
ajoutant des améliorations et des capacités
supplémentaires (expressions régulières, gestion
des dates, etc.).
• Chaque document possède un identifiant unique
généré par MongoDB : la propriété « _id ».
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 434
// Exemple de document dans MongoDB
{
first_name: "Paul",
surname: "Miller",
city: "London",
location: [45.123,47.232],
cars: [
{ model: "Bentley",
year: 1973,
value: 100000, ….},
{ model: "Rolls Royce",
year: 1965,
value: 330000, ….},
]
}
|
MongoDB – Orienté document
• Les documents sont stockés dans des collections (qu’on pourrait rapprocher aux tables).
• Il faut voir une collection comme un amas de documents pas forcément uniformes. Car un
document n’est jamais figé : les couples clé / valeur peuvent changer en fonction des données.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 435
Document
|
MongoDB – Orienté document
• Les documents sont stockés dans des collections (qu’on pourrait rapprocher aux tables). Il faut
voir une collection comme un amas de documents pas forcément uniformes.
• Ainsi, une base de données sous MongoDB contient donc des collections de documents.
• Un SGBD MondoDB est composé d’une ou plusieurs base de données.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 436
|
MongoDB – Orienté document
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 437
SGBDR
• Les bases de données ont des tables.
• Les tables ont des colonnes.
• Les lignes ont de cellules.
• Les champs contiennent des types de
données simples.
• Les schémas sont rigides.
MongoDB
• Les bases de données ont des collections.
• Les collections ont des documents.
• Les documents ont des champs.
• Les champs contiennent : des types de
données simples, des arrays ou d’autre
documents.
• Les schémas sont fluides.
|
MongoDB – Requêtage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 438
Création d’une collection
CREATE TABLE users (
name VARCHAR(128),
age NUMBER
)
db.createCollection(“users”)
|
MongoDB – Requêtage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 439
Insertion
INSERT INTO table (f1, f2, f3)
VALUES (v1, v2, v3)
db.collection.insert(
{f1: v1, f2: v2, f3: v3}
)
db.comments.insert({
'discussion_id': discussion_id,
'slug': slug,
'posted': datetime.utcnow(),
'author': author_info,
'text': comment_text
})
|
MongoDB – Requêtage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 440
Modification
UPDATE table
SET f1 = v1, f2 = v2
WHERE f3 = v3
db.collection.update(
{f3: v3},
{$set:
{f1: v1, f2: v2}
}
)
|
MongoDB – Requêtage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 441
Sélection
SELECT f1, f2
FROM table
WHERE f3 = 'foo'
db.collection.find(
{f3: 'foo'},
{f1: 1, f2: 1}
)
db.users.find()
db.invoices.find({id: 12})
db.customers.find({name:'John'})
|
MongoDB – Requêtage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 442
Commandes diverses
show dbs // Voir les bases de données disponibles
use foo // Choisir une base de données (ici switcher sur “foo”)
db // Vérifier qu’elle est la base de données en cours
show collections // Lister les collections de la base de données
// Insérer des données
foo = {"lastName": "Doe", "firstName": John, "dateBirth": 1970-06-24}
db.test.insert(foo)
db.test.find() // Récupérer les documents d’une collection
|
MongoDB – Requêtage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 443
Commandes diverses
// Utiliser du JavaScript dans Mongo
for (var i=0; i < 5; i++) db.test.insert({a:42, b:i})
// Vérifier l’ajout des documents
db.test.find()
// Retournera...
{"_id": ObjectId("554a990f0ebf783b64a56776"), "a": 42, "b": 0}
{"_id": ObjectId("554a990f0ebf783b64a567ce"), "a": 42, "b": 1}
{"_id": ObjectId("554a990f0ebf783b64a567cf"), "a": 42, "b": 2}
{"_id": ObjectId("554a990f0ebf783b64a567d0"), "a": 42, "b": 3}
{"_id": ObjectId("554a990f0ebf783b64a567d2"), "a": 42, "b": 4}
|
MongoDB – Requêtage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 444
Commandes diverses
db.test.find({ b: {$gt: 2}}).sort({b: -1})
// Retournera...
{"_id": ObjectId("554a990f0ebf783b64a567d2"), "a": 42, "b": 4}
{"_id": ObjectId("554a990f0ebf783b64a567d0"), "a": 42, "b": 3}
|
MongoDB – Installation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 445
|
MongoDB – Installation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 446
• Télécharger MongoDB sur mongodb.com et
installer l’archive sur votre poste. Sous Windows,
le répertoire d’installer par défaut est dans
Program FilesMongoDBServer.
• MongoDB nécessite un répertoire pour stocker
toutes les données. Créons ce répertoire en invite
de commandes, en tapant la commande : md
datadb
|
MongoDB – Installation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 447
• Pour lancer MongoDB, exécutez le
fichier mongod.exe depuis votre
terminal.
• Ceci lance le processus de la base
de données MongoDB. Le message
« waiting for connections » sur
l'invite de commandes indique que
le processus mongod.exe a bien
été exécuté.
|
MongoDB – Installation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 448
• Pour se connecter à l’instance de MongoDB
il faut utiliser le Shell Mongo.
• Exécutez le fichier mongo.exe depuis une
autre fenêtre de terminal (pour ne pas tuer
l’instance mongod).
• Après le lancement de mongo, votre session
va utiliser par défaut la base de données «
test ».
• Taper use <database> pour changer de
base de données.
|
MongoDB
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 449
Exercice d’application
• Installer MongoDB sur votre poste.
• Lancer mongod.
• Connectez-vous en utilisant mongo.
• Créer une base de données, une collection et quelques documents.
• Tester les requête de modification, suppression, sélection, etc.
Partie 7
Angular
Concepts fondamentaux d’Angular 2
|
Angular – Présentation
• Sur la partie serveur, Node.js a de plus en plus clairement remporté la bataille. Côté client c’est le
framework JavaScript AngularJS qui est devenu une référence (47K étoiles sur GitHub !).
• AngularJS est un framework JavaScript côté client open-source développé par Google en 2009.
• Framework MVC (Modèle Vue Contrôleur) et / ou MVVM (Modèle Vue – Vue Modèle).
• Concepts clés :
• Particulièrement adapté pour du Single Page Application (SPA)
• Il étend le langage HTML par des directives HTML
• Data Binding bidirectionnel
• Injection de dépendances
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 451
|
Angular – Présentation
• Première version nommée « AngularJS »
• Actuellement en version 1.5.0 (février 2016)
• Utilisé massivement en production, mais
concurrencé par l’arrivée de Angular 2.
• Développement verbeux et quelques
concepts difficile à assimiler.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 452
On distingue deux versions du framework Angular :
• Deuxième version nommée « Angular »
• Actuellement en version beta. Pas de roadmap.
• Rupture totale avec la version 1 : on peut
presque le considérer comme un autre
framework.
• Plus simple, plus rapide.
|
Angular – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 453
|
Angular – Présentation
• Angular 2 est encore en cours de développement. Cependant, il est possible de développer dés
maintenant des applications. Le core va être amené à évoluer, mais globalement les bases sont
posées. Ne pas utiliser en production !
• Vous serez sur le marché de l’emploi d’ici 1 à 2 ans… ils est plus judicieux de découvrir Angular 2.
• Pourquoi Google a retiré la mention « JS » dans « Angular 2 » ? Google pousse l’utilisation du
langage TypeScript en remplacement de JavaScript. Cependant, il est toujours possible de
développer directement en JavaScript.
• On peut également utiliser le langage de programmation Dart (développé par Google).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 454
Angular 2
|
Angular – Présentation
• Se base sur les futurs standards du web :
• WebComponents : a voir comme des widgets réutilisables. Ils font partie intégrante des
navigateurs, et ne nécéssitent donc pas de librairie comme jQuery. Un Web Component
existant peut être utilisé sans écrire de code, simplement en ajout la déclaration d'un
import à une page HTML. Possibilité d’utiliser nos propres balises dans un code HTML.
• ES6 / ES7 (en draft) / TypeScript
• Réponce face au frameworks concurrents comme Ember.js et React (Facebook).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 455
Angular 2
|
Angular – Présentation
• Langage de programmation open-source développé en 2012 par Microsoft, comme un sur-
ensemble de JavaScript (tout code JavaScript peut être utilisé dans TypeScript).
• Développé dans le but d’améliorer le code JavaScript (face aux manquements d’ECMAScript 5) :
typage, interfaces, classes, modules, mixin, etc.
• Le code TypeScript est transcompilé / transpiler vers JavaScript.
• TypeScript supporte la spécification ECMAScript 6. Son intérêt est limité depuis l’arrivée
d’ECMAScript 6.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 456
TypeScript (rappel)
|
Angular – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 457
TypeScript (rappel)
class Greeter {
constructor(public greeting: string) { }
greet() {
return "<h1>" + this.greeting + "</h1>";
}
};
var greeter = new Greeter("Hello, world!");
document.body.innerHTML = greeter.greet();
• Exemple de code TypeScript (Hello World) :
Comparaison de TypeScript VS JavaScript sur typescriptlang.org/Playground
|
Angular – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 458
TypeScript (rappel)
npm install -g typescript
• Comme TypeScript n’est pas un langage de programmation directement intégré dans nos
navigateurs, nous devons l’installer. Le plus simple et de passer par npm :
|
Angular – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 459
Prise en main du framework
• Aller sur https://angular.io/docs/ts/latest/quickstart.html
et suivez les différentes étapes.
• Comme Google conseille d’utiliser TypeScript, et que la
grande majorité des tutoriaux ainsi que la
documentation officiel se basent sur ce langage,
sélectionner bien « Angular 2 for TypeScript » dans le
menu déroulant.
Partie 8
MEAN.JS
Full-Stack JavaScript Using MongoDB,
Express, AngularJS, and Node.js
|
MEAN.JS – Présentation
• MEAN.JS est un framework JavaScript fullstack qui permet de
faire communiquer les différentes couches de l’architecture MEAN.
• Cela peut demander un peu de configuration. MEAN.JS permet de
se concentrer sur la partie métier de votre application, plutôt que
de faire du code boileplate.
• Un bon framework n’avance pas la ligne d’arrivée, il avance la ligne
de départ. Il faut choisir un framework qui inclus de la génération
de code, des scripts, des tests, déploiement… c’est le cas de
MEAN.JS.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 461
|
MEAN.JS – Présentation
• MEAN.JS ne doit pas être confondu avec MEAN.io.
• Les deux frameworks sont quasiment identiques puisque MEAN.JS est un fork de MEAN.IO. La
même personne est à l’origine de ces framework. Cette personne c’est désolidarisé de MEAN.io
après des points de divergence interne.
• Quelques différences dans les outils utilisés :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 462
MEAN.JS MEAN.IO
Système de build : Grunt
Scaffolding : Yeoman Generators
Système de build : Gulp
Scaffolding : custom CLI nommé « mean »
|
MEAN.JS – Présentation
• Un système solaire composé de 4 planètes (MongoDB, Express, AngularJS et NodeJS), et de satellites :
• Yo : générateur
• Grunt : build script (automatisation de tâches : minification, compilation, etc.)
• Bower : gestionnaire de dépendance
• Bootstrap : mobile support (responsive web design)
• KarmaJS : pour écrire et lancer des tests unitaires
• Passport : gestion de l’authentification sur des services externes
• Tout ces outils / helpers sont là pour rendre le développement d’une application MEAN le plus facile
possible
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 463
|
MEAN.JS – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 464
Remarque importante :
AngularJS (version 1) est
utilisée. Les développeurs ont
prévu de migrer vers la version
2 lorsqu’elle sera finalisée.
|
MEAN.JS – Utilisation
• En cours de rédaction…
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 465
Partie 9
Meteor
Complete platform for building web and
mobile apps in pure JavaScript.
|
METEOR – Présentation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 467
|
METEOR – Présentation
• Meteor est un framework open-source de développement web en
JavaScript basé sur Node.js.
• Il s’inspire fortement de l’architecture / de la philosophie MEAN.
• Il s’inscrit comme un framework « nouvelle génération » car il bouscule les
codes : une application peut être développée simplement et rapidement
avec Meteor.
• Des mécanismes complexes comme la persistance client / serveur et le
temps réel sont implémentés de manière native et transparente. Meteor
apporte une couche d’abstraction à de nombreux problèmes et pièges
qu’on pourrait rencontrer en temps normal.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 468
Première version :
décembre 2011.
Dernière version
1.2.1 (octobre 2015)
|
METEOR – Présentation
• Le partage de code entre l’environnement client et serveur est possible avec Meteor.
• Meteor repose sur Node.js. C’est ce qui permet de faire le lien entre la base de données de votre
application et son interface utilisateur, tout en assurant que les deux restent bien synchronisés.
• Les données de la base de données côté serveur peuvent être répliquées en tout ou partie sur les
clients. De manière générale, les client ne manipulent jamais directement les données du serveur.
Les modifications (ajout, modification, suppression) côté client sont synchronisées avec le serveur.
• Cela permet une grande flexibilité.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 469
|
METEOR – Présentation
• On peut alors effectuer des requêtes même en étant déconnecté du serveur. Lorsque le client sera
de nouveau connecté au serveur les éventuelles modifications sur les données seront envoyées
vers le serveur.
• Programmation réactive côté client (Latency Compensation) : l’action est immédiate pour le
client, mais le traitement côté serveur peut être différé ou mis en arrière plan. Exemple : envoi
immédiat d’un message dans un chat via un bouton « Envoyer », alors que la transmission et la
vérification côté serveur se fait en arrière-plan.
• Votre application web Meteor peut être transformée en application mobile native iOS / Android
en seulement quelques lignes de commandes. Apache Cordova est utilisé.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 470
|
METEOR – Présentation
• Vous pouvez déployer votre application dans le cloud Meteor en 1 ligne de commande (sur le même
principe que Heroku que nous avons vue dans la partie Node.js).
• Optionnel : vous pouvez utiliser AngularJS ou React pour le partie client.
• Hot Code Reload : les modifications que vous faites dans le code sont reportées en direct sur votre
page (sans avoir à recharger votre page).
• Pour toutes ces raisons, grand intérêt pour ce framework JavaScript dans la communauté des
développeurs.
• Levée de fonds de 11,2 millions de dollars en 2012.
• De nombreux Meetup chaque année en France et dans le reste du monde.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 471
|
METEOR – Présentation
• Meteor dispose de son propre catalogue de packages
/ modules : Atmosphere.
• Il fonctionne sur le même principe que npm.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 472
|
METEOR – Présentation
• La documentation de Meteor permet de prendre
rapidement en main le framework.
• Elle est complète et comprend beaucoup
d’exemple de code.
• Vous pouvez la consulter via :
http://docs.meteor.com/
• Sur StackOverflow, le tag meteor est très actif :
http://stackoverflow.com/questions/tagged/met
eor
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 473
|
METEOR – Présentation
• Le guide de Meteor permet de
connaître les bonnes pratiques à
utiliser lorsque vous développerez
votre application.
• Ce guide vient en complément de
la documentation officielle.
• Vous pouvez le consulter via :
http://guide.meteor.com/
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 474
|
METEOR – Plateforme
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 475
Infographie par @nwientge pour Meteorjs.club
|
METEOR – Plateforme
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 476
|
METEOR – Installation
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 477
• Pour Windows : https://install.meteor.com/windows
• Pour Mac OS et Linux : exécuter la commande curl https://install.meteor.com/ | sh
• Au moment de l’installation, créer un compte développeur sur Meteor.
|
METEOR
• Les slides suivantes se basent en partie sur le
livre Discover Meteor.
• Une version en ligne, traduire par la
communauté, est disponible depuis
http://fr.discovermeteor.com.
• Je vous invite à lire attentivement ce livre
pour en apprendre d’avantage sur le
développement d’application Meteor.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 478
|
METEOR – Premiers pas
• On suppose que vous avez installé Meteor sur votre poste.
• Toute comme Node.js, Express ou MongoDB, Meteor fonctionne en ligne de commande. Une
variable d’environnement a été créé vous permettant d’utiliser la commande meteor directement
dans votre terminal.
• Pour lister toutes les actions disponibles, exécuter la commande suivante :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 479
meteor help
|
METEOR – Premiers pas
• Nous allons maintenant créer notre premier application. La commande create de Meteor permet
de créer une application basique (création du répertoire de projet, téléchargement des
dépendances et génération d’un squelette basique).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 480
meteor create microscope
• Exécuter la commande suivante pour lancer votre application :
cd microscope
meteor
|
METEOR – Premiers pas
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 481
|
METEOR – Premiers pas
• Meteor à son propre gestionnaire de paquets et dépendance qui fonctionne sur le même principe
que npm que nous avons vu dans les parties précédentes. Equivalent à la commande npm install
<packageName>, la commande suivante permet d’ajouter un paquet :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 482
Ajout d’un paquet
meteor add <packageName>
meteor add twbs:bootstrap
meteor add underscore
• Ajoutons les 2 paquets suivant (Bootstrap comme framework CSS et Underscore qui apporte des
fonctions utilitaires pour JavaScript.
|
METEOR – Premiers pas
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 483
Ajout d’un paquet
|
METEOR – Premiers pas
• La commande précédente à téléchargé le paquet et ses éventuelles dépendances.
• Dans le même principe que le fichier packages.json de npm, Meteor délègue la gestion des
paquets installés à deux fichiers : .meteor/packages et .meteor/versions.
• Vérifier que ces fichiers contiennent bien les paquets ajoutés.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 484
Ajout d’un paquet
Suppression d’un paquet
meteor remove <packageName>
|
METEOR – Premiers pas
• isopacks : paquets de Meteor pouvant fonctionner à la fois côté client et serveur
• Paquets tiers : isopacks développés par la communauté. Dans le même principe que la catalogue
npm ou que Packagist de Composer, la catalogue des paquets est géré par Atmosphere
(http://atmosphere.meteor.com/).
• Paquets locaux : dans le répertoire /packets
• Paquets npm : ne fonctionnent pas directement avec la plateforme Meteor mais peuvent être
utilisés par d’autres paquets en tant que dépendance.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 485
Types de paquet
|
METEOR – Premiers pas
• /client : exécuté que la par client
• /server : exécuté que par le serveur
• Tout le reste est exécuté à la fois par le client et le serveur.
• /public : ressource statiques (images, css)
• /lib : fichiers chargés par Meteor avant tous les autres
• Fichiers main.* : chargés par Meteor après les autres
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 486
Structure d’une application
Appelé par Meteor en fonction du
contexte (client / serveur)
|
METEOR – Premiers pas
• Meteor trouvera et inclura automatiquement les fichiers que vous ajoutez dans le répertoire
/client.
• Ce qui signifie que vous n'avez jamais besoin d'écrire manuellement des chemins d'inclusion
(include) pour les fichiers javascript ou CSS.
• Au final, Meteor compilera tout dans un seul fichier minifié.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 487
Inclusion automatique des fichiers
|
METEOR – Premiers pas
• Les feuilles de style CSS sont automatiquement chargées et comprimées à la volée par Meteor, de
sorte qu'elles doivent être placées dans le dossier /client, plutôt que /public comme le seraient les
autres ressources statiques.
• Même principe qu’avec Grunt (voir MEAN.JS).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 488
Feuilles de style
|
METEOR – Templates (Spacebars)
• Meteor utilise son propre moteur de template nommé Spacebars.
• https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md
• Meteor garde les templates et leur logique séparés, et ces templates ne font rien par eux-même.
• Un template est fichier HTML comprenant une balise ouvrante et fermante <template>
• On utilise l’attribut « name » de cette balise pour spécifier le nom du template.
• Donc le nom de fichier du template n’a pas d’incidence. Par convention, on nomme quand même
le fichier par le nom utilisée dans l’attribut name.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 489
Présentation
|
METEOR – Templates (Spacebars)
• Inclusion d’un template dans une page HTML :
• Création du fichier de template (notez l’utilisation de la balise <template>) :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 490
Présentation
<template name="postList">
<div class="posts page">
...
</div>
</template>
client/templates/posts/post_list.html
{{> postsList}}
|
METEOR – Templates (Spacebars)
• Itération sur une variable ici « posts » qui représente un tableau d’articles, puis appel du template
permettant d’afficher le détail d’un article.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 491
{{#each posts}}
{{> postItem}}
{{/each}}
client/templates/posts/posts_list.html
<template name="postItem">
<h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
</template>
client/templates/posts/posts_item.html
Appel d’une propriété de l’objet courant.
|
METEOR – Templates (Spacebars)
• Afin d'exister, un template a besoin de helpers.
• Dans l’exemple précédent, la variable « posts » est lié à un helper.
• Template = affichage + itération (aucune logique métier ou de framework)
• Helpers = assigne et prépare une variable à chaque variable  logique du template
• On parle de « helpers du template » dans la terminologie Meteor.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 492
Helpers de template
|
METEOR – Templates (Spacebars)
var postsData = [
{
title: 'Introducing Telescope',
url: 'http://sachagreif.com/introducing-telescope/'
},
{
title: 'Meteor',
url: 'http://meteor.com'
}
];
Template.postsList.helpers({
posts: postsData
});
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 493
client/templates/posts/posts_list.js
Ces données viendraient
normalement de la base de
données… mais c’est un premier pas.
|
METEOR – Templates (Spacebars)
• Tester l’application Microscope (celle du livre Discover Meteor) :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 494
// Cloner l’application depuis GitHub
git clone https://github.com/DiscoverMeteor/Microscope.git github_microscope
cd github_microscope
// Changer de branche (chapitre 3:2 = templates)
git checkout chapter3-2
// Lancer l’application
meteor
|
METEOR – Collections temps réel
• Les collections temps réel sont au cœur de Meteor.
• Quelque soit l’application Meteor développé, les collections sont des éléments centraux.
• A placer dans le répertoire « lib » pour quelles soient lancer en premier.
• Nous allons voir comment synchroniser automatiquement des données et intégrer des collections
dans les templates.
• Une collection (à comprendre dans le sens MongoDB du terme) est une structure de données qui
prend soin de conserver les données en base de données côté serveur et côté client. Une
synchronisation est ensuite faite, en temps réel, avec chaque navigateur connecté.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 495
|
METEOR – Collections temps réel
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 496
Posts = new Mongo.Collection('posts');
lib/collections/posts.js
• La collection Posts est disponible à la fois sur le client et sur le serveur (car dans /lib).
• Collection (dans le sens Meteor) : librairie standard pour manipuler la couche persistance
(MongoDB et local storage côté client).
• Sur le client la collection est une copie d'un sous-ensemble de la réelle et canonique collection.
La collection côté client est constamment mise à jour avec ce sous-ensemble, (la plupart du
temps) de manière transparente.
|
METEOR – Collections temps réel
• Agit comme une API dans votre base de donnée MongoDB.
• Permet d'écrire des commandes Mongo telles que Posts.insert() ou Posts.update().
• On peut manipuler directement des collections / documents depuis le shell MongoDB.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 497
Collections côté serveur
meteor mongo
> db.posts.insert({title: "A new post"});
> db.posts.find();
{ "_id": ObjectId(".."), "title" : "A new post"};
|
METEOR – Le shell meteor
• Appelé depuis le terminal avec
meteor shell
• Donne un accès direct au code
côté serveur de l’application.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 498
|
METEOR – Le shell mongo
• Appelé depuis le terminal avec
meteor mongo
• Donne l'accès direct à la base de
donnée de l'application.
• Similaire au shell Mongo vu
dans le chapitre précédent sur
MongoDB.
• Meteor inclue sa propre instance
de MongoDB (vous n’avez pas
besoin de l’installer).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 499
|
METEOR – Collections temps réel
• Quand vous déclarez Posts = new Mongo.Collection('posts'); sur le client, ce que vous êtes
en train de créer est un cache local dans le navigateur de la collection Mongo réelle.
• Collection côté client en tant que “cache”  contient le sous-ensemble des données, et offre un
accès rapide à ces données.
• Ces documents sont stockés dans la mémoire du navigateur, ce qui signifie qu'y accéder est tout
simplement instantané.
• L'implémentation de Mongo côté client s'appelle MiniMongo.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 500
Collections côté client
|
METEOR – Collections temps réel
• Comment la collection côté client synchronise ses données avec la collection côté serveur ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 501
Communication client / serveur
// Changer de branche (chapitre 4:1 = collections)
git checkout chapter4-1
meteor
• Ouvrer deux fenêtre de votre navigateur, et accéder à la console JavaScript dans l’un des deux. Ouvrez
aussi le shell Mongo (voir slide précédente).
• Dans le shell Mongo, exécuter :
db.posts.find();
|
METEOR – Collections temps réel
• Dans le console du premier navigateur :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 502
Communication client / serveur
Posts.findOne();
• Créer un nouveau article. Dans l'une des consoles navigateur, exécutez une commande d'insertion :
Posts.find().count(); // 1
Posts.insert({title: "A second post"});
Posts.find().count(); // 2
• Vérifier sur le shell Mongo :
db.posts.find();
|
METEOR – Collections temps réel
• Ouvrir la console du 2nd navigateur et exécuter :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 503
Communication client / serveur
db.posts.find(); // 2
• La collection côté serveur a été informé par la collection côté client d'un nouvel article, et a pris
en charge la tâche d'insérer l'article dans la base de données Mongo et de renvoyer l'information
à toutes les autres collections post connectées.
|
METEOR – Collections temps réel
• En phase de développement vous serrez amené à manipuler souvent votre base de données en
ajoutant des collections, créer des documents de tests… Il est par fois utile de repartir sur une
base de données vierge.
• La commande suivante permet de remettre à zéro les données. Avant d’exécuter cette
commande, vous devez arrêter l’instance Meteor (CTRL + C sur la console Meteor).
• Puis relancer votre application Meteor :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 504
meteor reset
meteor
|
METEOR – Collections temps réel
• Toujours en phase de développement, il est intéressant d’ajouter automatiquement des données
de tests en base de données à chaque démarrage de l’application.
• On utilise une fixture, représenté par un fichier JavaScript créé dans le répertoire /server (donc
jamais chargé dans le navigateur d'un utilisateur).
• Le code sera exécuté immédiatement quand le serveur démarrera, et fera des appels d'insertion
sur la base de données.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 505
meteor reset
|
METEOR – Collections temps réel
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 506
if (Posts.find().count() === 0) {
Posts.insert({
title: 'Introducing Telescope',
url: 'http://sachagreif.com/introducing-telescope/'
});
Posts.insert({
title: 'Meteor',
url: 'http://meteor.com'
});
}
server/fixtures.js
|
METEOR – Collections temps réel
• Maintenant que nous avons des articles en base de données, modifions le helper de template
pour récupérer ces articles directement en base, au lieu d’un tableau statique depuis une variable.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 507
Template.postsList.helpers({
posts: function() {
return Posts.find();
}
});
client/templates/posts/posts_list.js
|
METEOR – Collections temps réel
• Ajouter maintenant un article depuis la
console d’un des deux navigateurs.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 508
Posts.insert({
title: 'Meteor Docs',
author: 'Tom Coleman',
url: 'http://docs.meteor.com'
});
• Dans le navigateur, l’article apparait
maintenant dans la liste (l’interface a
été automatiquement mis à jour).
|
METEOR – Collections temps réel
• Par défaut le paquet autopublish est activé.
Dans ce cas là on a pas besoin de penser aux
publications.
• Permet de partager chaque collection dans sa
totalité à chaque client connecté.
• En production il ne faut pas activer le paquet
autopublish, au risque de dévoiler des
informations confidentielles (comme la base user
contenant les mots de passe) !
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 509
Publication et souscriptions des collections
|
METEOR – Collections temps réel
• Instantanément les articles ne sont plus affichés (et donc plus contenu dans la base locale de
chaque client connecté).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 510
Publication et souscriptions des collections
meteor remove autopublish
• Désactiver l’autopublish :
|
METEOR – Collections temps réel
• Comment transférer seulement les articles que l'utilisateur a besoin de voir (en prenant en
compte les choses comme la pagination) ?
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 511
Publication et souscriptions des collections
Meteor.publish('posts', function() {
return Posts.find();
});
server/publications.js
Meteor.subscribe('posts');
client/main.js
|
METEOR – Publications et Souscriptions
• Meteor peut gérer une large quantité de données et être
sécurisé. Il faut cependant comprendre comment le
système de publications et souscriptions fonctionne.
• Meteor = client + serveur.
• Architecture appelée Database Everywhere : Meteor va
prendre un sous-ensemble de votre base de données et le
copier sur le client.
• Au lieu d'envoyer du code HTML au client, une application
Meteor va envoyer la donnée brute (data on the wire).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 512
|
METEOR – Publications et Souscriptions
• On peut accéder aux données instantanément, et même
les modifier, sans attendre un aller-retour client > serveur
(principe de Latency compensation).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 513
|
METEOR – Publications et Souscriptions
• Principe de la publication : décider quelles données vont être publiées sur les copies locales côté
client. On parle alors de sous-ensemble.
• Protocol appelé DDP (Distributed Data Protocol).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 514
Publication
|
METEOR – Publications et Souscriptions
• Cela assure qu'il n'y a aucun moyen possible qu'un client soit capable d'accéder à un article
signalé. Assurez-vous juste que vous publiez seulement les données que vous voulez fournir au
client.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 515
Publication
Meteor.publish('posts', function() {
return Posts.find({flagged: false});
});
server/publications.js
|
METEOR – Publications et Souscriptions
• Exemple : publier une collection dans sa totalité
(ce que fait autopublish quand il est activé).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 516
Publication
Meteor.publish('allPosts', function(){
return Posts.find();
});
server/publications.js
|
METEOR – Publications et Souscriptions
• Exemple : publier une collection partielle.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 517
Publication
Meteor.publish('somePosts', function(){
return Posts.find({'author':'Tom'});
});
server/publications.js
|
METEOR – Publications et Souscriptions
• Exemple : publier des propriétés partielles.
Exclusion de certains champs.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 518
Publication
Meteor.publish('allPosts', function(){
return Posts.find({}, {fields: {
date: false
}});
});
server/publications.js
|
METEOR – Publications et Souscriptions
• On peut aussi combiner les deux exemples précédents (filtrer sur un auteur et retourner
seulement les champs avec date = false).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 519
Publication
Meteor.publish('allPosts', function(){
return Posts.find({'author':'Tom'}, {fields: {
date: false
}});
});
server/publications.js
|
METEOR – Publications et Souscriptions
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 520
Souscription
• Principe : spécifier aux clients quel sous-ensemble de données ils ont besoin à un moment donné.
• Les données auxquelles vous souscrivez seront dupliquées sur le client grâce à Minimongo
(implémentation de MongoDB côté client).
Affichage seulement des
articles écrits par un
utilisateur précis.
|
METEOR – Publications et Souscriptions
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 521
Souscription
Meteor.publish('posts', function(author) {
return Posts.find({flagged: false, author: author});
});
server/publications.js
Meteor.subscribe('posts', 'bob-smith');
client/main.js
|
METEOR – Publications et Souscriptions
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 522
Trouver (filtrer les données de la base locale)
Template.posts.helpers({
posts: function(){
return Posts.find({author: 'bob-smith', category: 'JavaScript'});
}
});
Côté client
• Sélectionner un sous-ensemble précis de données.
|
METEOR – Routage
• Iron Router est un package de routage qui a été créé spécialement pour les applications Meteor.
• La commande suivante permet d’installer le paquet. Pensez à redémarrer votre instance de
Meteor.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 523
Installation du routeur
meteor add iron:router
|
METEOR – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 524
Relier des URLS à des templates
|
METEOR – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 525
Relier des URLS à des templates
<head>
<title>Microscope</title>
</head>
client/main.html
• Le layout sera intégré dans ce template basique (nécessaire avec Meteor / handlebars).
|
METEOR – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 526
Relier des URLS à des templates
<template name="layout">
<div class="container">
<header class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="/">Microscope</a>
</div>
</header>
<div id="main">
{{> yield}}
</div>
</div>
</template>
client/templates/application/layout.html
Remplace notre précédent postsList
|
METEOR – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 527
Relier des URLS à des templates
Router.configure({
layoutTemplate: 'layout'
});
Router.route('/', {name: 'postsList'});
lib/router.js
• Indique au routeur d’utiliser le layout précédent (« layout » correspond au nom du fichier).
• Définition d’une nouvelle route appelée postsList. Assignation à l’URI « / ».
|
METEOR – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 528
Relier des URLS à des templates
<header class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="{{pathFor 'postsList'}}">Microscope</a>
</div>
</header>
client/templates/application/layout.html
|
METEOR – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 529
Router vers un article spécifique
<template name="postPage">
<div class="post-page page">
{{> postItem}}
</div>
</template>
client/templates/posts/post_page.html
|
METEOR – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 530
Router vers un article spécifique
...
Router.route('/', {name: 'postsList'});
Router.route('/posts/:_id', {
name: 'postPage‘
});
lib/router.js
• Nous allons créer une autre route nommée, cette fois en associant les chemins d'URL de la forme
/posts/<ID> au template postPage :
|
METEOR – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 531
Router vers un article spécifique
• Nous routons maintenant vers le template correct, mais il
nous manque encore quelque chose : le routeur connaît
l’_id de l'article que nous voulons afficher, mais le
template n'a toujours pas d'indice.
• Heureusement, le routeur a une solution intégrée
intelligente : il vous laisse spécifier un contexte de
données (data context). C’est ce avec quoi vous remplissez
votre template.
|
METEOR – Routage
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 532
Router vers une page d’erreur
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
notFoundTemplate: 'notFound',
});
lib/router.js
<template name="notFound">
<div class="not-found page jumbotron">
<h2>404</h2>
<p>Désolé, nous ne pouvons pas trouver une page à cette adresse.</p>
</div>
</template>
client/templates/application/not_found.html
|
METEOR – Ajout d’une donnée côté client
• On a vu comment ajouter des données depuis la console du navigateur côté client. Pour rappel,
dans l’application d’exemple on affiche une liste d’article. Pour ajouter un article on appelait
l’instruction Posts.insert().
• On créera une interface graphique pour permettre aux utilisateurs d’ajouter un article.
• On ajoute la route suivante dans le routeur :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 533
Construction de la page d’ajout d’article
Router.route('/submit', {name: 'postSubmit'});
lib/router.js
Correspond au nom du template. Meteor analysera le code
de chacun des fichiers HTML de notre application à la
recherche d’une balise <template> ayant pour attribut
« name » la valeur « postSubmit ».
|
METEOR – Ajout d’une donnée côté client
• Ajout d’un lien dans l’entête de page. On référence directement la route plutôt que d’écrire
l’adresse en dur :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 534
Construction de la page d’ajout d’article
<ul class="nav navbar-nav">
<li><a href="{{pathFor 'postSubmit'}}">Créer un post</a></li>
</ul>
client/templates/includes/header.html
|
METEOR – Ajout d’une donnée côté client
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 535
Construction de la page d’ajout d’article
<template name="postSubmit">
<form class="main form page">
<input name="url" id="url" type="text" value="" placeholder="Votre URL" />
<input name="title" id="title" type="text" value="" placeholder="Nommez votre article" />
<input type="submit" value="Submit" />
</form>
</template>
client/templates/posts/post_submit.html
• Inutile de préciser l’attribut « action » dans le formulaire HTML, car nous allons intercepter
l’évènement d’envoi (submit) sur ce formulaire.
|
METEOR – Ajout d’une donnée côté client
• Pour plus de simplicité on utilise la
bibliothèque jQuery. C’est tout à fait
possible avec Meteor (après avoir
installé le paquet correspondant).
• L’utilisateur envoi le formulaire, un
nouveau article est créé. Puis avec
Router.go(), l’utilisateur est
instantanément redirigé vers une
autre page.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 536
Construction de la page d’ajout d’article
Template.postSubmit.events({
'submit form': function(e) {
e.preventDefault();
var post = {
url: $(e.target).find('[name=url]').val(),
title: $(e.target).find('[name=title]').val()
};
post._id = Posts.insert(post);
Router.go('postPage', post);
}
});
client/templates/posts/post_submit.js
|
METEOR – Ajout d’une donnée côté client
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 537
Sécurisation (validation d’accès)
meteor remove insecure
• Seul les utilisateurs authentifiés doivent pouvoir accéder au formulaire d’ajout d’article.
• La sécurité des données est incluse dans les collections Meteor, mais elle est désactivée par défaut
pour faciliter le développement.
• Pour réactiver cette sécurité, on doit supprimer le paquet insecure :
|
METEOR – Ajout d’une donnée côté client
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 538
Sécurisation (validation d’accès)
• Sans ce paquet, les insert() côté client sur la collection des articles ne sont plus autorisés !
• Donc 2 solutions :
• Définir quand un client et autorisé ou non à insérer un article.
• Faire les insertions côté serveur.
|
METEOR – Ajout d’une donnée côté client
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 539
Sécurisation (validation d’accès)
• Définir quand un client et autorisé ou non à insérer un article :
Posts = new Meteor.Collection('posts');
Posts.allow({
insert: function(userId, doc) {
// autoriser les posts seulement si l'utilisateur est authentifié
return !! userId;
}
});
lib/collections/posts.js
!! : convertie une valeur en booléen
Si useId est égale à 0, null ou undefined  retournera false.
|
METEOR – Ajout d’une donnée côté client
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 540
Sécurisation (validation d’accès)
• Grâce au code précédent (fonction allow), même en utilisant la console navigateur, l’utilisateur ne peut
pas ajouter d’article s’il n’est pas authentifié.
|
METEOR – Ajout d’une donnée côté client
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 541
Sécurisation (validation d’accès)
• Définir quand un client et autorisé ou non à insérer un article – Sécuriser l’accès au formulaire.
Router.route('/submit', {name: 'postSubmit'});
var requireLogin = function() {
if (! Meteor.user()) {
this.render('accessDenied');
} else {
this.next();
}}
Router.onBeforeAction(requireLogin, {only: 'postSubmit'});
lib/router.js
On appelle ça un « hook de routage ».
Peut être comparé aux middlewares de
Express.
|
METEOR – Ajout d’une donnée côté client
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 542
Sécurisation (validation d’accès)
• Définir quand un client et autorisé ou non à insérer un article – Sécuriser l’accès au formulaire.
// On va cacher le lien d’ajout si l’utilisateur n’est pas connecté
<ul class="nav navbar-nav">
{{#if currentUser}}<li><a href="{{pathFor 'postSubmit'}}">Créer un post</a></li>{{/if}}
</ul>
client/templates/includes/header.html
|
METEOR – Ajout d’une donnée côté client
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 543
Sécurisation (validation d’accès)
• Définir quand un client et autorisé ou non à insérer un article – Sécuriser l’accès au formulaire.
|
METEOR – Session
• Utile pour stocker des états éphémères (sans passer par une transmission de paramètre par URL).
• Manipulation des sessions via l’objet natif et global Session.
• Une session est caractérisée par une clé et une valeur.
• Ajout ou modification d’une donnée en session :
• Lecture d’une donnée en session :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 544
Session.set('foo', 'Lorem ipsum');
Session.get('foo');
|
METEOR – Gestion des utilisateurs
• La gestion des utilisateurs est facile avec Meteor. En quelques minutes on peut mettre en place un
système d’authentification complet.
• Meteor inclus nativement l’authentification. Cependant, il faut installer des paquets additionnel
pour ajouter des connecteurs en fonction du ou des types d’authentification que vous souhaitez
mettre en place.
• Connexion par mot de passe (local) : accounts-password
• Connexion depuis un compte Google : accounts-google
• Connexion depuis un compte Twitter : accounts-twitter
• Connexion depuis un compte Facebook : accounts-facebook
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 545
Utilise le protocole OAuth2
pour se connecter à des
services tiers.
meteor add accounts-password
|
METEOR – Gestion des utilisateurs
• Meteor permet de gérer nativement :
• Connexion / Déconnexion
• Création de compte
• Validation de compte par email
• Fonctionnalité mot de passe perdu
• Possibilité d’utiliser le protocole OAuth 2 pour se connecter via un service tiers
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 546
|
METEOR – Gestion des utilisateurs
• Les comptes utilisateurs sont stockés dans la collection MongoDB « users » qui est
automatiquement créé par Meteor sur le serveur.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 547
Collection « users »
{
_id: "bbca5d6a-2156-41c4-89da-0329e8c99a4f", // Meteor.userId()
username: "cool_kid_13",
emails: [
{ address: "cool@example.com", verified: true },
{ address: "another@different.com", verified: false }
],
createdAt: Wed Aug 21 2013 15:16:52 GMT-0700 (PDT),
... (voir slide suivante)
}
|
METEOR – Gestion des utilisateurs
{
... (voir slide précédente)
profile: {
// The profile is writable by the user by default.
name: "Joe Schmoe"
},
services: {
facebook: {
id: "709050", // facebook id
accessToken: "AAACCgdX7G2...AbV9AZDZD"
}
}
}
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 548
Collection « users »
|
METEOR – Gestion des utilisateurs
Meteor.user(); // Retourne null si l’utilisateur n’est pas connecté
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 549
Collection « users »
• Récupération de l’utilisateur courant :
• Remarque : même avec l’auto-publication désactivée, Meteor (via le paquet comptes) auto-publie
les détails de base du compte de l'utilisateur actuellement authentifié. Un utilisateur ne peut donc
pas voir les détails d'un autre compte.
• La publication publie donc seulement un objet utilisateur par utilisateur authentifié (et aucun si
vous n'êtes pas authentifié).
|
METEOR – Gestion des utilisateurs
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 550
Collection « users »
• Par mesure de sécurité, le document user retourné par la collection pour l’utilisateur courant ne
contient pas le même nombre de champs entre MongoDB côté serveur et la base de donnée côté
client.
• On remarque alors qu’une collection locale peut être un sous-ensemble sécurisé (dans le sens où
les données retournées sont limitées). L'utilisateur authentifié voit seulement les informations
nécessaires à son bon fonctionnement.
❯ Meteor.users.findOne();
Object {_id: "kYdBd8hr3fMPGPcii", username: "john"}
Console navigateur
|
METEOR – Gestion des utilisateurs
• L’algorithme de chiffrement bcrypt est utilisé (particulièrement recommandé pour le chiffrement
de données sensibles comme des mots de passe).
• Documentation complète sur le module natif de gestion des utilisateurs / de l’authentification :
• https://www.meteor.com/accounts
• http://docs.meteor.com/#/full/accounts_api
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 551
|
METEOR – Gestion des utilisateurs
• Plutôt que de créer manuellement des templates d’authentification (formulaire de connexion,
création de compte, etc.), vous pouvez installer le paquet suivant :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 552
Interface utilisateur
meteor add accounts-ui-unstyled // Version sans aucune mise en forme
meteor add accounts-ui // Version non Bootstrap
meteor add ian:accounts-ui-bootstrap-3 // Version Bootstrap
{{> loginButtons}}
• Le template « loginButtons » est disponible. Il permet d’afficher un menu déroulant contenant les
formulaires. On utilisera la syntaxe habituelle pour insérer le template :
|
METEOR – Gestion des utilisateurs
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 553
|
METEOR – Gestion des utilisateurs
• Les utilisateurs assument généralement que leur état de connexion est partagée entre tous les
onglets ouverts dans leur navigateur.
• C’est-à-dire que si l’utilisateur à ouvert plusieurs onglets de votre application sur son navigateur,
et qu’il se connecte sur l’un des onglets, il s’attend à être connecté automatiquement sur les
autres onglets.
• En pratique peut de site implémentent ce comportement. L’utilisateur doit recharger les autres
onglets pour profiter de l’authentification (relecture de la session).
• Meteor gère ça nativement en utilisant la base de donnée cliente (local storage) pour
synchroniser l’état de connexion de l’utilisateur entre les onglets.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 554
Synchronisation de l’état de connexion
|
METEOR – Déploiement sur le cloud
• Nous avons vu dans le chapitre consacré à la plateforme Node.js que nous pouvions déployer
rapidement une application dans le cloud. Plusieurs solutions PaaS existent. Nous avions utilisé
Heroku pour sa simplicité et sa gratuité.
• Meteor met également à disposition une solution PaaS entièrement gratuite.
• Documentation complète sur http://guide.meteor.com/deployment.html
• Votre application sera déployée sur un sous-domaine du type http://yourApp.meteor.com.
• Une seule ligne de commande suffit pour le déploiement des sources !
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 555
meteor deploy your-app.meteor.com
|
METEOR – Déploiement sur le cloud
• Suppression d’une application déployée sur Meteor.com :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 556
Commandes utiles
meteor deploy --delete your-app.meteor.com
• Voir les derniers logs :
meteor logs your-app.meteor.com
• Accéder à la base de données mongo :
meteor mongo your-app.meteor.com
|
METEOR – Déploiement sur le cloud
• La commande meteor deploy créé bien une base de données mais ne transfert par défaut pas
vos collections MongoDB. Quelques étapes sont nécessaires pour déployer également votre base
de données.
• Les programmes mongodump et mongostore sont nécessaires. Ils peuvent être téléchargés sur
mongodb.org/downloads (inclus dans le bundle).
• Faire un dump de votre base de données MongoDB locale (-d : nom de votre base de données,
-o : répertoire de destination du dump) :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 557
Déploiement de la base de données Mongo
mongodump -h 127.0.0.1:3002 -d meteor -o meteor
|
METEOR – Déploiement sur le cloud
• Exécuter la commande suivante pour connaitre l’URL de votre base de données distante
MongoDB (créée lors du déploiement de votre application) :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 558
Déploiement de la base de données Mongo
meteor mongo --url your-app.meteor.com
// Retounera une adresse au format :
mongodb://user:password@sky.member1.mongodirector.com:27017/your_app_meteor_com
• La chaine « user:password » correspond au nom d’utilisateur et au mot de passe de votre instance
distante MongoDB créés spécifiquement par Meteor.com lors du déploiement. Le nom du
serveur peut changer.
|
METEOR – Déploiement sur le cloud
• A partir de l’adresse récupérée dans le slide précédent, exécuter la commande suivante pour
déployer vos collections (bien sûr, adapter les paramètres) :
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 559
Déploiement de la base de données Mongo
mongorestore -u client -h sky.member1.mongodirector.com:27017
-d your_app_meteor_com
-p 'password' folder/
Source : http://stackoverflow.com/questions/11024888/is-there-a-simple-way-to-export-the-data-from-a-meteor-deployed-
app/16380978
|
METEOR – Déploiement sur le cloud
• Le déploiement sur Meteor.com est parfait en phase de
développement, mais n’est pas vraiment adaptée pour
de la production (performances limités : chaque
application est lancée dans un processus unique).
• Galaxy est la solution PaaS professionnelle de Meteor.
C’est un système distribué qui repose sur Amazon AWS.
Plus d’infos sur https://galaxy.meteor.com/
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 560
|
Meteor
Exercice d’application :
Création d’une application
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 561
|
METEOR – Création d’une application
• Le développement de cette application compte pour votre partiel.
• Vous pouvez vous baser sur les slides précédentes, mais également sur les autres chapitres de
Discover Meteor qui n’ont pas été abordés ici. Le but est d’implémenter un maximum de choses
dans le temps impartis.
• Soyez créatif et appliquez-vous.
• Vous avez passé un partenariat avec les boulangeries et restaurants de votre quartier. Vous
souhaitez offrir un service à vos utilisateurs, pour leur permettre de passer commande de leur
déjeuner, à partir d’un catalogue de restaurants (et leurs menus) directement depuis votre
application.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 562
|
METEOR – Création d’une application
• Cela va permettre aux restaurateurs / boulangers (qu’on va simplifier par le terme « commerce »)
de préparer leurs commandes en avance. Les clients n’auront plus qu’à aller récupérer leurs
commandes prêtes. On pourrait même aller plus loin en imaginant un système de paiement en
ligne… mais ce sera pour une autre fois.
• Votre application aura plusieurs page :
• Page d’accueil : affichage des commerces.
• Détail d’un commerce : affichage des menus disponibles dans ce commerce et des
informations sur le commerce (nom, horaires d’ouverture, téléphone, etc.).
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 563
|
METEOR – Création d’une application
• Votre application aura plusieurs page :
• Un menu est caractérisé par un nom, un texte de description, un prix, et éventuellement
une photo, un nombre de produit restant.
• En face de chaque menu, un bouton permet de passer commande. Le passage d’une
commande modifie le nombre de produit restant.
• Si vous voulez allez plus loin, vous pouvez ajouter un espace d’administration permettant
de gérer les commerces et leurs menus.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 564
|
METEOR – Création d’une application
• Bien sûr vous devez authentifier vos clients : l’idéal est de passer par un espace client (page
d’inscription, de connexion, récupération du client connecté). Peut être qu’il y a des paquets tout
prêt sur Atmosphere.
• Votre base de données MongoDB contiendra plusieurs collections.
• Cahier des charges :
• Vous devez publier votre projet sur GitHub.
• Vous pouvez publier votre application sur le cloud Meteor.
• Vous devez utiliser Bootstrap pour votre interface utilisateur.
Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 565
|Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 566
Merci de votre attention !

Formation JavaScript full-stack (JS, jQuery, Node.js...)

  • 1.
    Formation « WebAvancé » JavaScript full-stack – Node.js – Meteor Février 2016 – Formation ORT 3CSi spécialité développement web Guillaume MOREL-BAILLY
  • 2.
    | Copyright Cette présentation estmis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International (CC BY-NC-SA 4.0). http://creativecommons.org/licenses/by-nc-sa/4.0/ Vous êtes autorisé à partager et adapter ce document, selon les conditions suivantes : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 2 Attribution — Vous devez créditer l’œuvre, intégrer un lien vers la licence et indiquer si des modifications ont été effectuées à l’œuvre. Pas d’Utilisation Commerciale — Vous n'êtes pas autorisé à faire un usage commercial de cette œuvre, tout ou partie du matériel la composant. Partage dans les mêmes conditions — Dans le cas où vous reprenez ou effectuez une modification de cette œuvre, vous devez la diffuser dans les même conditions, c'est à dire avec la même licence d’utilisation.
  • 3.
    | Présentation • Guillaume MOREL-BAILLY •Développeur web et mobile freelance depuis +5 ans • Ingénieur en sécurité informatique depuis 1 an pour une SSII. Sécurisation et maintenance d’une application de BI pour un acteur mondial de l'acier inoxydable. • Me contacter : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 3 Qui suis-je ? linkedin.com/in/guillaumemorelbailly
  • 4.
    | Présentation • Tour detable pour mieux vous connaitre, cerner vos attentes et besoins. • Cursus / formation; expérience(s) professionnelle(s); technos abordées ou maitrisées; projets futurs, etc. ? • Qu’attendez-vous de cette formation ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 4 Qui êtes-vous ?
  • 5.
    | Présentation du cours •Objectif : vous apporter une culture sur les techniques de développement web modernes orientées JavaScript. Découverte d’architectures et de frameworks client / serveur utilisés en entreprise. • Volume horaire : mois de février • Cours théorique (slides) et pratiques (exercices, TP) • Documents de cours • Evaluations : contrôles de connaissance (QCM + devoir sur feuille) + 1 application à développer de A à Z (mise en situation) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 5
  • 6.
    | Technologies, frameworks, outils…abordés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 6
  • 7.
    | Plan de formation 1)Introduction à JavaScript 2) Développer avec jQuery 3) L’architecture MEAN 4) Node.js 5) Déploiement cloud sur Heroku (aparté) 6) Socket.io Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 7 7) Express 8) MongoDB 9) Angular 10) MEAN.JS 11) METEOR
  • 8.
    Partie 1 Introduction àJavaScript Eléments de base du langage et concepts avancés
  • 9.
    | JavaScript Histoire Février 2016Formation ORT 3CSi - Guillaume MOREL-BAILLY 9
  • 10.
    | JavaScript – Pourquoi? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 10
  • 11.
    | JavaScript – Histoire •1993 : apparition du navigateur web NCSA Mosaic qui a rendu le World Wide Web populaire. Distribué gratuitement par le NCSA (National Center for Supercomputing Applications). • NCSA : un centre de recherche universitaire américain précurseur sur les technologies web. Développement par exemple du serveur web HTTPd (qui servira de base à Apache). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 11 • 1994 : création de la Netscape Communications Corporation, puis apparition de Netscape Navigator un an plus tard, suite au débauchage des développeurs de Mosaic. • 1995 : Netscape détient plus de 90 % de part de marché, Microsoft lance Internet Explorer 1.0.
  • 12.
    | JavaScript – Histoire •Netscape voulait que le langage de programmation Scheme soit intégré au sein de son navigateur. Scheme est un langage de script très épuré créé dans les années 70. • Brendan Eich est embauché par Netscape pour cette mission, mais finalement on lui demande de créer un nouveau langage de programmation. • Le cahier des charges était strict : il devait créer ce langage en 10 jours pour respecter la date de sortie de la version beta 2.0 de Netscape Navigator. Il fallait aussi s’inspirer de Java. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 12
  • 13.
    | JavaScript – Histoire "Therewas some pressure from management to make the syntax look like Java. There was also some pressure to make it not too big, because after all, people should use Java if they're doing any real programming. This is just Java's dumb little brother. But if I put classes in, I’d be in big trouble.“ Brendan Eich Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 13
  • 14.
    | JavaScript – Histoire •Brendan Eich s’est alors inspiré du langage de programmation Self, basé sur le concept de prototypes. • Le langage Mocha est créé, renommé ensuite en LiveScript. Quelques mois plus tard, en septembre 1995, Netscape opte pour un nom plus vendeur, JavaScript, après un partenariat signé avec Sun Microsystems. • Attention, malgré son nom et quelques similarités syntaxiques superficielles, JavaScript n’est pas Java ! Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 14
  • 15.
    | JavaScript – Histoire •1996 : JavaScript est rapidement adopté pour le développement web orienté client. Netscape soumet JavaScript à l’organisme de standardisation ECMA International. • Microsoft réagit en développant JScript inclus dans Internet Explorer 3. • 1997 : adoption du nouveau standard ECMAScript. Les spécifications sont rédigées dans le document Standard ECMA-262. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 15
  • 16.
    | ECMAScript Tout est histoirede standardisation Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 16
  • 17.
    | JavaScript – ECMAScript •Ecma International est une organisation européenne de standardisation informatique (au sens large). On pourrait le comparer au consortium W3C, mais qui est chargé uniquement des technologies du World Wide Web. • JavaScript est standardisé par Ecma International. • Le nom ECMAScript réfère au langage de programmation de type script standardisé. Le standard ECMAScript est documenté avec la spécification ECMA-262. • ECMAScript ne décrit pas le Document Object Model (DOM) qui est standardisé par le W3C. • Les spécifications du standard sont mises en œuvre dans différents langages de script. Les implémentations les plus connus étant JavaScript, Jscript et ActionScript. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 17
  • 18.
    | JavaScript – ECMAScript Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 18
  • 19.
    | JavaScript – ECMAScript •ECMAScript Edition 5 (ES5) : version actuellement intégrée dans les moteurs de scripts des navigateurs web  version qu’on utilisera dans le reste de ce cours • ECMAScript Edition 6 (ES6) : publié en juin 2015, ES6 (appelé aussi ES2015) n’est pas encore pleinement supporté par les navigateurs. On peut utiliser un transcompilateur comme Babel ou Traceur vers ES5 pour développer dés maintenant en ES6. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 19 Dernières versions d’ECMAScript : Tester la compatibilité ES6 de votre navigateur sur : kangax.github.io/compat-table/es6/
  • 20.
    | JavaScript – ECMAScript •JavaScript, implémentation du standard ECMAScript n’a pas évolué depuis 2009. Depuis, de plus en plus d’applications web utilisent massivement JavaScript côté client. Le développement natif en JavaScript devient complexe et des manques se font sentir. • ECMAScript 6 est une mise à jour majeure du langage de script standardisé (liste complète des nouveautés sur : https://github.com/lukehoban/es6features/blob/master/README.md, comparaison de code ES5 vs ES6 sur http://es6-features.org/). • Le langage de programmation TypeScript est publié en 2012 par Microsoft. C’est un langage à part entière de JavaScript mais qui permet de transpiler le code TypeScript en JavaScript. Il a été créé pour apporter une réponse aux manques de ECMAScript 5. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 20 ECMAScript 6 (ES2015)
  • 21.
    | ECMAScript 6 (ES2015) classShape { constructor (id, x, y) { this.id = id; this.move(x, y); } move (x, y) { this.x = x; this.y = y; } } ECMAScript 5 var Shape = function (id, x, y) { this.id = id; this.move(x, y); }; Shape.prototype.move = function (x, y) { this.x = x; this.y = y; }; Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 21 JavaScript – ECMAScript
  • 22.
    | JavaScript – ECMAScript •Langage de programmation open-source développé en 2012 par Microsoft, comme un sur- ensemble de JavaScript (tout code JavaScript peut être utilisé dans TypeScript). • Développé dans le but d’améliorer le code JavaScript (face aux manquements d’ECMAScript 5) : typage, interfaces, classes, modules, mixin, etc. • Le code TypeScript est transcompilé / transpiler vers JavaScript. • TypeScript supporte la spécification ECMAScript 6. Son intérêt est limité depuis l’arrivée d’ECMAScript 6. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 22 TypeScript
  • 23.
    | Moteurs de script etde rendu Comprendre le fonctionnement et les composants de nos navigateurs web. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 23
  • 24.
    | JavaScript – Moteursde script Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 24
  • 25.
    | JavaScript – Moteursde script Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 25 Moteur de rendu (HTML + CSS) Moteur de script (JavaScript) Plugins (Flash, Silverlight, Applets Java, etc.)
  • 26.
    | JavaScript – Moteursde script Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 26
  • 27.
    | JavaScript – Moteursde script Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 27
  • 28.
    | JavaScript – Moteursde script Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 28 Moteur de rendu (HTML + CSS) Moteur de script (JavaScript)
  • 29.
    | JavaScript – Moteursde script Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 29 Firefox Moteur de rendu : Gecko Moteur de script : SpiderMonkey Google Chrome Moteur de rendu : Blink Moteur de script : V8 Internet Explorer Moteur de rendu : Trident Moteur de script : Chakra Safari Moteur de rendu : WebKit Moteur de script : Nitro Opera Moteur de rendu : Blink Moteur de script : V8
  • 30.
    | JavaScript – Moteursde script • Projet open-source développé par Google et écrit en C++. • Développé à l’origine pour Google Chrome, mais utilisé dans de nombreux autres projets, dont Node.js (cette technologie sera abordée dans un prochain chapitre). • Un moteur JavaScript très moderne sur plusieurs aspects. • V8 compile directement le JavaScript en langage machine (langage natif du processeur) avant de l’exécuter. Alors que les autres moteurs de script interprètent du bytecode, ou compilent le code en langage machine avant de l’exécuter. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 30 V8 : le moteur de script « next gen » de Google
  • 31.
    |Février 2016 FormationORT 3CSi - Guillaume MOREL-BAILLY 31 JavaScript – Chargement d’une page par le navigateur
  • 32.
    | Le langage JavaScript Présentation Février 2016Formation ORT 3CSi - Guillaume MOREL-BAILLY 32
  • 33.
    | JavaScript – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 33
  • 34.
    | JavaScript – Présentation •JavaScript est un langage de script, multi-plateforme et orienté web, piloté par les évènements. • Il fait partie d’un environnement hôte, le plus souvent un navigateur web, pour qu’il puisse être utilisé sur les objets de cet environnement. • Fonctionnalités centrales et native de JavaScript : • Bibliothèque standard d’objets (Array, Date, Math, etc.) • Eléments de langage : opérateurs, structures de contrôles, instructions, etc. • Fonctionnalités étendues (côté client) : contrôle du navigateur et du DOM. Le DOM définit la façon dont les documents HTML sont exposés aux scripts. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 34 JavaScript, c’est quoi ?
  • 35.
    | JavaScript – Présentation •Notion de « first-class functions » (objet de première classe). • Les fonctions JavaScript sont des objets de première classe, ce qui veut dire que les fonctions et les objets sont traités exactement de la même manière. Toute opération faite sur un entier, un string, un array ou un objet générique peut être fait sur une fonction. A l’inverse seule une fonction peut être appelée. • De manière concrète : • Une fonction peut avoir des propriétés • On peut affecter une fonction à une variable : var foo = function() {…}; • On peut passer une fonction comme paramètre à une autre fonction • Une fonction peut retourner une autre fonction Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 35 JavaScript, c’est quoi ?
  • 36.
    | JavaScript – Présentation varsquare = function(x) { return x * x; }, mult = function (f1, f2) { return function(n) { return f1(n) * f2(n); } }, foo = mult(square, square), value = foo(2); console.log(value); // 16 Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 36 JavaScript, c’est quoi ?
  • 37.
    | JavaScript vs Java(ou tout autre langage comparable : C#, C++, etc.) • JavaScript est interprété : le code est traité par le moteur de script du navigateur lors de l’exécution (ce qui le rend indépendant de toute plate-forme). Cas particulier : le moteur de script V8 de Google (inclus dans Chrome, Opera) qui compile JavaScript en code machine natif avant de l’exécuter. • Java est un langage compilé et interprété (le code source est compilé vers un bytecode, la machine virtuelle Java interprète ce bytecode). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 37 JavaScript – Présentation
  • 38.
    | JavaScript vs Java(ou tout autre langage comparable : C#, C++, etc.) • JavaScript est un langage de programmation objet orienté prototype. Les prototypes sont utilisés pour représenter les liens entre les objets. Les prototypes permettent d'avoir un héritage dynamique. Ainsi, les caractéristiques héritées par un objet peuvent varier dans le temps. • Java est un langage de programmation objet orienté classe. Il est entièrement basé sur l’utilisation de classes et de méthodes. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 38 JavaScript – Présentation
  • 39.
    | JavaScript vs Java(ou tout autre langage comparable : C#, C++, etc.) • JavaScript est faiblement typé (typage dynamique). Seul le type var existe. NB : Avec ECMAScript 6, les types let et const sont introduits. TypeScript permet d’avoir un typage fort. • Java est fortement typé (typage statique) : char, byte, short, int, long, float, double, boolean et string. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 39 JavaScript – Présentation var name = "John"; var now = new Date(); var p = new Person(name, now); String name = "John"; Date now = new Date(); Person p = new Person(name, now); Person p = "Jake"; // throws ClassCastException
  • 40.
    | JavaScript – Ecriredu code côté client • La balise script permet d’intégrer du code JavaScript dans une page. • Attributs de script : • type : indique le type MIME du contenu  "text/javascript" . Note : depuis HTM5 il n’est plus nécessaire de spécifier le type. • src : indique que le code se situe dans un fichier externe Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 40 Balise HTML script
  • 41.
    | JavaScript – Ecriredu code côté client Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 41 Code JavaScript « inline » <script type="text/javascript"> function helloWorld() { alert("Hello World"); } </script> • Conseil : déplacer le code JavaScript dans un fichier externe et utiliser le moins possible du code inline dans un fichier HTML pour favoriser la maintenabilité et séparer clairement les responsabilités (l’affichage des traitements).
  • 42.
    | JavaScript – Ecriredu code côté client Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 42 Fichier externe <!DOCTYPE html> <html lang="fr"> <head>...</head> <body> ... <script src="main.js"></script> </body> </html> • Conseil : charger les fichiers externes JavaScript en bas de page (juste avant la balise fermante body). Le navigateur web interprète la page reçue ligne par ligne : le chargement d’une ressource JavaScript est bloquante.
  • 43.
    | JavaScript – Ecriredu code côté client • Sur la majorité des navigateurs web : touche F12 • Firefox intègre même une console avancée : Développement > Ardoise JavaScript (Maj + F4) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 43 Console du navigateur
  • 44.
    | Le langage JavaScript Eléments debase Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 44
  • 45.
    | JavaScript Février 2016 FormationORT 3CSi - Guillaume MOREL-BAILLY 45
  • 46.
    | JavaScript – Lesopérateurs Types d’opérateurs Code d’exemple var var foo; new new Foo; Assignation foo = {bar: "a value"} foo.bar = "value"; delete delete foo.bar; Membres foo.bar; foo[‘bar’]; Appel bar(); foo.bar(); Comparaison == ou === Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 46
  • 47.
    | JavaScript – Lesvariables Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 47 Déclarations Type de déclaration ECMAScript var ES5 On déclare une variable, éventuellement en initialisant sa valeur. let ES6 On déclare une variable dont la portée est celle du bloc courant, éventuellement en initialisant sa valeur. const ES6 On déclare une constante nommée, accessible en lecture seule. var x; var y = 42; var foo = "hello"; bar = "world";
  • 48.
    | JavaScript – Lesvariables • Une variable déclarée grâce à l'instruction var ou let sans valeur initiale définie vaudra undefined. • Tenter d'accéder à une variable qui n'a pas été déclarée lèvera l’exception ReferenceError. • On utilise undefined pour déterminer si une variable possède une valeur : if (foo === undefined)… Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 48 Evaluation des variables var a; console.log("La valeur de a est " + a); // le log contient "La valeur de a est undefined" console.log("La valeur de b est " + b); // signale une exception ReferenceError
  • 49.
    | JavaScript – Lesvariables • Valeur undefined dans un contexte booléen : convertie en false • Valeur undefined dans un contexte numérique : convertie en NaN Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 49 Evaluation des variables var monTableau = new Array(); if (!monTableau[0]){ // false maFunction(); } var a; a + 2; // NaN
  • 50.
    | JavaScript – Lesvariables • Valeur null dans un contexte numérique : convertie en 0 (zéro) • Valeur null dans un contexte booléen : convertie en false Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 50 Evaluation des variables var n = null; console.log(n * 32); // Le log affichera 0
  • 51.
    | JavaScript – Typesde données • 6 types de données primitifs en ECMAScript 5: • Type booléen : Boolean (avec les valeurs true ou false) • Type nul : null • Type pour les valeurs indéfinies : undefined • Type pour les nombres : Number (par exemple 42 ou 3.14159) • Type pour les chaines de caractère : String (par exemple "Hello World") • 5 type pour les objets : Object, Array, Date, RegExp, Function Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 51
  • 52.
    | JavaScript – L’instructiontypeof • Comme JS est faiblement typé, on a parfois le besoin de savoir avec qu’elle type de valeur on travaille. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 52
  • 53.
    | JavaScript – Conversionde types de données • D’après vous, le code suivant lève t’il une erreur ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 53 var answer = 42; answer = "Thanks for all the fish..."; JavaScript utilisant un typage dynamique, cette dernière instruction ne renverra pas d'erreur.
  • 54.
    | JavaScript – Conversionde types de données • Lorsque des expressions impliquent des chaînes de caractères et des valeurs numériques ainsi que l'opérateur "+", JavaScript convertit les nombres en chaînes de caractères : • Attention, avec des instructions impliquant d'autres opérateurs (comme le signe "-", JavaScript ne convertit pas nécessairement les valeurs numériques en chaînes de caractères. Ainsi, on aura : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 54 x = "La réponse est " + 42; // "La réponse est 42" y = 42 + " est la réponse"; // "42 est la réponse" foo = "37" - 7; // 30 bar = "37" + 7; // "377"
  • 55.
    | JavaScript – Conversionde chaînes en nombres • parseInt effectue une conversion en valeur entière • Number effectue une conversion numérique plus stricte Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 55 parseInt(""); // NaN parseInt(42.5); // 42 parseInt("42"); // 42 parseInt("077"); // 63 (= 7 + 7*8) parseInt("123foo"); // 123 parseInt("0xF", 16); // 15 car on est en base hexa Number("foo"); // NaN Number("001"); // 1
  • 56.
    | JavaScript – Conversionde chaînes en nombres • parseFloat effectue une conversion d’une chaine de caractère en nombre flottant Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 56 parseFloat("42.5"); // 42.5 parseFloat("1.45kg"); // 1.45 parseFloat("77.3"); // 77.3 parseFloat("077.3"): // 77.3 parseFloat("0x77.3"): // 0 parseFloat(".3"); // 0.3 parseFloat("0.1e6"); // 100000
  • 57.
    | JavaScript – Opérateurde comparaison Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 57
  • 58.
    | JavaScript - Commentaires //un commentaire sur une ligne /* un commentaire plus long sur plusieurs lignes */ /* Par contre on ne peut pas /* imbriquer des commentaires */ SyntaxError */ Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 58
  • 59.
    | JavaScript - Objets Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 59 • Liste d’une ou plusieurs paires de propriétés nom / valeur • Ces paires sont délimitées par des accolades : { } • On peut également pour imbriquer un objet dans un autre var person = { firstName: "John", lastName: "Honda", age: 29, foo: { bar: "test" } };
  • 60.
    | JavaScript - Objets Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 60 var sales = "Toyota"; function carTypes(name) { if (name === "Honda") { return name; } else { return "Sorry, we don't sell " + name + "."; } } var car = { myCar: "Saturn", getCar: carTypes("Honda"), special: sales }; console.log(car.myCar); // Saturn console.log(car.getCar); // Honda console.log(car.special); // Toyota
  • 61.
    | JavaScript – Tableaux(Arrays) • Les tableaux JavaScript sont des objets semblables à une liste • Ils possèdent plusieurs méthodes incorporées pour exécuter des opérations de parcours et de modification. • Syntaxes pour créer un array : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 61 Description et syntaxe [element0, element1, ..., elementN] new Array(element0, element1[, ...[, elementN]]) new Array(arrayLength) var fruits = ["Apple", "Banana"];
  • 62.
    | JavaScript – Tableaux(Arrays) • Le premier élément d'un tableau a 0 pour indice • La position du dernier élément est donnée par length moins 1. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 62 Accéder aux éléments d’un tableau var arr = ["this is the first element", "this is the second element"]; console.log(arr[0]); // logs 'this is the first element' console.log(arr[1]); // logs 'this is the second element' console.log(arr[arr.length - 1]); // logs 'this is the second element‘ var fish = ["Lion", , "Angel"]; console.log(fish[0]); // logs ‘Lion' console.log(fish[1]); // logs ‘undefined' console.log(fish[2]); // logs ‘Angel ‘
  • 63.
    | JavaScript – Tableaux(Arrays) • Les éléments d'un tableau sont simplement des propriétés d'objets. • Normalement on accède à une propriété d’objet avec la notation en point (object.property) • Cependant il n’est pas possible d’accéder aux propriétés dont le nom commence par un chiffre. Il est nécessaire d'utiliser la syntaxe avec les crochets. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 63 Accéder aux éléments d’un tableau var years = [1950, 1960, 1970, 1980, 1990, 2000, 2010]; console.log(years.0); // a syntax error console.log(years[0]); // works properly
  • 64.
    | JavaScript – Tableaux(Arrays) • De façon semblable, les propriétés nommées avec des mots-clés réservés ne peuvent être consultées qu'en utilisant la syntaxe avec crochets : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 64 Accéder aux éléments d’un tableau (aparté) // An object var promise = { 'var' : 'text', 'array': [1, 2, 3, 4] }; Console.log(promise.array); // syntax error console.log(promise['array']); // works properly
  • 65.
    | JavaScript – Objetnatif : exemple de Math • L’objet Math est un objet natif dont les méthodes et propriétés permettent l'utilisation de constantes et fonctions mathématiques. • Cet objet n'est pas une fonction ! • Toutes les propriétés et les méthodes de Math sont statiques. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 65 console.log(Math.e); // 2.718 (nombre d’Euler) Console.log(Math.PI); // 3.14159… Console.log(Math.min(2, 58)); // 2 Console.log(Math.ceil(42.3)); // 43 : plus petit entier supérieur Console.log(Math.floor(42.8)); // 42 : plus petit entier inférieur
  • 66.
    | JavaScript - Instructionsconditionnelles Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 66 Instruction if...else if (condition_1) { statement_1; } else if (condition_2) { statement_2; } else if (condition_n) { statement_n; } else { statement_last; }
  • 67.
    | JavaScript - Instructionsconditionnelles • Lors d'un test, les valeurs suivantes seront considérées comme équivalentes à false : • False • Undefined • Null • 0 • NaN • La chaine de caractère vide ("") Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 67 Instruction if...else
  • 68.
    | JavaScript - Instructionsconditionnelles • Attention à ne pas confondre les valeurs booléennes « primitives » true et false avec les valeurs crées grâce à un objet Boolean. Par exemple, on aura : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 68 Instruction if...else var b = new Boolean(false); if (b) // this condition evaluates to true if (b == true) // this condition evaluates to false
  • 69.
    | JavaScript - Instructionsconditionnelles Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 69 Instruction switch switch (fruittype) { case "Oranges": console.log("Oranges are $0.59 a pound."); break; case "Apples": console.log("Apples are $0.32 a pound."); break; case "Bananas": console.log("Bananas are $0.48 a pound."); break; default: console.log("Sorry, we are out of " + fruittype + "."); } console.log("Is there anything else you'd like?");
  • 70.
    | JavaScript – Boucleset itérations Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 70 Instruction for for (var i = 0; i < 9; i++) { console.log(i); // more statements } var i = 0; for (;;) { if (i > 3) break; console.log(i); i++; }
  • 71.
    | JavaScript – Boucleset itérations • Permet d'itérer sur l'ensemble des propriétés énumérables d'un objet, dans un ordre arbitraire. • Ne doit pas être utilisée pour parcourir un Array lorsque l'ordre des éléments est important ! Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 71 Instruction for…in var obj = {a:1, b:2, c:3}; for (var prop in obj) { console.log("obj." + prop + " = " + obj[prop]); } // Output: // "obj.a = 1" // "obj.b = 2" // "obj.c = 3"
  • 72.
    | JavaScript – Boucleset itérations • Permet d'exécuter une instruction tant qu'une condition donnée est vérifiée. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 72 Instruction while while (i < 10) { text += "The number is " + i; i++; }
  • 73.
    | JavaScript – Boucleset itérations • Permet de répéter un ensemble d'instructions jusqu'à ce qu'une condition donnée ne soit plus vérifiée. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 73 Instruction do…while do { i += 1; console.log(i); } while (i < 5);
  • 74.
    | JavaScript – Conceptsavancés • Il est possible de lever (c’est-à-dire signaler) des exceptions avec l'instruction throw et de les gérer (les intercepter) avec des instructions try...catch. • En JavaScript, n'importe quel objet peut être signalé comme une exception : throw "Erreur2"; • Cependant, afin de respecter certaines conventions et de bénéficier de certaines informations, on préférera les exceptions de base ECMAScript ou DOMException / DOMError si on manipule le DOM. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 74 Gestion des exceptions Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError
  • 75.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 75 Gestion des exceptions // Lever une erreur générique try { throw new Error("Ouups !"); } catch (e) { console.log(e.name + ": " + e.message); }
  • 76.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 76 Gestion des exceptions // Gérer une erreur spécifique try { foo.bar(); } catch (e) { if (e instanceof EvalError) { console.log(e.name + ": " + e.message); } else if (e instanceof RangeError) { console.log(e.name + ": " + e.message); } // ... etc }
  • 77.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 77 Gestion des exceptions // On crée un nouvel objet, héritage par prototype depuis le constructeur de type Error function MyError(message) { this.name = 'MyError'; this.message = message || 'Default Message'; this.stack = (new Error()).stack; } MyError.prototype = Object.create(Error.prototype); MyError.prototype.constructor = MyError; try { throw new MyError('custom message'); } catch (e) { console.log(e.name); // 'MyError' console.log(e.message); // 'custom message' }
  • 78.
    | JavaScript – Fonctions •Les fonctions font partie des briques fondamentales de JavaScript. • Rappel de la partie « Présentation » : les fonctions sont des objets de première classe. Cela signifie qu'elles peuvent être manipulées et échangées, qu'elles peuvent avoir des propriétés et des méthodes, comme tous les autres objets JavaScript. • Une fonction est une procédure JavaScript, un ensemble d'instructions effectuant une tâche ou calculant une valeur. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 78 var x = myFunction(4, 3); // Function is called, return value will end up in x function myFunction(a, b) { return a * b; // Function returns the product of a and b }
  • 79.
    | JavaScript – Fonctions •Déclaration d’une fonction Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 79 function add(a, b) { var c = a+b; return c; } var add = function (a, b) { var c = a+b; return c; }; • On peut également assigner une fonction à une variable
  • 80.
    | JavaScript – Fonctions •On peut aussi rendre une fonction auto exécutable : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 80 (function() { console.log('Hello World!'); })(); // Affichera Hello World! à l’ouverture de la page
  • 81.
    | JavaScript – Fonctions •Les paramètres donnés lors de l'appel d'une fonction sont appelés les arguments de la fonction. • Les arguments sont passés par valeur. Si la fonction modifie la valeur d'un argument, ce changement ne se répercute pas en dehors de la fonction. • Cas spécifique : passage par référence d’un objet. Si la fonction modifie les propriété de l'objet de la référence, ce(s) changement(s) seront perceptibles en dehors de la fonction. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 81 NB: Les notions de porté, passage par valeur et référence seront étudiées plus en détail dans le chapitre suivant.
  • 82.
    | JavaScript – Fonctions Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 82 // Declare the function 'myFunc' function myFunc(theObject) { theObject.brand = "Toyota"; } var mycar = { brand: "Honda", model: "Accord", year: 1998 }; console.log(mycar.brand); // Log 'Honda‘ myFunc(mycar); // Pass object reference to the function // Logs 'Toyota' as the value of the 'brand' property of the object, as changed to by the function console.log(mycar.brand);
  • 83.
    | Le langage JavaScript Manipulation duDOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 83
  • 84.
    | JavaScript – Manipulationdu DOM • JavaScript contient une bibliothèque standard d'objets tels que Array, Date, et Math, ainsi qu'un ensemble d'éléments de langage (on vient de les voir). • Ces fonctionnalités centrales et natives de JavaScript peuvent être étendues de plusieurs façons en fournissant d'autres objets. • JavaScript côté client étend ces éléments de base en fournissant des objets pour contrôler le navigateur et le Document Object Model (DOM). • Le DOM définit la façon dont les documents HTML sont exposés aux scripts. C’est une API, standardisée par le W3C et exploitée par les navigateurs web (entre autre). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 84
  • 85.
    | JavaScript – Manipulationdu DOM • De manière simplifiée, le DOM : • fournit une représentation structurée d’un document HTML ou XML; • codifie la manière dont un script peut accéder à cette structure. • Le DOM parcourt une hiérarchie d’éléments. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 85
  • 86.
    | JavaScript – Manipulationdu DOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 86
  • 87.
    | JavaScript – Manipulationdu DOM • L’API DOM est accessible par JavaScript via l’objet « document » • Plusieurs méthodes : • document.createElement() • document.getElementById() • document.getElementByTagName() • document.getElementByName() • Plusieurs propriétés : • innerHTML • innerText Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 87
  • 88.
    | JavaScript – Manipulationdu DOM • Créer une page HTML composée des éléments suivantes : • Un titre de niveau h1 • Un paragraphe contenant du texte (contenant des mots en « strong », un lien, etc.) • Une liste de type ul ou ol • Le tout englobé dans un div • Utiliser document pour mettre en couleur le paragraphe • Créer un bouton permettant d’afficher une popup contenant l’attribut href du lien contenu dans le paragraphe. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 88 Exercice n°1 : objectif
  • 89.
    | JavaScript – Manipulationdu DOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 89 Exercice n°1 : correction <div id="wrapper"> <h1>Hello World!</h1> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In suscipit, metus et aliquam convallis, orci est blandit metus, vel fringilla erat ex sit amet odio. Nunc consectetur aliquet odio, sit amet suscipit orci. Maecenas <a href="http://www.google.fr" title="Google" id="link">finibus</a> ipsum.</p> <ul> <li>Lorem ipsum</li> <li>Dolor sit amet</li> <li>Foo bar</li> </ul> <button id="myButton">Get href</button> </div>
  • 90.
    | JavaScript – Manipulationdu DOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 90 Exercice n°1 : correction <script> var elements = document.getElementsByTagName("p"); var length = elements.length; for (var i = 0; i < length; i++) { elements[i].style.color= "red"; } var myLink = document.getElementById("link"); var myButton = document.getElementById("myButton"); myButton.addEventListener("click", function(event) { alert(myLink.getAttribute("href")); }); </script>
  • 91.
    | JavaScript – Manipulationdu DOM • Créer une fonction JavaScript qui permette d’ajouter une ligne à un tableau au clic sur un bouton. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 91 Exercice n°2 : objectif <table id="myTable" border="1"> <tr> <td>Ligne1 cellule1</td> <td>Ligne1 cellule2</td> </tr> <tr> <td>Ligne2 cellule1</td> <td>Ligne2 cellule2</td> </tr> </table>
  • 92.
    | JavaScript – Manipulationdu DOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 92 Exercice n°2 : correction function insertRow() { var foo = document.getElementById('myTable').insertRow(0); var cell1 = foo.insertCell(0); var cell2 = foo.insertCell(1); cell1.innerHTML = "NvllLigne Cellule1"; cell2.innerHTML = "NvllLigne Cellule2"; } <button id="insertNewRow" onclick="insertRow">Ajouter une nouvelle ligne</button>
  • 93.
    | JavaScript – Manipulationdu DOM • Créer une page contenant un bouton qui permette de de générer un nombre aléatoire compris entre 1 et 12. • Afficher le résultat dans un champ input de type text. • Le bouton doit changer d’état : au premier chargement, afficher « Jouer » puis afficher « Rejouer ». • Astuce : vous pouvez utiliser l’objet Math pour générer un nombre aléatoire. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 93 Exercice n°3 – « Tirage au sort » : objectif
  • 94.
    | JavaScript – Manipulationdu DOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 94 Exercice n°3 – « Tirage au sort » : correction Pour générer le nombre aléatoire entre 1 et 12 : // Valeur min inclue, max inclue Math.floor(Math.random() * (max - min + 1)) + min; -> Math.random : nbr entre 0 et 1 -> (max - min + 1) : 12 - 1 + 1 -> Math.floor = plus grand entier qui est <= à un nbr x
  • 95.
    | JavaScript – Manipulationdu DOM • Créer une fonction JavaScript qui, au clic sur un bouton : • Demande à l’utilisateur de saisir le nombre de colonnes et le nombre de lignes. • Créée dynamiquement un tableau en fonction des entrées récupérées (et modifier le nom de chaque cellule créée). • Astuce : utiliser window.prompt() Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 95 Exercice n°4 : objectif
  • 96.
    | JavaScript – Manipulationdu DOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 96 Exercice n°4 : correction <table id="theTable" border="1"></table> <button onclick="create">Créer un tableau</button> // ou via fonction anonyme function create() { nbRow = window.prompt("Nombre de ligne", 1); nbCell = window.prompt("Nombre de colonnes", 1); for (var r = 0; r < parseInt(nbRow, 10); r++) { var x = document.getElementById(‘theTable').insertRow(r); for (var c = 0; c < parseInt(nbCell, 10); c++) { var y = x.insertCell(c); y.innerHTML=« Ligne "+ r +« , colonne "+ c; } } }
  • 97.
    | JavaScript – Manipulationdu DOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 97 Exercice n°5 : objectif • Créer une liste HTML (select) puis ajouter quelques éléments à cette liste (option). • Ajouter un bouton qui permettre de supprimer l’élément sélectionné de la liste. • Astuce : selectedIndex permet de récupérer l’élément sélectionné d’une liste HTML
  • 98.
    | JavaScript – Manipulationdu DOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 98 Exercice n°5 : correction <select id="fruits"> <option>Orange</option> <option>Mandarine</option> <option>Banane</option> <option>Kiwi</option> </select> <input type="button" id="myButton" value="Supprimer ce fruit"> var myButton = document.getElementById("myButton"); myButton.addEventListener("click", function(event) { var fruitsList = document.getElementById("fruits"); fruitsList.remove(fruitsList.selectedIndex); });
  • 99.
    | JavaScript – Manipulationdu DOM • Ecrire un programme qui permette d’afficher une image aléatoire après un clic sur un bouton. Attention : ces images doivent être préchargées lors du premier clic (pour améliorer l’UI). • Pour vous aider, voici quelques étapes : • Créer un objet contenant vos images avec quelques propriétés, ex : url, hauteur, largeur. • Précharger les images avec new Image(), les stocker dans un tableau. • Créer une fonction permettant de générer un nombre aléatoire (pour charger l’image aléatoirement dans votre objet) compris entre 0 et la taille de votre tableau de buffer. Vous pouvez vous baser sur l’exercice précédent. • Retourner l’élément correspondant à ce nombre aléatoire à partir du tableau de buffer (on reçoit une « instance » de Image). • Afficher l’image (en remplaçant la précédente). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 99 Exercice n°6 – « Chargement d’images » : objectif
  • 100.
    | JavaScript – Manipulationdu DOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 100 Exercice n°6 – « Chargement d’images » : correction // Tableau de nos images var imgs = [{ src: "file:///C:/Users/user/Desktop/image1.jpeg", width: "256", height: "256" },{ src: "file:///C:/Users/user/Desktop/image2.jpg", width: "435", height: "474" },{ src: "file:///C:/Users/user/Desktop/image3.jpg", width: "330", height: "330" },{ src: "file:///C:/Users/user/Desktop/image4.jpg", width: "320", height: "330" } ];
  • 101.
    | JavaScript – Manipulationdu DOM Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 101 Exercice n°6 – « Chargement d’images » : correction // L’instanciation de Image, va automatiquement lancée une requête HTTP GET var imgBuffer = []; for (var i = 0, j = imgs.length; i < j; i++) { imgBuffer[i] = new Image(); imgBuffer[i].src = imgs[i].src; imgBuffer[i].width = imgs[i].width; imgBuffer[i].height = imgs[i].height; } // getRandNb retourne un objet Image // attribut de la méthode : valeur min, max => voir exercice précédent (compteur) var randomImg = getRandNb(0, preBuffer.length - 1); // Remplacer l’image existante var newImage = getRandomInt(0, imgBuffer.length - 1); var container = document.getElementById('container'); container.innerHTML = ''; container.appendChild(newImage);
  • 102.
    | JavaScript – Manipulationdu DOM • Analyser et comprendre le code existant (dispo sur l’espace partagé). • Améliorer l'interface utilisateur : par exemple, modifier l'état du bouton "Démarrer le jeu" après avoir démarrer une partie. • Le jeu devra gérer trois niveaux différents. Chaque niveau augmentant la complexité du puzzle et modifiant l'image de fond. • Le jeu devra garder les scores ainsi que les noms des joueurs par rapport au temps mis pour faire le puzzle et au nombre de mouvements réalisés. Il affichera les cinq meilleurs scores à la fin d'une partie, pour le niveau joué, dans un canevas (même principe que le texte de départ). Si les niveaux sont tous passés, afficher le classement global. • Soyez force de proposition ! Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 102 Exercice n°7 – « Puzzle glissant » : objectif Exercice noté Basé sur l’application de Brad Manderscheid développée pour TutsPlus.com
  • 103.
    | Le langage JavaScript AJAX Février 2016Formation ORT 3CSi - Guillaume MOREL-BAILLY 103
  • 104.
    | JavaScript – AJAX AsynchronousJavaScript And XML Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 104 Format d’échange de données en le client et le serveur. Historiquement du XML, puis progressivement remplacé par du JSON. On peut également échanger du texte brut. Une requête AJAX est asynchrone (non bloquante côté client). Le client écoute en parallèle une éventuelle réponse du serveur. Langage de script utilisé côté client pour initier les requêtes AJAX et éventuellement traiter la réponse du serveur. Manipulation du DOM pour mettre à jour le contenu. 1/ 2/ 3/
  • 105.
    | JavaScript – AJAX •AJAX n’est pas un langage mais une architecture qui fait appel à plusieurs technologies. • Permet de dynamiser tout ou partie d’une page web pour enrichir l’expérience utilisateur en ne forçant plus le rechargement complet d’une page. • Première apparition du terme « AJAX » en 2005 dans un article du Web Adaptive Path rédigé par l’architecte Jesse James Garrett. Depuis, AJAX a rapidement été adopté par les développeurs. • Le concept de rechargement dynamique d’une page web est apparu dés 1996 via l’utilisation d’iframe et de l’élément HTML layer (abandonné depuis) : souvent regroupé sous le terme DHTML. • Une solution plus élégante a été introduite par Microsoft en 1998 : MSRS (pour Microsoft Remote Scripting) qui fonctionnait via un applet Java auquel on pouvait donner dynamiquement des données par le biais d'un module JavaScript. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 105
  • 106.
    | JavaScript – AJAX •Microsoft a ensuite introduit l’objet XMLHttpRequest dans Internet Explorer 5 et dans Outlook Web Access (une sorte de webmail disponible avec Microsoft Exchange Server). • L’utilisation d’un applet Java dans MSRS a été remplacé par celui de l’objet XMLHttpRequest dans les années 2000. • Entre 2002 et 2005, l’objet XMLHttpRequest a été introduit dans le standard ECMAScript, le rendant utilisable par l’ensemble des navigateurs web du marché. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 106
  • 107.
    | JavaScript – AJAX Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 107 Modèle d’application web classique
  • 108.
    | JavaScript – AJAX Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 108 Modèle d’application web dynamique
  • 109.
    | JavaScript – AJAX Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 109 Modèle d’application web dynamique (or JSON)
  • 110.
    | JavaScript – AJAX •Objet natif de JavaScript pouvant être utilisé par l’ensemble des moteurs de script (car standardisé dans l’ECMAScript). • Cependant, il y a quelques différences d’implémentation selon le moteur et la version du navigateur de l’utilisateur. AJAX étant très demandé, c’est l’une des raisons pour laquelle jQuery a rapidement gagné en popularité. • XMLHttpRequest permet d'envoyer des requêtes synchrones ou asynchrones en HTTP. Mais il est généralement utilisé que pour l’envoi de requêtes asynchrones (c’est là tout son intérêt). • Donc l’objet XMLHttpRequest != AJAX (qui est une architecture, un semble de technologies). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 110 L’objet XMLHttpRequest
  • 111.
    | JavaScript – AJAX •XMLHttpRequest permet d'envoyer des requêtes HTTP (GET, POST, PUT, etc.) de manière très simple. Il suffit de créer une instance de l'objet, d’attacher éventuellement une fonction de callback, de lier une URL, et d'envoyer la requête. • Il existe plusieurs fonctions natives que nous allons voir dans les slides suivants. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 111 L’objet XMLHttpRequest
  • 112.
    | JavaScript – AJAX •Les navigateurs modernes (Chrome, IE 7+, Firefox, etc.) supportent l’objet XMLHttpRequest. On abordera pas la gestion de l’AJAX pour les anciennes versions de ces navigateurs. • La syntaxe pour créer un objet XMLHttpRequest est la suivante : • A partir de cette instance, on peut utiliser les fonctions de XMLHttpRequest. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 112 L’objet XMLHttpRequest – Création d’un objet var xhttp = new XMLHttpRequest();
  • 113.
    | JavaScript – AJAX •Pour envoyer une requête HTTP à un serveur, on utilise les fonctions open() et send(). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 113 L’objet XMLHttpRequest – Envoyer une requête à un serveur xhttp.open('POST', 'foo.php', true); xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); // Optionnel Xhttp.send('firstName=John&lastName=Doe'); Fonction Description open(method, url, async) Spécifie le type de requête HTTP. send() Envoi la requête à un serveur. send(string) Envoi la requête à un serveur et transmet des données (typiquement, pour une requête HTTP de type POST).
  • 114.
    | JavaScript – AJAX •Si une requête asynchrone (c’est-à-dire non bloquante) a été initiée, il faut spécifier la fonction JavaScript qui sera appelée lors de la réponse du serveur. C’est ce qu’on appelle une fonction de callback. • On utilisera l’évènement onreadystatechange de l’objet XMLHttpRequest Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 114 L’objet XMLHttpRequest – Recevoir une requête du serveur xhttp.onreadystatechange = function() { if (xhttp.readyState == 4 && xhttp.status == 200) { var response = xhttp.responseText; } }; xhttp.open("GET", "foo.php", true); xhttp.send(); Réponse retournée par le serveur Utiliser xhttp.responseXML si du XML est retourné par le serveur.
  • 115.
    | JavaScript – AJAX PropriétéDescription / valeurs onreadystatechange Enregistre une fonction qui devra être appelée automatiquement à chaque fois que la propriété readyState change. Généralement on passe une fonction anonyme. readyState Statut de la requête XMLHttpRequest : 0 : request not initialized 1 : server connection established 2 : request received 3 : processing request 4 : request finished and response is ready status 200 : « OK » 404 : Page non trouvée Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 115 L’objet XMLHttpRequest – Recevoir une requête du serveur
  • 116.
    | JavaScript – AJAX •On a vu qu’on pouvait utiliser l’évènement onreadystatechange ainsi que la propriété readyState pour surveiller la progression d’une requête asynchrone. • Une évolution de l’API permet maintenant d’utiliser la fonction addEventListener (implémentant l’interface ProgressEvent) pour intercepter les notifications de progression périodiques, de notifications d’erreur, etc. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 116 L’objet XMLHttpRequest – Recevoir une requête du serveur oReq.addEventListener("progress", updateProgress, false); oReq.addEventListener("load", transferComplete, false); oReq.addEventListener("error", transferFailed, false); oReq.addEventListener("abort", transferCanceled, false); oReq.open();
  • 117.
    | JavaScript – AJAX •Historiquement le format XML était utilisé pour échanger des données entre le client et le serveur. • Cependant ce format est lourd et difficile à parser en JavaScript. • JSON (JavaScript Object Notation) est un format de données léger destiné à la transmission de données. Il est indépendant de tout langage, bien qu’il se rapproche de la syntaxe objet de JavaScript. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 117 XML ou JSON ?
  • 118.
    | JavaScript – AJAX Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 118 XML ou JSON ? {"employees":[ {"firstName":"John", "lastName":"Doe"}, {"firstName":"Anna", "lastName":"Smith"}, {"firstName":"Peter", "lastName":"Jones"} ]} <employees> <employee> <firstName>John</firstName> <lastName>Doe</lastName> </employee> <employee> <firstName>Anna</firstName> <lastName>Smith</lastName> </employee> <employee> <firstName>Peter</firstName> <lastName>Jones</lastName> </employee> </employees>
  • 119.
    | JavaScript – AJAX •L'objet natif JSON contient des méthodes pour convertir des valeurs en JSON et pour convertir des données JSON en valeurs JavaScript. • La méthode JSON.stringify() permet de convertir une valeur en JSON, et éventuellement de remplacer des valeurs grâce à une fonction de remplacement ou en ne filtrant que certaines propriétés données. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 119 XML ou JSON ? JSON.stringify({}); // '{}' JSON.stringify(true); // 'true' JSON.stringify("toto"); // '"toto"' JSON.stringify({x: 5, y: 6}); // '{"x":5,"y":6}'
  • 120.
    | JavaScript – AJAX •La méthode JSON.parse() interprète une chaîne de caractères comme du JSON, transformant de façon optionnelle la valeur produite et ses propriétés, puis retourne la valeur. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 120 XML ou JSON ? var text = '{"name":"John Johnson","street":"Oslo West 16","phone":"555 1234567"}'; var obj = JSON.parse(text); document.getElementById("demo").innerHTML = obj.name + "<br>" + obj.street + "<br>" + obj.phone;
  • 121.
    | JavaScript – AJAX •L’architecture AJAX est utilisée massivement dans les sites et applications web. Généralement utilisée pour dynamiser quelques éléments comme la validation et l’envoi d’un formulaire, la pagination d’éléments, etc. • On développe également des applications « full-ajax » : le code peut devenir vite complexe, lourd, difficile à maintenir. • D’autres technologies ont émergées en remplacement ou complément de Ajax, par exemple les WebSocket ou le concept de « binding » (pour lier de manière automatique un élément du DOM à une source de données) utilisé par exemple par AngularJS ou EmberJS. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 121 AJAX : Aujourd’hui et demain
  • 122.
    | Le langage JavaScript Concepts avancés Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 122
  • 123.
    | JavaScript – Conceptsavancés • La portée est un des éléments fondamentaux de JavaScript, et peut être le plus difficile à maitriser car il diffère beaucoup des autres langages de programmation. La portée s’applique aux variables comme aux fonctions. • Afin d'utiliser une fonction, il est nécessaire de l'avoir auparavant définie au sein de la portée dans laquelle on souhaite l'appeler. • On ne peut pas accéder aux variables définies dans une fonction en dehors de cette fonction : ces variables n'existent que dans la portée de la fonction. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 123 Fonctions : portée
  • 124.
    | JavaScript – Conceptsavancés • En revanche, une fonction peut accéder aux différentes variables et fonctions qui appartiennent à la portée dans laquelle elle est définie. • Une fonction définie dans une autre fonction peut également accéder à toutes les variables de la fonction « parente » et à toute autre variable accessible depuis la fonction « parente ». Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 124 Fonctions : portée
  • 125.
    | Fonctions : portée Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 125 JavaScript – Concepts avancés // The following variables are defined in // the global scope var num1 = 20, num2 = 3, name = "Licorne"; // This function is defined in the global scope function multiply() { return num1 * num2; } multiply(); // Returns 60 // A nested function example function getScore () { var num1 = 2, num2 = 3; function add() { return name + " scored " + (num1 + num2); } return add(); } getScore(); // Returns "Chamahk scored 5"
  • 126.
    | JavaScript – Conceptsavancés • Comme on l’a vu, JavaScript permet d'imbriquer des fonctions et la fonction interne aura accès aux variables et paramètres de la fonction parente. À l'inverse, la fonction parente ne pourra pas accéder aux variables liées à la fonction interne. • On crée ce qu’on appelle une closure (fermeture en français) lorsque la fonction interne est disponible en dehors de la fonction parente. • Une closure est un objet spécial qui combine : une fonction + l’environnement dans lequel la fonction a été créée. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 126 Fonctions : closures
  • 127.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 127 Fonctions : closures var animal = function(nom) { // La fonction externe utilise un paramètre "nom" var getNom = function () { // La fonction interne accède à la variable "nom" de la fonction externe return nom; } // Renvoie la fonction interne pour la rendre disponible // en dehors de la portée de la fonction parente return getNom; } monAnimal = animal("Licorne"); monAnimal(); // Renvoie "Licorne" Exemple 1 :
  • 128.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 128 Fonctions : closures function createFunction() { var name = "Hello"; function displayName() { alert(name); } return displayName; }; var myFunction = createFunction(); myFunction(); Exemple 2 : • L'intérêt de ce code est que la fonction displayName() a été renvoyée depuis la fonction parente avant d'être exécutée. • Normalement, les variables locales d'une fonction n'existent que pendant l'exécution d'une fonction. Une fois que createFunction() aura fini son exécution, on peut penser que la variable name ne sera plus accessible.
  • 129.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 129 Fonctions : closures function createFunction() { var name = "Hello"; function displayName() { alert(name); } return displayName; }; var myFunction = createFunction(); myFunction(); • Cependant, le code continue à fonctionner : la variable est donc accessible d'une certaine façon. • La solution est la suivante : createFunction est devenue une closure.
  • 130.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 130 Fonctions : closures function createFunction() { var name = "Hello"; function displayName() { alert(name); } return displayName; }; var myFunction = createFunction(); myFunction(); • Pour rappel : closure = fonction + environnement dans lequel la fonction a été créée. • L'environnement est composé de toutes les variables locales de la portée présente lorsque la fermeture a été créée. • Ici myFunction est une fermeture qui contient la fonction displayName et la chaîne de caractères "Hello" qui existait lorsque la closure a été créée.
  • 131.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 131 Fonctions : closures function faireAddition(x) { return function(y) { return x + y; }; }; var ajout5 = faireAddition(5); var ajout10 = faireAddition(10); console.log(ajout5(2)); // 7 console.log(ajout10(2)); // 12 Exemple 3 : • faireAddition permet de créer d'autres fonctions (qui font la somme de leur argument et d'un nombre fixe). • On crée deux fonctions, la première qui ajoute 5 à l'argument et la deuxième qui ajoute 10. • ajout5 et ajout10 sont des closures. Ils partagent la même définition de fonction mais des environnements différents. • Dans l'environnement de ajout5, x vaut 5. Pour ajout10, x vaut10.
  • 132.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 132 Fonctions : closures function getCounter() { var i = 0; return function () { return i++; } } var counter1 = getCounter(); var counter2 = getCounter(); console.log(counter1()); // 1 console.log(counter1()); // 2 console.log(counter2()); // 1 console.log(counter2()); // 2 console.log(counter1()); // 3 console.log(counter1()); // 4 Exemple 4 :
  • 133.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 133 Fonctions : closures var sayHello = function (name) { var text = 'Hello, ' + name; return function () { console.log(text); }; }; sayHello('Todd'); Exemple 5 : que fait ce code ?
  • 134.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 134 Fonctions : closures var sayHello = function (name) { var text = 'Hello, ' + name; return function () { console.log(text); }; }; var helloTodd = sayHello('Todd'); helloTodd(); // will call the closure and log 'Hello, Todd' Exemple 5 : que fait ce code ?
  • 135.
    | JavaScript – Conceptsavancés Exercice d’application : • Soit le code HTML suivant : • Créer un script qui permette de changer le texte d’aide (par défaut « Des aides seront affichées ici ») au clic sur un champ input. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 135 Fonctions : closures <span id="helper">Des aides seront affichées ici</span> <p>Email : <input type="text" id="email" /></p> <p>Nom : <input type="text" id="name" /></p> <p>Âge : <input type="text" id="age" /></p>
  • 136.
    | JavaScript – Conceptsavancés • Dans une fonction JavaScript on aura l’objet suivant : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 136 Fonctions : closures var helpers = [ {'id': 'email', 'helper': 'Votre adresse e-mail'}, {'id': 'name', 'helper': 'Votre prénom et nom'}, {'id': 'age', 'helper': 'Votre age (vous devez avoir au moins 18 ans)'} ]; • Aide : faire une boucle sur cet objet et manipuler le DOM avec la fonctions document.getElementById() pour sélectionner un élément HTML via son id. Utiliser « innerHTML » pour modifier le contenu d’un élément, et onfocus pour créer un évènement au focus.
  • 137.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 137 function showHelp(help) { document.getElementById('helper').innerHTML = help; } function setupHelp() { var helpText = [ {'id': 'email', 'helper': 'Votre adresse e-mail'}, {'id': 'name', 'helper': 'Votre prénom et nom'}, {'id': 'age', 'helper': 'Votre age (vous devez avoir au moins 18 ans)'} ]; for (var i = 0; i < helpText.length; i++) { var item = helpText[i]; document.getElementById(item.id).onfocus = function() { showHelp(item.helper); } } } setupHelp();
  • 138.
    | JavaScript – Conceptsavancés • Problème : le code précédent ne fonctionne pas. Quelque soit le champ sur lequel on se situe, le message d'aide concernant l'âge est le seul qui s'affiche. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 138 Fonctions : closures
  • 139.
    | JavaScript – Conceptsavancés • Explications : les fonctions attachées aux gestionnaires d'événements sont des closures et que l'environnement qui leur est rattaché est le même pour les trois : il provient de la portée de la fonction setupHelp. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 139 Fonctions : closures function setupHelp() { ... for (var i = 0; i < texteAide.length; i++) { var item = helpText[i]; document.getElementById(item.id).onfocus = function() { showHelp(item.helper); } } } Closure
  • 140.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 140 Fonctions : closures function makeHelpCallback(help) { return function() { showHelp(help); }; } function setupHelp() { ... for (var i = 0; i < helpText.length; i++) { var item = helpText[i]; document.getElementById(item.id).onfocus = makeHelpCallback(item.help); } }
  • 141.
    | JavaScript – Conceptsavancés • On ne peut pas accéder aux variables définies dans une fonction en dehors de cette fonction : ces variables n'existent que dans la portée de la fonction. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 141 Portée des fonctions et variables // code here can not use carName function myFunction() { var carName = "Volvo"; // code here can use carName console.log(carName); // Volvo } console.log(carName); // Uncaught ReferenceError: carName is not defined
  • 142.
    | JavaScript – Conceptsavancés • Si on assigne une valeur à une variable qui n’a pas été déclarée (avec var), cette variable aura automatiquement une portée globale. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 142 Portée des fonctions et variables // code here can use carName function myFunction() { carName = "Volvo"; // code here can use carName }
  • 143.
    | JavaScript – Conceptsavancés • Une fonction peut accéder aux différentes variables et fonctions qui appartiennent à la portée dans laquelle elle est définie. • Une variable déclarée en dehors d’une fonction a une portée globale. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 143 Portée des fonctions et variables var carName = "Volvo"; // code here can use carName function myFunction() { // code here can use carName }
  • 144.
    | JavaScript – Conceptsavancés • Une fonction définie dans une autre fonction (= closure) peut également accéder à toutes les variables de la fonction « parente » et à toute autre variable accessible depuis la fonction « parente ». Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 144 Portée des fonctions et variables
  • 145.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 145 Portée des fonctions et variables // Variables globales var num1 = 20, num2 = 3, nom = "Licorne"; // Fonction définie dans la portée globale function multiplier() { return num1 * num2; } multiplier(); // Renvoie 60 function getScore () { var num1 = 2, num2 = 3; function ajoute() { return nom + " a marqué " + (num1 + num2); } return ajoute(); } getScore(); // "Licorne a marqué 5"
  • 146.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 146 Portée et this var myFunction = function () { console.log(this); // this = global, [object Window] }; myFunction(); var myObject = {}; myObject.myMethod = function () { console.log(this); // this = Object { myObject } }; var nav = document.querySelector('.nav'); // <nav class="nav"> var toggleNav = function () { console.log(this); // this = <nav> element }; nav.addEventListener('click', toggleNav, false);
  • 147.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 147 Portée et this var nav = document.querySelector('.nav'); // <nav class="nav"> var toggleNav = function () { console.log(this); // <nav> element setTimeout(function () { console.log(this); // [object Window] }, 1000); }; nav.addEventListener('click', toggleNav, false); • Même au sein de la même fonction, le scope peut être changé et la valeur de this peut l’être également.
  • 148.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 148 Portée et this var nav = document.querySelector('.nav'); // <nav class="nav"> var toggleNav = function () { var that = this; console.log(that); // <nav> element setTimeout(function () { console.log(that); // <nav> element }, 1000); }; nav.addEventListener('click', toggleNav, false); • Même au sein de la même fonction, le scope peut être changé et la valeur de this peut l’être également.
  • 149.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 149 Créer un scope privé (function () { var myFunction = function () { // do some stuff here }; })(); myFunction(); // Uncaught ReferenceError: myFunction is not defined
  • 150.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 150 Module Pattern : namespace + scope privé et public // Définition du module var Module = (function () { var privateMethod = function () { ... }; return { myMethod: function () { console.log('myMethod has been called.'); }, someOtherMethod: function () { ... } }; })(); // call module + methods Module.myMethod();
  • 151.
    | JavaScript – Conceptsavancés • L'élévation est peut-être l'élément le plus surprenant et celui qui peut causer le plus de soucis en termes de portée. Le hoisting est fait de manière transparente par JavaScript. • La principale chose à garder en mémoire est la suivante (pour ECMAScript 5) : pour toute définition d'une variable, il y a une déclaration de cette variable au début de sa portée et une affectation à l'endroit de sa définition. • Les déclarations de fonctions sont également remontées dans le code. Par contre ce n’est pas le cas des expression de fonctions. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 151 Hoisting (élévation)
  • 152.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 152 Hoisting (élévation) var state; // variable declaration state = "ready"; // variable definition (assignment) var state = "ready"; // declaration plus definition • Il faut toujours visualiser une variable comme étant constituée de deux parties : la déclaration puis la définition.
  • 153.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 153 Hoisting (élévation) • On a vu qu’une variable déclarée dans un scope appartient à ce scope (cette portée). • Mais ce qu’on a pas encore vu, c’est que peut importe où la variable est déclarée dans ce scope, toutes les déclarations de variables sont remontées en haut de leur scope (global ou local). C’est ce qu’on appel l’élévation. • Note : l’élévation déplace seulement la déclaration de la variable. L’assignement n’est pas déplacé. console.log(state); // output: undefined var state = "ready"; var state; // moved to the top console.log(state); state = "ready"; // left in place
  • 154.
    | JavaScript – Conceptsavancés • JavaScript peut parfois se révéler déroutant, notamment pour les développeurs habitués à des langages fonctionnant avec des classes. • JavaScript ne fournit pas d'implémentation de classe. • Le mot-clé class a été introduit avec ECMAScript 6 mais ne fournit qu'un sucre syntaxique, JavaScript continue d'avoir un modèle d'héritage basé sur les prototypes. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 154 Prototypes : présentation
  • 155.
    | JavaScript – Conceptsavancés • Mais alors, quid de l’héritage ? • Dès lors qu'on aborde l'héritage, JavaScript n'utilise qu'un seul concept : les objets (souvenez- vous, tout est objet en JavaScript !). • Chaque objet possède un lien, interne, vers un autre objet, appelé prototype. • Cet objet prototype possède lui aussi un prototype et ainsi de suite, jusqu'à ce que l'on aboutisse à un prototype null. null, n'a, par définition, aucun prototype et forme donc le dernier maillon de la chaîne des prototypes. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 155 Prototypes : présentation
  • 156.
    | JavaScript – Conceptsavancés • On sait déjà que les objets JavaScript sont des conteneurs de propriétés. On vient de voir que chaque objet possède un lien vers un objet prototype. • Lorsqu'on souhaite accéder à une propriété d'un objet, on recherche : • d'abord parmi les propriétés propres de l'objet, • puis parmi celles de son prototype, • puis parmi celle du prototype du prototype, • et ainsi de suite jusqu'à ce qu'une propriété correspondante soit trouvée ou qu'on ait atteint la fin de la chaîne de prototypes. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 156 Prototypes : héritage de propriété
  • 157.
    | JavaScript – Conceptsavancés • En JavaScript, toute fonction peut être rattachée à un objet en tant que propriété. • Une fonction héritée agit comme n'importe quelle autre propriété (voir slide précédent). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 157 Prototypes : héritage de fonctions
  • 158.
    | JavaScript – Conceptsavancés • Le but est de créer la chaine de prototypes suivante : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 158 Prototypes : héritage de fonctions
  • 159.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 159 Prototypes : héritage de fonctions Animal = function(name) { this.name = name; } Animal.prototype.eats = function() { return this.name + " is eating"; } Chordate = function(name) { this.name = name; } Chordate.prototype = new Animal(); Chordate.prototype.has_spine = true; Mammal = function(name) { this.name = name; } Mammal.prototype = new Chordate(); Mammal.prototype.has_hair = true; m = new Mammal('cat');
  • 160.
    | JavaScript – Conceptsavancés • Remarque : lorsqu'une fonction héritée est exécutée, la valeur de this pointe vers l'objet qui hérite. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 160 Prototypes : héritage de fonctions (et portée) var o = { a: 2, m: function(b){ return this.a + 1; } }; console.log(o.m()); // 3 // Appelle de o.m : 'this' fait référence à o var p = Object.create(o); // p est un objet héritant de o p.a = 12; // crée une propriété 'a' pour p console.log(p.m()); // 13 // lorsque p.m est appelé, 'this' fait référence à p.
  • 161.
    | JavaScript – Conceptsavancés (mémoire) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 161 Références var me = { name: { first: "John" } }; var foo = me.name; foo = {first: "Alexis"}; console.log(me.name.first);
  • 162.
    | JavaScript – Conceptsavancés (mémoire) • var str : on déclare simplement un pointeur. La valeur de str est pour l’instant sur undefined • str = "hi" : on prend un pointeur et on lui assigne une adresse sur cette variable en mémoire Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 162 Références
  • 163.
    | JavaScript – Conceptsavancés (mémoire) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 163 Références var obj = {}; obj.txt = "hi";
  • 164.
    | JavaScript – Conceptsavancés (mémoire) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 164 Références var obj = {}; obj.txt = "hi";
  • 165.
    | JavaScript – Conceptsavancés (mémoire) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 165 Références var obj = {}; obj.txt = "hi";
  • 166.
    | JavaScript – Conceptsavancés (mémoire) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 166 L’opérateur delete var me = { name: { first: "Justin" } }, foo = me.name; delete me.name; console.log(foo.first); window me name first "justin"
  • 167.
    | JavaScript – Conceptsavancés (mémoire) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 167 L’opérateur delete var me = { name: { first: "Justin" } }, foo = me.name; delete me.name; console.log(foo.first); window me name first "justin" foo
  • 168.
    | JavaScript – Conceptsavancés (mémoire) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 168 L’opérateur delete var me = { name: { first: "Justin" } }, foo = me.name; delete me.name; console.log(foo.first); window me first "justin" foo
  • 169.
    | JavaScript – Conceptsavancés (mémoire) • L'opérateur delete permet de retirer une propriété d'un objet. • Contrairement à ce qu'on pourrait croire, l'opérateur delete n'a strictement rien à voir avec de la libération de mémoire directe  il ne libère la mémoire qu'indirectement, en supprimant des références. • Si l'opération de delete est bien effectuée, la propriété sera retirée de l'objet. • Remarque : delete fonctionne uniquement pour les propriétés d'un objet. Il n'a aucun effet sur les variables ou les noms de fonctions. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 169 L’opérateur delete
  • 170.
    | JavaScript – Conceptsavancés (mémoire) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 170 Références (suite) var me = { name: { first: "Justin" } }, foo = me.name; window me name first "Justin" foo
  • 171.
    | JavaScript – Conceptsavancés (mémoire) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 171 Références (suite) var me = { name: { first: "Justin" } }, foo = me.name; foo = { first: “Alexis" } window me name first "Justin" foo first "Alexis"
  • 172.
    | JavaScript – Conceptsavancés 21 undefined undefined 21 {} NaN true Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 172 Les opérateurs de comparaison expliqués "21" null null 21 {} NaN {valueOf: function() {return "1"}} == == === === === === == vrai vrai faux vrai faux faux vrai
  • 173.
    | JavaScript – Conceptsavancés • Opérateur === avec des types primitifs. • Ce code va rechercher ces deux primitifs en mémoire et va chercher à comparer leurs valeurs. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 173 Les opérateurs de comparaison expliqués var str1 = "hi"; var str2 = "hi"; str1 === str2 vrai Adresse Valeur … … x1001 call-object x1002 str1 x1003 x2001 x1004 str2 x1005 x2101 … … x2001 STRING x2002 hi … … x2101 STRING x2102 hi
  • 174.
    | JavaScript – Conceptsavancés • Opérateur === avec des objets. • Ce code va rechercher ces deux objets en mémoire et va comparer leurs pointeurs (car ce ne sont pas des primitifs). C’est une comparaison « par référence ». Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 174 Les opérateurs de comparaison expliqués var obj1 = {}; var obj2 = {}; obj1 === obj2 faux Adresse Valeur … … x1001 call-object x1002 obj1 x1003 x2001 x1004 obj2 x1005 x2101 … … x2001 OBJECT x2002 0 … … x2101 OBJECT x2102 0
  • 175.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 175 Les opérateurs de comparaison expliqués – x == y Types identiques ? Tous les deux null ou undefined ? string == number ? boolean == anything ? Object == string ou Number ? === true == == false
  • 176.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 176 true == ({toString: function() {return "1"}}) Types identiques ? Tous les deux null ou undefined ? string == number ? boolean == anything ? Object == string ou Number ? === true 1 == ({toString: function(){return "1"}}) == false
  • 177.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 177 1 == ({toString: function() {return "1"}}) Types identiques ? Tous les deux null ou undefined ? string == number ? boolean == anything ? Object == string ou Number ? === true false 1 == "1" ==
  • 178.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 178 1 == "1" Types identiques ? Tous les deux null ou undefined ? string == number ? boolean == anything ? Object == string ou Number ? === true 1 == 1 == false
  • 179.
    | JavaScript – Conceptsavancés Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 179 1 == 1 Types identiques ? Tous les deux null ou undefined ? string == number ? boolean == anything ? Object == string ou Number ? true == false === == C’est pour ça que le comparateur == est gourmand en performance ! Il faut plutôt privilégier l’opérateur ===.
  • 180.
    |Février 2016 FormationORT 3CSi - Guillaume MOREL-BAILLY 180
  • 181.
    Partie 2 Développer avecjQuery Write less, do more
  • 182.
    | jQuery – Présentation •jQuery est une bibliothèque JavaScript open-source et multi-plateforme créée entre autre pour faciliter la manipulation du DOM, la gestion des évènements et l’utilisation de l’Ajax. • On peut étendre les fonctionnalités de jQuery par l’ajout du plugins. Il existe par exemple plusieurs centaines de plugins permettant d’implémenter une galerie d’image. • Première version lancée par John Resig en 2006. • On distingue 2 branches en production : • version 1.x (dernière en date 1.12.0) : support anciennes version IE • version 2.x (dernière en date 2.2.0) : plus légère Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 182
  • 183.
    | Avantages • Facilite grandementla manipulation du DOM (l’utilisation de l’API document par JavaScript reste compliquée dés qu’il s’agit de manipuler des éléments précis du DOM). • On écrit souvent 2x moins de lignes de codes avec jQuery qu’en JavaScript natif. Gain de temps; maintenabilité accrue; etc. • Plugins : éviter de réinventer la roue ! Inconvénients • jQuery est une couche d’abstraction à JavaScript, si bien que certains développeurs « développent » en jQuery sans même connaitre JavaScript.  peut être problématique. • Nécessite de charger la bibliothèque (qui est de plus en plus lourde au fil du temps…). • Passer par les fonctions natives du langages JavaScript sera toujours plus rapide (en terme de charge / temps d’exécution). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 183 jQuery – Présentation
  • 184.
    | jQuery – Présentation •jQuery UI : collection d'éléments utiles dans le développement d'une interface utilisateur riche et interactive. La bibliothèque est découpée en 4 parties complémentaires : interactions (par exemple gestion du drag’n’drop), widgets (Datepicker, ProgressBar, Slider…), effets et les thèmes. jQuery UI a passé son âge d’or… il est en perte de vitesse depuis. On recommandera plutôt d’utiliser des fameworks UI en HTML5 (comme Bootstrap). • jQuery Mobile : première version sortie en octobre 2010, permet de développer facilement des interfaces mobiles. La bibliothèque a perdu de son intérêt depuis l’apparition de frameworks mobiles « modernes » plus performants. PhoneGap le maintien en vie. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 184 Projets connexes
  • 185.
    | jQuery – Présentation •En fonction du projet sur lequel vous travaillez et des impératifs du cahier des charges (support des anciens navigateurs, ou utilisation d’un plugin jQuery basé sur une ancienne version, etc. ?), choisissez la version de jQuery correspondante. • Pour de nouveaux projets « from scratch », on conseillera la branche 2.x. • Chargement de la bibliothèque (version minifiée) en local ou via un CDN. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 185 Chargement de la bibliothèque <script src="jquery.min.js"></script> <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
  • 186.
    | jQuery – Sélecteurs •Les sélecteurs jQuery permettent de sélectionner des éléments du DOM sur lesquels on souhaite effectuer des opérations (par exemple récupérer la valeur d’un champ input, ou changer l’opacité d’un div). • En JavaScript natif on passe par l’API document qui permet l’accès et la manipulation directe du DOM. Cette API fournit des méthodes comme getElementById() ou getElementsByTagName() qui sont pratiques pour sélectionner des éléments simples et précis. Pour des usages plus poussés, ces méthodes montrent vite leurs limites. • jQuery permet de sélectionner très facilement des éléments du DOM en utilisant la fonction $(). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 186
  • 187.
    | jQuery – Sélecteurs •La fonction $() n’est en fait qu’un alias vers la fonction jQuery(). • La fonction $() créé un nouveau objet jQuery qui référence le(s) élément(s) sélectionné(s). • Note : on peut également utiliser des fonctions de jQuery sans forcément sélectionner un élément du DOM en amont. C’est par exemple le cas de $.ajax(). • Syntaxe de base : $(selector).action(); • Le sélecteur peut être vue comme une requête de sélection permettant d’identifier le ou les éléments HTML à manipuler. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 187
  • 188.
    | jQuery – Sélecteurs •Tout est question de contexte. • Par défaut, les sélecteurs effectuent leurs recherchent dans le DOM à partir de la racine du document (la page web). Toutefois, un contexte alternatif peut être donné en utilisant le second attribut optionnel de la fonction $(). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 188 $("div.foo").click(function() { $("span").addClass("bar"); }); $("div.foo").click(function() { $("span", this).addClass("bar"); }); Recherche d’un élément « span » dans le DOM à partir de la racine du document. Recherche d’un élément « span » dans le DOM à partir du nœud div.foo. C’est-à-dire que seul les éléments span enfants de .foo seront sélectionnés.
  • 189.
    | jQuery – Sélecteurs •En interne, la sélection d’un contexte différent est implémenté avec la fonction .find(). • Donc $("span", this) est équivalent à $(this).find("span"). • De la même manière, on peut passer un sélecteur en 2nd argument : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 189 // Sélectionner tous les éléments p enfant de #bar $("p", "#bar"); // Equivalent à : $("#bar").find("p");
  • 190.
    | jQuery – Sélecteurs Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 190 Sélecteur Exemple Sélectionnera… this $(this) L’élément courant * $("*") Tous les éléments de la page #id $("#foo") Les éléments avec l’id “foo" .class $(".foo") Les éléments avec la classe “foo" .class,.class $(".foo, .bar") Tous les éléments avec la classe “foo" ou “bar" element $("p") Tous les éléments <p> el1,el2,el3 $("h1, div, p") Tous les éléments <h1>, <div> et <p> :first $("p:first") Le premier élément <p> :last $("p:last") Le dernier élément <p> :even $("tr:even") Tous les éléments <tr> pairs (even)
  • 191.
    | jQuery – Sélecteurs Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 191 Sélecteur Exemple Sélectionnera… parent > child $("div > p") Tous les éléments <p> qui sont enfant direct d’un élément <div> parent descendant $("div p") Tous les éléments <p> qui sont descendant d’un élément <div> element + next $("div + p") Le premier élément <p> qui sera à la suite d’éléments <div> :focus $(":focus") L’élément qui a actuellement le focus :contains(text) $(":contains('Hello')") Tous les éléments qui contiennent le texte « Hello » :has(selector) $("div:has(p)") Tous les éléments <div> qui ont un élément <p> :empty $(":empty") Tous les éléments vides :parent $(":parent") Tous les éléments qui sont parents d’un autre élément :hidden $("p:hidden") Tous les éléments <p> qui sont cachés (visibilité) :visible $("table:visible") Tous les éléments <table> qui sont visibles
  • 192.
    | jQuery – Sélecteurs Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 192 Sélecteur Exemple Sélectionnera… [attribute] $("[href]") Tous les éléments avec un attribut href [attribute=value] $("[href=‘foo.htm']") Tous les élements avec un attribut href égal à “foo.htm" [attribute!=value] $("[href!=‘foo.htm']") Tous les éléments avec un attribut href different de “foo.htm" [attribute$=value] $("[href$='.jpg']") Tous les éléments avec un attribut href finissant par ".jpg" [attribute^=value] $("[title^='Tom']") Tous les éléments avec un attribut titre commençant par "Tom" [attribute*=value] $("[title*=‘foo']") Tous les éléments avec un attribute titre contenant le mot “foo"
  • 193.
    | jQuery – Sélecteurs Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 193 Sélecteur Exemple Sélectionnera… :input $(":input") Tous les éléments input :text $(":text") Tous les éléments input de type "text" :checkbox $(":checkbox") Tous les éléments input de type "checkbox" :submit $(":submit") Tous les éléments input de type "submit" :enabled $(":enabled") Tous les éléments input activés :disabled $(":disabled") Tous les éléments input désactivés :selected $(":selected") Tous les éléments input sélectionnés :checked $(":checked") Tous les éléments input cochés
  • 194.
    | jQuery – Sélecteurs •Soit le code HTML ci-dessous, sélectionner en jQuery le titre de niveau h1 et passer le texte en majuscule (vous pouvez utiliser la fonction css() pour manipuler les styles). Sélectionner le premier élément li de la liste et passer le texte en rouge. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 194 Exercice d’application rapide <div id=wrapper> <h1>Lorem ipsum dolor sit amet</h1> <p>Un paragraphe de test</p> <ul> <li>Element 1</li> <li>Element 2</li> <li>Element 3</li> </ul> </div>
  • 195.
    | jQuery – Sélecteurs Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 195 Exercice d’application rapide <div id="wrapper"> <h1>Lorem ipsum dolor sit amet</h1> <p>Un paragraphe de test</p> <ul> <li>Element 1</li> <li>Element 2</li> <li>Element 3</li> </ul> </div> <script> $(function() { // ou $(document).ready(function() { $('h1').css('text-transform', 'uppercase'); $('li:first-child').css('color', 'red'); }); </script> Bien penser à charger jQuery dans vote page !
  • 196.
    | jQuery – Lafonction $() (notion avancée) • Nous avons vu que la fonction $() permet de sélectionner un ou des éléments du DOM en fonction d’une requête. • On peut aussi utiliser la fonction $() avec les objets JavaScript natifs. • Dans ce cas, seules les fonctions jQuery data(), prop(), on() et trigger() sont disponibles. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 196 // Define a plain object var foo = { foo: "bar", hello: "world" }; // Pass it to the jQuery function var $foo = $(foo); // Test accessing property values var test1 = $foo.prop("foo"); // bar
  • 197.
    | jQuery – Lafonction $() (notion avancée) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 197 // Execute la fonction quand le DOM est prêt à être utilisé // C’est-à-dire quand la page sera entièrement chargée $(function() { // Document is ready }); • Dernier usage de la fonction $() : l’utilisation d’une fonction de callback. // Utilisation d’un alias (exemple d’utilisation: utilise lorsqu’on travaille avec WordPress, ou seul // le mot clé jQuery est disponible jQuery(function( $ ) { // On peut maintenant utiliser le signe $ comme alias à la function "jQuery" });
  • 198.
    | jQuery – Lafonction $() (notion avancée) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 198 $(document).ready(function(){ // Document is ready }); • La fonction $(function() { ... }); est équivalente à la notation :
  • 199.
    | jQuery – L’objetjQuery (notion avancée) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 199 • Quand la fonction jQuery (ou l’alias $) est invoquée avec une sélecteur CSS, elle retournera un objet jQuery enveloppant tout élément(s) correspondant à ce sélecteur. Une « collection » est retournée. Attention, ce n’est pas un array JavaScript ! • Par exemple, en écrivant : var headings = $("h1"); • La variable headings est maintenant un élement jQuery contenant tous les éléments <h1> de la page au moment où la ligne a été interprétée par JavaScript. On peut vérifier ça en appelant la propriété length : alert(headings.length);
  • 200.
    | jQuery – L’objetjQuery (notion avancée) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 200 • La fonction eq() permet de retourner un élément précis de la collection jQuery : var firstHeading = headings.eq( 0 ); • La fonction get() permet de retourner un élément DOM précis de la collection jQuery. Donc au lieu de retourner un élément du DOM « jQuerisé », on retourne l’élement DOM lui-même (comme on l’aurait fait avec les fonctions de sélection natives de JavaScript) : var firstHeadingElem = $( "h1" ).get( 0 ); • Par contre on ne peut plus utiliser les fonctions natives de jQuery sur cette variable.
  • 201.
    | jQuery – L’objetjQuery (notion avancée) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 201 • Détail important : à chaque sélection d’un élément, un objet jQuery différent est retourné (même si cet objet fait référence au même élément du DOM). // Créé 2 objets jQuery totalement distinct pour le même élément var logo1 = $("#logo"); var logo2 = $("#logo"); // Pour s’en assurer, on peut comparer ces objets : console.log(logo1 === logo2); // false • Par contre, ils contiennent (référencent) le même élément DOM : var logo1Elem = logo1.get(0); var logo2Elem = logo2.get(0); console.log(logo1Elem === logo2Elem); // true
  • 202.
    | jQuery – L’objetjQuery (notion avancée) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 202 • Pour bien distinguer un objet jQuery d’un élément du DOM, il est d’usage de préfixer les variables référant à un objet jQuery avec le signe « $ ». • Il n’y a aucune magie derrière cette pratique : c’est juste une convention de nommage (à suivre ou non… mais soyez constant dans l’écriture de votre code). // Comparaison d’éléments du DOM (mais avec des nom de variable plus explicites) var $logo1 = $("#logo"); var logo1 = $logo1.get(0); var $logo2 = $("#logo"); var logo2 = $logo2.get(0); console.log(logo1 === logo2); // true
  • 203.
    | jQuery – L’objetjQuery (notion avancée) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 203 • Les objets jQuery ne sont pas dynamique : dans le sens ou la collection retournée par un sélecteur ne changera pas, même si des éléments correspondant au sélecteur son supprimés ou ajoutés dans le DOM. • Si le document a peut-être changé depuis la création initiale de l'objet jQuery, la collection doit être mise à jour en créant un nouveau objet jQuery. Tout simplement en ré-exécutant le même sélecteur : var allParagraphs = $("p"); // On ajoute un nouveau paragraphe dans le DOM pour un raison X ou Y. allParagraphs n’est pas MAJ. // On doit mettre à jour manuellement la sélection précédente : allParagraphs = $("p");
  • 204.
    | jQuery – Fonctions •Une fois qu’un élément a été identifié (c’est-à-dire sélectionné), on peut utiliser des fonctions jQuery sur cet élément. La plupart de ces fonctions sont dites « utilitaires » dans le sens où elles permettent de simplifier leur manipulation. • Les fonctions jQuery ne concernent pas uniquement la manipulation du DOM ou la mise en forme CSS. • Syntaxe : $(selector).action(); • On peut « chainer » la plupart des fonctions : $(selector).action().action2().action3(); Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 204
  • 205.
    | jQuery – Fonctions •addClass() : ajoute une ou plusieurs classes aux éléments sélectionnés • removeClass(): retire une ou plusieurs classes aux éléments sélectionnés • toggleClass() : ajoute la classe si elle n’existe pas, sinon retire cette classe (toggle = bascule) • hasClass() : vérifie si l’un des éléments sélectionné contient cette classe Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 205 Manipulation des classes CSS $("p:first").addClass("intro"); if ($("p:first").hasClass("intro")) { $("#result").append(“Le paragraphe a la classe CSS intro"); }
  • 206.
    | jQuery – Fonctions •append() : insert du contenu à la fin des éléments sélectionnés • appendTo() : insert un élément HTML à la fin / suite des éléments sélectionnés • before() : insert du contenu avant les éléments sélectionnés • insertAfter() : insert un élément HTML après les éléments sélectionnés • insertBefore() : insert un élément HTML avant les éléments sélectionnés • prepend() : insert un contenu au début des éléments sélectionnés (en leur sein) • prependTo() : insert un élément HTML au début des éléments sélectionnés (en leur sein) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 206 Insertion
  • 207.
    | jQuery – Fonctions Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 207 Insertion : exemple de prependTo() <h2>Greetings</h2> <div class="container"> <div class="inner">Hello</div> <div class="inner">Goodbye</div> </div> $("<p>Test</p>").prependTo(".inner"); <h2>Greetings</h2> <div class="container"> <div class="inner"> <p>Test</p>Hello </div> <div class="inner"> <p>Test</p>Goodbye </div> </div>
  • 208.
    | jQuery – Fonctions •attr() : définit un attribut, ou retourne des attributs de l’élément sélectionné Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 208 D’autres fonctions… $("img").attr("width", "500"); • clone() : fait une copie de l’élément sélectionné $("p").clone().appendTo("body"); • css() : définit ou retourne un ou plusieurs styles CSS pour l’élément sélectionné $("p").css("color", "red"); $("p").css({"background-color": "yellow", "font-size": "200%"}); // multiples propriétés
  • 209.
    | jQuery – Fonctions •empty() : supprime les éléments enfant (du nœud DOM) de l’élément sélectionné Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 209 D’autres fonctions… $("div").empty(); • height() : définit ou retourne la hauteur de l’élément sélectionné $("div").height(); … $("#foo").height(30); • offset() : retourne la position (x/y) de l’élément à l’écran. Utiliser offsetParent() pour la position par rapport à l’élément parent. var positions = $(".bar").offset(); // Accès aux propriétés : positions.left et positions.top;
  • 210.
    | jQuery – Fonctions •text() : définit ou retourne le contenu texte de l’élément sélectionné Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 210 D’autres fonctions… $("p").text("Hello world!"); // <p>Hello world!</p> • val() : définit ou retourne la valeur de l’élément sélectionné $("input:text").val("Hello World"); • find() : recherche un élément correspond au contexte de l’élément sélectionné $(this).find("p");
  • 211.
    | jQuery – Evènements •Il existe plus de 30 évènements en jQuery… • Par exemple pour intercepter un clic sur un élément : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 211 $("#foo").click(function(){ console.log(“foo clicked”); }); • On passe une fonction anonyme à la fonction click() de jQuery. Le sélecteur $("#foo") fait que l’évènement click sera attaché à cet élément du DOM. • L’équivalent en JavaScript serait : document.getElementById(‘#foo’).addEventListener(‘click’, function() {…})
  • 212.
    | jQuery – Evènements •Cependant la fonction click() pose problème si notre DOM est susceptible de changer dans le futur. L’évènement click sera attaché uniquement au éléments du DOM existant lors de l’appel de click(). • Pour lever cette limitation, la fonction live() a été introduite en jQuery 1.6 : déprécié en 1.7 et supprimée en 1.9. ATTENTION : ne plus l’utiliser ! • On passera plutôt par la fonction on() : • Utilise moins de mémoire (car délégation) • Fonctionne avec des éléments ajoutés dynamiquement NB : click() est un alias vers trigger(‘click’), tandis que click(data, fn) est un alias vers on(‘click’, null, data, fn). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 212
  • 213.
    | jQuery – Evènements •Avec la syntaxe « on » dynamique : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 213 $("#foo").on("click", function(){ console.log("foo clicked"); });
  • 214.
    | jQuery – Evènements Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 214 • Exercice d’application : attacher un évènement « click » pour chaque paragraphe du div parent. Dans la méthode de callback, modifier la couleur du texte en rouge. Commencer par utiliser click() puis on(). • Attacher un second évènement « click » pour le bouton « create_element ». L’action sur ce bouton doit ajouter un nouveau paragraphe dans le div parent (vous pouvez utiliser la méthode append()). <div id="wrapper"> <p>First paragraph</p> <p>Second paragraph</p> </div> <button id="create_element">Create new paragraph</button>
  • 215.
    | jQuery – Evènements Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 215 $(function() { // Evènement non dynamique (à ne pas utiliser…) /*$('#wrapper p').click(function() { $(this).css('color', 'red'); });*/ $('#wrapper').on('click', 'p', function() { $(this).css('color', 'red'); }); $('#create_element').click(function() { $('#wrapper').append("<p>New element</p>"); }); }); • Exercice d’application : correction
  • 216.
    | jQuery – Evènements •A savoir qu’on peut également déclencher manuellement la soumission d’un formulaire en lever l’évènement submit : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 216 L’évènement submit() pour l’envoi d’un formulaire $("#myForm").submit(function(e) { e.preventDefault(); console.log("Le formuaire myForm a été envoyé"); }); $("#foo").click(function() { $("#myForm").submit(); });
  • 217.
    | jQuery – Evènements Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 217 L’évènement resize() pour surveiller la redimension d’une fenêtre $(window).resize(function() { console.log("La fenêtre a été redimensionnée par l’utilisateur"); }); • Attention, cet évènement est envoyé à l’élement « window ». • On devra donc attacher l’évènement resize sur un sélecteur de window :
  • 218.
    | jQuery – AJAX •L’utilisation de l’architecture AJAX en jQuery est plus simple qu’en JavaScript natif, surtout quand il s’agit de supporter les navigateurs d’ancienne génération. • Si on veut avoir un contrôle maximum sur la requête jQuery et la gestion des évènements, on passera par la fonction / l’interface bas niveau $.ajax() : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 218 $.ajax({ method: "POST", url: "foo.php", data: { name: "John", location: "Boston" }, dataType: "json", success: function(resp) { ... }, error: function(req, status, err) { ... } });
  • 219.
    | jQuery – AJAX Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 219 var jqxhr = $.ajax( "example.php" ) .done(function() { alert("success"); }) .fail(function() { alert("error"); }) .always(function() { alert("complete"); }); • On peut aussi utiliser cette notation depuis jQuery >= 1.5 :
  • 220.
    | jQuery – AJAX •Pour plus de simplicité, on peut également utiliser des fonctions raccourcies. • $.get() permet de charger des données d’un serveur en utilisant le verbe HTTP GET : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 220 // Requêter la page server.php en transmettant des données additionnelles // Utiliser l’évènement done() en attachant une function de callback $.get("server.php", { name: "John", time: "2pm" }) .done(function(data) { console.log("Data Loaded: " + data); } );
  • 221.
    | jQuery – AJAX •Pour plus de simplicité, on peut également utiliser des fonctions raccourcies. • $.post() permet de charger des données d’un serveur en utilisant le verbe HTTP POST : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 221 // Requêter la page server.php en transmettant des données additionnelles // Utiliser l’évènement done() en attachant une function de callback $.post("server.php", { name: "John", time: "2pm" }) .done(function(data) { console.log("Data Loaded: " + data); } ); $.post("server.php", $("#myForm").serialize());
  • 222.
    | jQuery – AJAX •Exercice d’application : soit le code HTML suivant, on cherche à soumettre ce formulaire de recherche via une requête HTTP POST en utilisant l’architecture AJAX. Créer également la partie serveur (en PHP par exemple). Retourner un objet JSON (en php : return json_encode([‘result’ => ‘…’]);) et parser le résultat côté client. • Aide : ajouter un évènement pour écouter la soumission du formulaire  utiliser .submit(callback); sur le sélecteur correspond au formulaire searchForm. Utiliser par exemple une fonction anonyme et passer « e » comme argument.  utiliser la méthode preventDefault() pour stopper la propagation du clic. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 222 <form action="search.php" id="searchForm"> <input type="text" name="s" placeholder=“Rechercher..."> <input type="submit" value="Search"> </form> <div id="result"></div>
  • 223.
    | jQuery – AJAX Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 223 $("#searchForm").submit(function(e) { e.preventDefault(); var $form = $(this), term = $form.find("input[name='s']").val(), url = $form.attr("action"); // Envoi paramètre "s" en POST var posting = $.post(url, { s: term }); // Afficher le résultat dans un div posting.done(function(data) { data = $.parseJSON(data); $("#result").empty().append(data.result); }); }); <?php header('Content-Type: application/json'); $search = $_POST["s"]; echo json_encode([ 'result' => "Votre recherche : $search" ]);
  • 224.
    | jQuery – Effetset animations Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 224 • jQuery propose des fonctions d'animations et de transitions qui peuvent être appliquées sur les éléments du DOM. • On distingue deux groupes d’effets et animations : • Les animations prédéfinies dans jQuery comme les effets de « fade » ou de « slide » • Les animations manuelles que l’on paramètre soit même en appelant la fonction animate()
  • 225.
    | jQuery – Effetset animations Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 225 Effet sur la visibilité des éléments : hide / show • hide(speed, callback) : permet de masquer un élément. Les deux paramètres de la fonction sont optionnels. Le premier permet de définir le temps de l’animation (en ms ou en passant par slow/fast), le second affecte une fonction de callback qui sera appelée à la fin de l’animation. // Au clic sur le bouton, masquer l’élement #foo // puis afficher un message de confirmation dans la console $("#myButton").click(function() { $("#foo").hide("slow", function() { console.log("Animation complete"); }); });
  • 226.
    | jQuery – Effetset animations Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 226 Effet sur la visibilité des éléments : toggle • toggle(speed, callback) : permet de basculer entre les fonctions hide() et show() en fonction de l’état de l’élément. Par exemple si l’élément est visible, l’appel de toggle() entrainera le déclenchement de hide(). // Au clic sur le bouton, masquer ou afficher l’élement #foo // puis afficher un message de confirmation dans la console $("#myButton").click(function() { $("#foo").toggle(2000, function() { console.log("Animation complete"); }); });
  • 227.
    | jQuery – Effetset animations • fadeIn(speed, callback) : permet d’afficher progressivement un élément masquée (l’opacité de l’élément cible va passer de 0 à 100 pendant la durée définie dans le paramètre optionnel speed). Le second paramètre affecte une fonction de callback qui sera appelée à la fin de l’animation. • fadeOut(speed, callback) : même principe, mais estompe progressivement un élément au lieu de l’afficher. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 227 Effet sur la visibilité des éléments : fading $("a").click(function() { $("div").fadeIn(3000, function() { $("span").fadeIn(100); }); return false; });
  • 228.
    | jQuery – Effetset animations • fadeToogle(speed, callback) : permet de basculer entre les fonctions fadeIn() et fadeOut() en fonction de l’état de l’élément. Par exemple si l’élément est visible, l’appel de fadeToggle() entrainera le déclenchement de fadeOut(). • fadeToogle(speed, opacity, callback) : permet d’afficher progressivement un élément jusqu’à une opacité donnée. A l’inverse de fadeIn() qui passe l’opacité de 0 à 100. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 228 Effet sur la visibilité des éléments : fading $("p:first").on("click", function() { $(this).fadeTo("slow", 0.33); });
  • 229.
    | jQuery – Effetset animations • Vous pouvez créer un effet de glissement sur les éléments en utilisant les fonctions slideDown(), slideUp() ou slideToggle(). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 229 Effets de glissement (slide) $("#flip").click(function(){ $("#panel").slideToggle(); });
  • 230.
    | jQuery – Effetset animations • Si aucun effets prédéfinis correspond à votre usage, vous pouvez utiliser la fonction animate({params}, speed, callback) pour définir votre propre animation. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 230 Animations personnalisées $("button").click(function(){ $("div.foo").animate({ left: '250px', opacity: '0.5', height: '150px', width: '150px' }, 2000, function() { console.log("Animation terminée"); }); }); Remarque : vous pouvez manipuler toutes les propriétés CSS (sauf color qui nécessite l’installation du plugin « jQuery Color »). Cependant, le nom des propriétés doit être en notation Camel Case. padding-left  paddingLeft
  • 231.
    | jQuery – Effetset animations • Comme presque toute fonction jQuery, vous pouvez passer par un chainage de méthodes pour éviter de dupliquer du code. Dans l’exemple suivant, les animations se succèderons une après une : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 231 Chainage des animations $("#foo").css("color", "red") .slideUp(2000) .slideDown(2000);
  • 232.
    | jQuery – Itérations •La function jQuery each() est utilisée pour itérer à travers chaque élément d’une collection d’objets jQuery. • Pour rappel, on utilise un sélecteur jQuery via la function $() ce qui aura pour effet de retourner une collections d’objets jQuery correspondant à la requête du sélecteur. • L’exemple suivant sélectionne chaque div du DOM et affiche l’index et l’ID de chaque div : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 232 $('div').each(function (index, value) { console.log('div' + index + ':' + $(this).attr('id')); });
  • 233.
    | jQuery – Itérations •L’exemple suivant permet d’afficher l’attribut href de chaque lien (élément <a>) du document : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 233 $('a').each(function (index, value){ console.log($(this).attr('href')); }); // Affichage uniquement des liens externes $('a').each(function (index, value){ var link = $(this).attr('href'); if (link.indexOf('http://') === 0) { console.log(link); } });
  • 234.
    | jQuery – Itérations •On peut utiliser la fonction each() directement sur un sélecteur (qui retourne une collection), ou l’utiliser de manière totalement indépendante du DOM. On utilisera la syntaxe $.each() : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 234 // Tableau JavaScript var arr = ['one', 'two', 'three', 'four', 'five']; // Itérer chaque élément du tableau $.each(arr, function (index, value) { console.log(value); // Stopper l’itération après le passage sur la valeur "three" return (value !== 'three'); }); // Affichera : one two three
  • 235.
    | jQuery – Itérations •La fonction utilitaire $.each() peut aussi itérer un objet JavaScript : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 235 // Objet JavaScript var obj = { one: 1, two: 2, three: 3, four: 4, five: 5 }; $.each(obj, function (index, value) { console.log(value); }); // Affichera : 1 2 3 4 5
  • 236.
    | jQuery – Plugins •Les plugins permettent d’étendre les fonctionnalités de base de jQuery. • L’appel d’un plugin se fait toujours de la même manière : $(selector).pluginName(options); Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 236 $('.slider').bxSlider({ slideWidth: 200, minSlides: 2, maxSlides: 3, slideMargin: 10 });
  • 237.
    | jQuery – Créationd’un plugin Structure basée sur https://github.com/jquery-boilerplate/jquery-patterns/blob/master/patterns/jquery.basic.plugin-boilerplate.js Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 237 ;(function ( $, window, document ) { ... })( jQuery, window, document ); Le point virgule avant l’invocation de la fonction permet d’éviter d’éventuelles erreurs (par exemple un autre plugin/script en amont qui n’aurait pas fermé correctement une instruction. Trois arguments sont passés dans cette fonction anonyme : 1) $ pour créer un alias de la fonction jQuery 2) l’objet natif window comme variable locale 3) l’objet natif document comme variable locale 2+3 : légèrement plus performant que d’appeler les objets globaux window et document; facile la minification.
  • 238.
    | jQuery – Créationd’un plugin Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 238 ;(function ($, window, document) { ... var pluginName = "defaultPluginName", defaults = { propertyName: "value" }; function Plugin(element, options) { this.element = element; this.options = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.init(); } ... })(jQuery, window, document); $.extend() : Etend un objet avec un ou plusieurs autres, et retourne l'objet original modifié. La fonction « Plugin » sera utilisée comme constructeur (voir slide suivante). Appel d’une des fonctions publics du plugin (on verra dans le slide suivante comment elle est déclarée et rendu accessible).
  • 239.
    | jQuery – Créationd’un plugin Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 239 ;(function ($, window, document) { ... $.fn[pluginName] = function (options) { return this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data( this, "plugin_" + pluginName, new Plugin(this, options) ); } }); }; ... })(jQuery, window, document); Cette fonction agit comme un Singleton pour éviter de multiples instanciations du plugin. Appel du constructeur (voir slide précédente) La propriété fn de jQuery est juste un alias vers la propriété prototype. De cette manière on étend jQuery en ajoutant une nouvelle fonction à la chaine de fonction jQuery. Cette fonction sera : defaultPluginName();
  • 240.
    | jQuery – Créationd’un plugin Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 240 ;(function ($, window, document) { ... $.extend(Plugin.prototype, { init: function () { this.yourOtherFunction("foo"); }, yourOtherFunction: function (text) { // some logic $(this.element).text(text); } }); ... })(jQuery, window, document); On as vu que la fonction init() était appelée par le constructeur de notre plugin. Au sein de cette fonction, on peut déjà accéder au DOM via this.element, et aux paramètres du plugin via this.settings. Comme son nom l’indique, on va pouvoir initier un certain nombre d’actions, dont l’appel de notre code métier.
  • 241.
    | jQuery – Créationd’un plugin • L’application web sur laquelle vous travaillez dispose d’un système de gestion des comptes utilisateurs. Un formulaire permet à un visiteur de se créer un compte utilisateur : il doit indiquer un nom, prénom, une adresse email et choisir un mot de passe. • Pour des raisons de sécurité, on souhaite forcer le choix d’un mot de passe sécurisé. • On décide de passer par la bibliothèque PHP et JavaScript zxcvbn de Dropbox. Elle permet de mesurer l’entropie d’un mot de passe en fonction de plusieurs critères. La fonction native de zxcbn retourne un indice (propriété score) allant de 0 à 4. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 241 Exercice d’application
  • 242.
    | jQuery – Créationd’un plugin • Le but final est d’afficher un indicateur graphique reprenant ce score. Si le score est supérieur ou égale à 3 on autorisera la soumission du formulaire. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 242 Exercice d’application Exemple d’implémentation sur dropbox.com
  • 243.
    | jQuery – Créationd’un plugin • Remarque : pour renforcer le calcul de l’entropie, on passera en paramètre à la fonction zxcvbn les champs input nom, prénom et adresse email. De cette manière zxcvbn réduira l’entropie si le mot de passe contient l’une de ces valeurs. • Cette bibliothèque n’est pas portée sur jQuery. On devra créer un plugin jQuery pour faciliter la manipulation des fonctions JavaScript fournies par zxcvbn et capitaliser sur le code créé (réutilisation dans d’autres projets, partage à la communauté, etc.). • Vous devrez procéder par étapes successives pour mener à bien cette mission. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 243 Exercice d’application
  • 244.
    | jQuery – Créationd’un plugin • En premier lieu, créer un formulaire d’inscription, avec les champs correspondant aux informations qu’on souhaite récupérer (nom, prénom, email, mot de passe), ainsi qu’un bouton de soumission. Si vous souhaitez, vous pouvez même créer la partie serveur pour persister la soumission en table, et même appeler la bibliothèque PHP zxcvbn pour renforcer la sécurité (indispensable en production). • Télécharger et intégrer la bibliothèque JavaScript zxcvbn dans votre page. Commencer par utiliser la fonction native de zxcvbn pour calculer l’entropie. • En fonction de cette entropie, autoriser ou non la soumission du formulaire. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 244 Exercice d’application
  • 245.
    | jQuery – Créationd’un plugin • Seulement après, baser sur le squelette de plugin pour créer votre propre plugin que vous nommerez « zxcvbn ». Ce plugin devra : • Récupérer un certain nombre d’options : l’indice de force minimum attendu, des références vers les champs input (ou directement les valeurs de ces champs), etc. • Afficher un indicateur graphique à proximité du champ mot de passe • Autoriser ou non la soumission du formulaire Appeler le plugin avec le code : $("#form").zxcvbn({minScore: 3, blacklisted: […]}); Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 245 Exercice d’application
  • 246.
    |Février 2016 FormationORT 3CSi - Guillaume MOREL-BAILLY 246
  • 247.
  • 248.
    | MEAN – Introduction •Depuis les 20 dernières années, il y a eu des changements conséquents dans le domaine du développement informatique, et plus particulièrement en développement web. • Les technologies, langages, et les architectures évoluent rapidement. • Depuis 2/3 ans, un nouveau engouement pour le langage JavaScript dans la communauté des développeurs. On a tendance à redécouvrir ce langage (et les possibilités qu’il offre), alors qu’il existe depuis plus de 20 ans… • « MEAN » est une architecture (on utilisera aussi le terme anglais « stack »). • Utilisation massive de JavaScript, côté client et serveur. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 248
  • 249.
    | MEAN – Introduction •Découverte de l’architecture MEAN et ses composantes (couches et outils utilisés et utilisables). • L’architecture MEAN n’est pas figée : vous pouvez remplacer un framework par un autre. • Faible couplage et forte cohésion. • Attention, MEAN n’est pas une réponse à tous les besoins ! • En développement informatique, l’ordre des opérations est très important. On doit d’abord comprendre les besoins et problématique, et seulement ensuite choisir les technologies qui peuvent y répondre. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 249
  • 250.
    | MEAN – Introduction •MEAN est une architecture à faible couplage et forte cohésion. • C’est l’un des intérêts majeurs de cette stack. • Le couplage mesure la dépendance entre système : par exemple entre les couches d’une architecture (frameworks / modules), ou les classes d’un programme • La cohésion mesure leurs compréhensibilités. Plus un élément à des responsabilités, plus faible est sa cohésion. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 250 Faible couplage et forte cohésion.
  • 251.
    | MEAN – L’architectureLAMP • Pour mieux comprendre ce qu’il y a de si intéressant à propos de l’architecture MEAN, on doit s’intéresser tout d’abord à l’architecture LAMP. • Acronyme qui désigne les technologies open-source utilisées pour créer un site ou une application web. Plusieurs couches : plateforme, serveur web, base de données et middleware/UI. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 251
  • 252.
    | MEAN – L’architectureLAMP • Faible couplage et forte cohésion : LAMP, WAMP, MAMP, WIMP, LEMP, etc. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 252 Plateforme (système d’exploitation) Serveur web Base de données (SGBD) Langage de programmation (middleware / UI)
  • 253.
    | MEAN – L’architectureLAMP Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 253
  • 254.
    | MEAN – L’architectureLAMP • LAMP s’est imposé comme un standard car c’est une architecture open-source, flexible et rapidement déployable de nos jours. • On peut facilement interconnecter des technologies entre elles. • Cependant quelques limitations : • Transformation des données • Plusieurs langages de programmation (par exemple JavaScript, PHP et SQL) • Scalabilité Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 254
  • 255.
    | MEAN – Choisirles bons outils • A quoi ressemble le développement web de nos jours ? • Recherche de composants / bibliothèques répondant à nos besoins. On se retrouve souvent avec des technologies et langages différents au sein d’un même projet. • Ne pas réinventer la roue : se reposer sur un système éprouvé, diminuer les coûts, etc. • Nécessite par contre d’avoir des composants avec un faible couplage et une forte cohésion. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 255
  • 256.
    | MEAN – Choisirles bons outils • Les managers recherchent l’outil ultime, qui permettrait de tout faire. • Le marteau de Maslow : tentation qui consiste à travestir la réalité d’un problème en le transformant en fonction des réponses dont on dispose, ou encore le fait de considérer qu’il n’y a qu’une réponse unique à tous les problèmes. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 256 « Si le seul outil que vous avez est un marteau, vous tendez à voir tout problème comme un clou ». Abraham Maslow
  • 257.
    | MEAN – Choisirles bons outils • Quand vous comparez des frameworks web, quand vous êtes à la recherche d’une solution pouvant répondre à vos besoins, – et non une solution qui correspondrait exactement aux outils et technologies que vous maitrisez –, … • Il faut favoriser l’extensibilité sur la totalité, et les plugins sur les fonctionnalités du core (un écosystème riche, robuste et actif). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 257
  • 258.
    | MEAN – Découvertede cette architecture • Le terme « MEAN » est l’acronyme de MongoDB, Express, Angular et Node.js. • Architecture nouvelle (moins de 3 ans), en plein développement. • En 2015 elle a été largement propulsée, profitant du nouvel engouement pour JavaScript, comme l’architecture « à la mode ». • Un seule langage de programmation sur toutes les couches , JavaScript, et un seul format d’échange de données : JSON. • On parle alors de solution « full-stack ». Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 258
  • 259.
    | MEAN – Découvertede cette architecture Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 259 Même langage, même objets… {"_id": ObjectId("278390a08i399"), "username" : "john" } {"_id": "278390a08i399", "username" : "john" } {"_id": "278390a08i399", "username" : "john" }
  • 260.
    | MEAN – Découvertede cette architecture • L’architecture MEAN ne doit pas être confondue avec l’architecture LAMP (ou ses dérivées). • L’architecture MEAN est similaire dans le sens où : • elle est également basée sur des technologies open-source, • c’est une architecture à forte cohésion et à faible couplage. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 260
  • 261.
    | MEAN – Découvertede cette architecture LAMP ≠ MEAN Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 261 ≠ ≠ ≠ ≠ Linux Apache MySQL PHP MongoDB Express Angular Node.js
  • 262.
    | MEAN – Découvertede cette architecture LAMP  NEMA ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 262     Linux Apache MySQL PHP Node.js Express MongoDB Angular (plateforme) (serveur web) (persistance) (interface utilisateur)
  • 263.
    | MEAN – Découvertede cette architecture • Donc on a vu que Node.js n’est pas un serveur web. • Node.js est « simplement » une plateforme qui inclue des modules réseau comme NET, HTTP, HTTPS et UPD. Mais ont peut également charger des modules de plus haut niveau comme Socket.io qui permet de gérer les WebSockets, ou bien SMTP pour créer un serveur d’envoi d’emails… • Cela signifie qu’on ramène ces services dans notre application, plutôt que de déployer notre application sur un conteneur externe (comme un serveur). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 263
  • 264.
    | MEAN – Découvertede cette architecture Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 264 LAMP MEAN Linux Node.js Navigateur MySQL MongoDBApache Application (PHP) Application Express.js Application Angular
  • 265.
    | MEAN – Découvertede cette architecture • Tout comme LAMP, on se retrouve avec de nombreuses technologies devant cohabiter. • Le faite d’avoir toutes ces couches ne signifie pas pour autant qu’on va devoir interagir avec chacune d’entre elles ! • Existe-t-il un framework permettant de réunir / connecter ces technologies avec un peu plus d’aisance, de commodité en apportant une génération de code (scaffolding), des tests d’intégration, des scripts de déploiement, etc. ? • MEAN.JS et MEAN.io (voir la partie 8 dédiée à ces frameworks) • Avoir une architecture MEAN pleinement fonctionnelle en quelques minutes. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 265
  • 266.
    Partie 4 Node.js Event-driven I/Oserver-side JavaScript environment based on V8
  • 267.
    | Node.js Présentation de Node.js: histoire, usages, concepts clés et architectures. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 267
  • 268.
    | Node.js – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 268
  • 269.
    | Node.js – Présentation •Node.js est une plateforme open-source, piloté par les évènements, pour développer des applications web côté serveur en utilisant le langage JavaScript. On parle aussi de Node.js comme un environnement d’exécution JavaScript. • A l’origine Node.js pouvait seulement être installé sur Linux. Aujourd’hui, des applications Node.js peuvent être exécutées également sur Windows et Mac OS X. • Moteur de script : machine virtuelle V8 de Google. • Création : mai 2009 par Ryan Dahl. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 269
  • 270.
    | Node.js – Présentation •Nous avons vu que JavaScript est par nature asynchrone. La plupart des opérations I/O en JavaScript sont non bloquantes : requêtes HTTP, requêtes AJAX, lecture / écriture sur le système de fichier, etc. • Cela signifie que les opérations s’exécutent de manière linéaire sans attendre la fin de l’opération précédente. Les fonction de callback permettent de récupérer la réponse d’une opération. • La programmation concurrente est un paradigme de programmation qui permet d’exécuter plusieurs opérations au cours de période de temps qui se chevauchent simultanément, au lieu d’exécuter ces opérations séquentiellement (attente de la fin d’une opération pour exécuter la suivante). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 270 Environnement non bloquant
  • 271.
    | Node.js – Présentation •La programmation concurrente fait appel à des threads. Des langages comme Java ou l’environnement .NET permettent de créer des applications multi-thread pour gérer la concurrence en leur sein. • Cependant, manipuler les threads n’est pas simple ! Communication inter-thread compliquée, risque d’étreinte mortelle / deadlocks (interblocage de données), ralentissement parallèle, problème de montée en charge, etc. • Des mécanismes de synchronisation permettent de réduire ces problèmes. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 271 Environnement non bloquant
  • 272.
    | Node.js – Présentation •Les langages comme Java ou l’environnement .NET ne sont pas asynchrone. Les opérations d’I/O ne sont pas non plus asynchrone. • C’est pour ça qu’on doit obligatoirement passer par l’utilisation de thread si on ne veut pas bloquer l’exécution de l’application. • Dans un serveur web comme Apache, c’est le même problème : un thread est créé pour chaque nouvelle connexion HTTP initiée par un client. • Dans un contexte très concurrentiel, le modèle de programmation multi-threading atteint rapidement ses limites. Dans le cas d’un serveur web, on a par exemple un nombre maximum de thread en simultané (donc de thread disponible). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 272 Environnement non bloquant
  • 273.
    | Node.js – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 273 Environnement non bloquant
  • 274.
    | Node.js – Présentation •Le problème ne se pose pas dans Node.js, car on profite de la puissante du langage JavaScript qui est asynchrone. • D’ailleurs, Node.js est single-threaded, c’est-à-dire que la programmation multi-thread est impossible. • Par exemple, dans le cas d’un serveur web créé avec Node.js, la nature non bloquante des opérations I/O permet de gérer de très nombreuses connexions simultanées sans que cela impacte les performances de l’application. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 274 Environnement non bloquant
  • 275.
    | Node.js – Présentation •De manière plus concrète, Node.js dispose en son sein d’une boucle d’évènements (event loop) qui va continuellement traiter les évènements reçus. • Dans le cas d’un serveur web avec Node.js, le serveur va conserver une pile de fonctions à exécuter (dites de callback) lors de la réception d’évènements précis. • L’unique thread de Node.js va ainsi traiter les évènements apparaissant dans la queue d’évènements les uns après les autres, au fil des requêtes et fin d’IO. • Permettre de traiter des milliers de requêtes simultanées en consommant très peu de mémoire. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 275 Environnement non bloquant
  • 276.
    | Node.js – Présentation •Seul inconvénient de ce modèle single-threaded : on ne profite pas de la puissance complète du processeur s’il dispose de plusieurs cœurs. • Pour ce faire, il faut lancer les applications Node.js en mode cluster (accessible via le module « Cluster » de Node.js). • Pour faire simple, ce module permet de partager des sockets entre processus pour mettre en place du load balancing entre les cœurs du processeur. • Plus d’informations sur la documentation : https://nodejs.org/api/cluster.html Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 276 Environnement non bloquant
  • 277.
    | Node.js – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 277 Environnement non bloquant
  • 278.
    | Node.js – Présentation •Piloté par les évènements. • Modèle d’entrées / sorties (I/O) asynchrone non bloquant en passant par l’utilisation de callbacks. • Tout à l’intérieur de Node.js est traité par un seul et unique thread. • Approche réactive implémentée par le boucle d’évènements (voir schéma précédent). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 278 Particularités de Node.js
  • 279.
    | Node.js – Présentation •Node.js à un cycle de développement très rapide. • Disclaimer : certaines fonctions de cette présentation seront peut être dépréciés dans quelques mois… • Généralement il y a au minimum 2 versions publiées chaque mois. • Des modifications importantes entre les versions : attention aux outils dépréciés et aux tutoriels qui ne sont plus à jour sur le web. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 279 Cycle de développement et versions
  • 280.
    | Node.js – Présentation •On distingue deux cycles de développement différents : les versions dites « LTS » et les versions dites « Stable ». • Versions LTS – L'abréviation LTS signifie Long Term Support, ou maintenue à long terme (3 ans). Ces versions portent des numéros pairs et mettent l’accent sur la stabilité et la sécurité. A privilégier en environnement de production. Dernière version LTS en date : v4.x.x (nom de code Argon). • Versions « Stable » – Ces versions portent de numéros impairs et ont des mises à jour plus fréquentes du code. Ajout de nouvelles fonctionnalités et amélioration de l’API existante. Le nom « stable » ne doit pas être compris au sens français du terme. Dernière version en date : v5.x.x. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 280 Cycle de développement et versions
  • 281.
    | Node.js – Présentation •En décembre 2014, suit à un conflit interne en les développeurs de Node.js un fork est créé : il s’agit de io.js. En juin 2015 Node.js et io.js se sont regroupés pour travailler en ensemble. • Les versions 1.x.x à 3.x.x réfèrent au fork io.js. • La version 4.x.x de Node.js a été créé suite au regroupement de io.js et Node.js (qui était en version 0.12.x). • Attention : on retrouve énormément de tutoriels concernant la version 0.12.x. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 281 Cycle de développement et versions
  • 282.
    | Node.js – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 282 Installation • Aller sur nodejs.org et installer Node.js sur votre poste. • Télécharger la version 5.x.x. • Exécuter la commande node -v dans votre terminal pour vérifier que l’installation s’est bien passée.
  • 283.
    |Février 2016 FormationORT 3CSi - Guillaume MOREL-BAILLY 283
  • 284.
    | Node.js – Présentation •Comment peut on faire tourner JavaScript en dehors d’un navigateur web ? • On pourrait penser que JavaScript sert seulement à manipuler le DOM d’une page et à interagir avec les évènements utilisateur via le navigateur (clic souris, etc.). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 284 JavaScript côté serveur ? JavaScript Si vous vous êtes fait la représentation suivante de JavaScript, vous pourriez être vraiment confus par cette notion d’utiliser JavaScript en hors d’un navigateur.
  • 285.
    | Node.js – Présentation «JavaScript » peut être décomposer en trois parts égales : • Le langage en lui-même (éléments de langage, mots clés, concepts, structure, etc.) • La plateforme sur lequel il peut tourner : V8, SpiderMonkey, Chakra, etc. • Les API : Navigator, Window, Document… Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 285 JavaScript côté serveur ? JavaScript Plateforme APIs
  • 286.
    | Node.js – Présentation •Ces API dépendent de la plateforme sur laquelle JavaScript (au sens large) est exécuté. • Dans le cas de JavaScript côté client, ces API sont fournies par le navigateur. Chaque navigateur gère ces API à sa manière (d’où parfois des problèmes de compatibilité entre navigateurs). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 286 JavaScript côté serveur ?
  • 287.
    | Node.js – Présentation •Si vous voulez exécuter les mêmes instructions sur Node.js, créer un fichier foo.js avec les lignes suivantes : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 287 JavaScript côté serveur ? console.log(navigator.appName); console.log(navigator.appVersion); • Puis exécutez-le avec Node.js en utilisant la commande « node » suivie de l’emplacement du fichier (ou de son nom si la console est ouverte dans le même répertoire). node foo.js
  • 288.
    | Node.js – Présentation •Avec l’architecture MEAN on utilise la langage JavaScript de bout en bout : • dans le navigateur, • sur le serveur pour nos programmes métiers mais aussi dans la couche de persistance. • Quand vous exécuter du JavaScript sur chacune des couches de l’architecture MEAN (serveur, persistance, client) vous devez connaitre quelles sont les APIs disponibles. • JavaScript, le langage est le seul élément qui est consistant dans les couches de notre architecture. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 288 JavaScript côté serveur ?
  • 289.
    | Node.js – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 289 JavaScript côté serveur ?
  • 290.
    | Node.js – Présentation •Pour rappel on peut décomposer un navigateur en deux grandes parties : le moteur de rendu et le moteur de script. • Ces moteurs peuvent égaler tourner en dehors de l’environnement d’un navigateur. Cela ouvre un tout nouveau champ de possibilité. • Mais à quoi ça sert de faire tourner sur un serveur un moteur de rendu qui est sensé permettre d’afficher à l’écran une page… en dehors d’un navigateur ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 290 JavaScript côté serveur ?
  • 291.
    | Node.js – Présentation •Reproduire le comportement d’un navigateur sans avoir à charger la page avec un navigateur. Utilisé pour faire des tests d’intégration. • Exemple de PhantomJS (pour de rendu WebKit) ou SlimerJS (reproduit Gecko). Et si un test est en échec, on peut demander la génération d’une capture d’écran. • On peut également faire tourner un moteur de script côté serveur : c’est ce que fait Node.js via le moteur V8 de Google. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 291 JavaScript côté serveur ?
  • 292.
    | Node.js – Présentation Pourfaire simple : presque tout le monde. Aller sur le wiki du repository GitHub de Node.js pour découvrir en détail les usages faits par certaines des entreprises mentionnées ici. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 292 Qui utilise Node.js ?
  • 293.
    | Node.js – Présentation •Migration de Java (et Java EE pour le site internet) vers JavaScript et Node.js. • Depuis le passage à Node.js : performances améliorées et coûts d’infrastructure réduits. • « We now run one quarter of the EC2 instances on Node compared with the legacy Java stack, whilst serving the same number of subscribers at lower latencies. » • Gain de productivité pour les développeurs : itérations (développement, tests, build, déploiement) plus faciles, du fait de la nature dynamique de JavaScript. • Plus d’infos sur talentbuddy « Building With Node.js At Netflix, an Interview With Yunong J Xiao » Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 293 Qui utilise Node.js ? Le cas
  • 294.
    | Node.js – Présentation •eBay utilisait Java et les frameworks web Spring et JAX-RS • Depuis, migration vers JavaScript en Node.js dans le but d’améliorer les performances et de switcher vers une plateforme moderne vers laquelle les développeurs seraient excités de travailler avec. • Le passage en full JavaScript a grandement facilité les itérations. • Plus d’infos sur talentbuddy « Building With Node.js At eBay, an Interview With John Cline » Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 294 Qui utilise Node.js ? Le cas
  • 295.
    | Node.js – Présentation •Linkedin était écrit avec le framework Ruby on Rails, mais c’est maintenant l’une des plus importante application Node.js en production. En complément de Node.js, HTML5 est utilisée pour la version mobile et l’application mobile. • « We use a ton of technologies at LinkedIn, but for the mobile server piece, it’s entirely Node-based.” • Linkedin voulait migrer vers une solution leur apportant plus de flexibilité (par exemple via la programmation asynchrone et évènementielle). • Gain en performance et en scalabilité. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 295 Qui utilise Node.js ? Le cas
  • 296.
    | Node.js – Présentation •Réduction drastique de l’infrastructure serveur : • « The improvements the team saw were staggering. They went from running 15 servers with 15 instances (virtual servers) on each physical machine, to just four instances that can handle double the traffic. » • Plus d’infos sur talentbuddy « Building With Node.js At Linkedin », et VentureBeat. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 296 Qui utilise Node.js ? Le cas
  • 297.
    | Node.js – Présentation •Node.js est organisé en plusieurs modules. Chaque module gère une fonctionnalité du core : système de fichier, réseau (DNS, HTTP, TCP, UDP et TLS), fonctions cryptographiques, etc. • Les modules sont chargés dans le code avec l’instruction require(). • Documentation complète : https://nodejs.org/dist/latest-v5.x/docs/api/ Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 297 Modules du core
  • 298.
    | Node.js – CommonJS •Pour charger une bibliothèque dans une page web, on utilise la balise HTML <script>. • Dans l’environnement Node.js, on utilise l’instruction require() pour charger un module interne ou externe. Par exemple le code suivant permet de charger le framework web Express : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 298 Chargement d’un module const http = require('express');
  • 299.
    | Node.js – CommonJS •Quand nous appelons Express, nous chargeons en fait un module CommonJS dans notre application. C’est ce qu’on appelle une dépendance. • Comment être sur que cette dépendance est mise à disposition de notre application ? Nous définissons les dépendances dans un fichier de configuration appelé « package.json ». • Cette dépendance doit être téléchargé en amont via une application qu’on appelle « npm ». • Nous allons voir dans la partie suivante comment ajouter n’importe quelle dépendance dans Node.js (et pas seulement un serveur web comme Express). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 299 Principe de fonctionnement
  • 300.
    | Node.js – CommonJS •CommonJS est une API permettant d’écrire des programmes JavaScript s'exécutant ailleurs que dans un navigateur web. Il permet de gérer des dépendances côté serveur (à l’inverse de RequireJS). • CommonJS a de nombreuses implémentations, par exemple dans Node.js. • Les bibliothèques qui se basent sur l’API CommonJS ne sont pas fortement liées à une plateforme spécifique. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 300 Principe de fonctionnement
  • 301.
    | Node.js – CommonJS Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 301 Chargement de modules CommonJS Exportation du module Express
  • 302.
    | Node.js – CommonJS •La nature même de JavaScript fait que tout est public et global. • Les modules donne la possibilité d’avoir des variables et des méthodes privées. En fait tout dans un module CommonJS est privé, à moins qu’on exporte explicitement ce module. • Cette possibilité là est très intéressante, car non supportée nativement par les anciennes version JavaScript (avant ECMAScript 6). CommonJS joue le rôle d’un polyfill. • Pour rappel (Wikipedia) : « un polyfill est un ensemble de fonctions permettant de simuler sur un navigateur web ancien des fonctionnalités qui ne sont pas nativement disponibles. » Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 302 Exportation
  • 303.
    | Node.js – CommonJS •require() charge le module lui-même mais aussi toutes ces dépendances. • module.exports === public API • Les variables et fonctions qui ne sont pas dans module.exports sont privées. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 303 Exportation
  • 304.
    | Node.js – Legestionnaire de paquets npm • Bien que Node.js ne soit pas un framework JavaScript, la plupart de ses modules sont écrits en JavaScript. Les développeurs peuvent étendre les fonctionnalités de base de Node.js en développant des modules en JavaScript. • On peut facilement installer et partager des modules en utilisant npm (Node Package Manager). • npm est un gestionnaire de paquets et de dépendances écrit entièrement en JavaScript et qui est installé automatiquement avec la plateforme Node.js (depuis 2011). Mais on peut l’utiliser en dehors de Node.js. • Pour faire une analogie à PHP, le gestionnaire de dépendances Composer se rapproche de npm. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 304 Présentation de npm
  • 305.
    | Node.js – Legestionnaire de paquets npm • Attention, npm ne doit pas être confondue avec l’instruction require() de CommonJS. • npm n’est pas utilisé pour charger du code ou des bibliothèques. Au lieu de ça, il est utilisé pour installer des modules et gérer les dépendances entre module en ligne de commande. • « Composer se rapproche de npm » : sauf que Composer permet également de charger les dépendances dans une application PHP (via un require/include sur le fichier vendor/autoload.php). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 305 Présentation de npm
  • 306.
    | Node.js – Legestionnaire de paquets npm • Un module (ou package) est juste un répertoire disposant d’un ou plusieurs fichiers. Il dispose également d’un fichier nommé package.json qui contient des métadata sur le module (nom, version, dépendances, etc.). • Une application web typique va dépendre de plusieurs dizaines de modules. • Les modules sont souvent petits : l’idée générale est qu’un module doit avoir une unique responsabilité. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 306 Principe de fonctionnement
  • 307.
    | Node.js – Legestionnaire de paquets npm • L’utilisation de npm se fait en ligne de commandes via la console du système hôte où est installé Node.js. • Le site npmjs.com liste les modules qui sont disponibles. On peut le comparer à packagist.org pour PHP. • On retrouve des modules Node.js mais aussi des modules front-end comme Angular ou bower. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 307 Principe de fonctionnement
  • 308.
    | Node.js – Legestionnaire de paquets npm Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 308 Principe de fonctionnement public registery npm publish packageName npm install packageName
  • 309.
    | Node.js – Legestionnaire de paquets npm • Un module peut être téléchargé avec la commande suivante : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 309 Installation d’un module npm install <package_name> • Cela créera un répertoire « node_modules » dans le répertoire de votre application (s’il n’existe pas déjà), et téléchargera le module dans ce répertoire. • Pensez bien à ajouter le répertoire node_modules dans le fichier .gitignore (pour qu’il ne soit pas commité dans votre repository). Les développeurs qui travaillent sur le projet devront simplement exécuter la commande npm update pour télécharger les même dépendances que vous.
  • 310.
    | Node.js – Legestionnaire de paquets npm • Quelle version du module est installée ? • Fichier package.json inexistant : installation de la dernière version • Fichier package.json existant : installation de la version du module spécifiée dans ce fichier (si spécifiée, sinon installation de la dernière version). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 310 Installation d’un module
  • 311.
    | Node.js – Legestionnaire de paquets npm • Permet de lister les modules dont votre application dépend. • Permet de spécifier les versions des module que votre projet utilise. • Facilite grandement le partage de votre application auprès d’autres développeurs. • Le fichier package.json doit contenir au minimum les propriétés « name » et « version ». Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 311 Le fichier package.json { "name": "my-awesome-package", "version": "1.0.0" }
  • 312.
    | Node.js – Legestionnaire de paquets npm • La bonne pratique consiste à créer un fichier package.json dés la création de votre application en utilisant la commande suivante : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 312 Le fichier package.json npm init • On peut également définir des valeurs par défaut pour éviter de renseigner à chaque fois les mêmes données à l’exécution de la commande init : npm set init.author.email "[email protected]" npm set init.author.name "ag_dubs" npm set init.license "MIT"
  • 313.
    | Node.js – Legestionnaire de paquets npm • On peut manuellement modifier le fichier package.json pour spécifier des dépendances. • On distingue 2 types de dépendances : celles de production (dans la propriété « dependencies ») et de développement (dans la propriété « devDependencies »). • Exemple de dépendances en développement : tests unitaires, minification, transpiler, etc. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 313 Le fichier package.json { "name": "my-awesome-package", "version": "1.0.0", "license": "MIT", "author" : "John Doe", "dependencies": { "my_dep": "^1.0.0", "express": "~4.13.0", "mongoose": "~3.6.1 " }, "devDependencies" : { "minify": "^3.1.0" } }
  • 314.
    | Node.js – Legestionnaire de paquets npm • Pour ajouter des dépendances à votre application, plutôt que de modifier manuellement le fichier package.json, le plus simple est d’utiliser les commandes suivantes : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 314 Le fichier package.json npm install <package_name> --save npm install <package_name> --save-dev
  • 315.
    | Node.js – Legestionnaire de paquets npm • De temps en temps, pensez à mettre à jour les modules dont votre application dépend de sorte à profiter des dernières nouveautés et des corrections de bugs / vulnérabilités. Pour ce faire, exécuter la commande suivante (au même niveau que package.json) : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 315 Mettre à jour vos dépendances npm update
  • 316.
    | Node.js – Legestionnaire de paquets npm • Pour supprimer une dépendance du répertoire node_modules et du fichier package.json, utiliser la commande suivante : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 316 Supprimer une dépendance npm uninstall --save <package_name>
  • 317.
    | Node.js – Legestionnaire de paquets npm • Semver (Semantic Versioning) est une gestion sémantique des versions d’un logiciel / modules. En d’autres termes, une façon de numéroter les versions de manière logique. • Ce n’est pas une norme, mais une bonne pratique (que je vous recommande d’appliquer)… Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 317 Comprendre les versions (semver) 4.13.2 Version majeure A incrémenter quand il y a des changements rétro-incompatibles Version mineur A incrémenter quand il y a des changements rétro-compatibles Correctif / patch A incrémenter quand il y a des corrections d’anomalies rétro- compatibles
  • 318.
    | Node.js – Legestionnaire de paquets npm • On renseigne souvent des numéros de versions des dépendances dans le fichier package.json. Parfois on rencontre la notation ~ (tilde) ou ^ (caret). • L’opérateur ~ permet de prévenir des changements brutaux alors que ^ est plus permissif. • Pour le tilde, il va inclure la version mineure la plus récente mais sans changer de branche. • ~1.2.3 équivaut à >=1.2.3 <1.3.0 • Pour le caret il inclura la version majeure la plus récente. • ^1.2.3 équivaut à >=1.2.3 <2.0.0 Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 318 Comprendre les versions (semver)
  • 319.
    | Node.js – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 319 Architecture interne de Node.js
  • 320.
    | Node.js – Exercicesbasiques • Ecrire un programme JavaScript qui permette d’afficher le texte « Hello World » un fois exécuté dans Node.js. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 320 L’incontournable « Hello World »
  • 321.
    | Node.js – Exercicesbasiques • Ecrire un programme JavaScript qui permette d’afficher le texte « Hello World » un fois exécuté dans Node.js. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 321 L’incontournable « Hello World » console.log("Hello World!"); Fichier hello.js $ node hello.js Hello World! $ _ Terminal
  • 322.
    | Node.js – Exercicesbasiques • Ecrire un programme JavaScript qui permette d’afficher le texte « Bonjour <nom> ». Le nom de l’utilisateur étant récupéré en argument. • Aide : utiliser l’objet natif « process ». Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 322 Passage d’arguments
  • 323.
    | Node.js – Exercicesbasiques • Ecrire un programme JavaScript qui permette d’afficher le texte « Bonjour <nom> ». Le nom de l’utilisateur étant récupéré en argument. • Ecrire un deuxième programme qui permette d’afficher l’ensemble des arguments saisis. • Aide : utiliser l’objet natif « process » et le tableau argv. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 323 Passage d’arguments
  • 324.
    | Node.js – Exercicesbasiques Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 324 Passage d’arguments var name = process.argv[2]; console.log("Hello " + name + "!""); Fichier helloBis.js $ node helloBis.js Guillaume Hello Guillaume! $ _ Terminal
  • 325.
    | Node.js – Exercicesbasiques Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 325 Passage d’arguments var arguments = ""; for (var i=2; i < process.argv.length; i++) { console.log(process.argv[i]); } Fichier displayArgs.js $ node displayArgs.js Formation ORT 3CSi Lyon Formation ORT 3CSi Lyon $ _ Terminal
  • 326.
    | Node.js – Exercicesbasiques • Sur le même principe des exercices précédents, écrire un programme qui émule une calculatrice basique. Le premier argument sera le type d’opération (addition, soustraction, multiplication et division), et les suivants les nombres à calculer. • Bonnes pratiques : séparer bien votre code en plusieurs fonctions. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 326 Passage d’arguments
  • 327.
    | Node.js Création d’unserveur web Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 327
  • 328.
    | Node.js – Créationd’un serveur web • Node.js n’est pas un serveur web, c’est une plateforme / environnement d’exécution ! • Cet idée fausse que Node.js serait un serveur web commence sur le programme d’exemple « Hello World » qui implémente un serveur web. • Ce qu’ils essayent de démontrer c’est que Node.js est une plateforme, qui peut, dans cet exemple, permettre de gérer nativement le protocole HTTP. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 328
  • 329.
    | Node.js – Créationd’un serveur web Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 329 const http = require('http'); const hostname = '127.0.0.1'; const port = 1337; http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('Hello World!n'); res.end(); }).listen(port, hostname, () => { console.log('Server running at http://'+ hostname +':'+ port +'/'); });
  • 330.
    | Node.js – Créationd’un serveur web • Modifier le code précédent pour faire en sorte d’afficher les paramètres GET que l’utilisateur aurait saisi dans l’URL. • Vous devrez charger le module « url » pour récupérer les paramètres (utilisez la documentation https://nodejs.org/api/). • Astuce : passer par la fonction url.parse() Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 330 Exercice d’application
  • 331.
    | Node.js – Créationd’un serveur web Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 331 Exercice d’application const http = require('http'); const url = require('url'); const hostname = '127.0.0.1'; const port = process.env.PORT || 5000; http.createServer((req, res) => { var parsedUrl = url.parse(req.url, true); var queryAsObject = parsedUrl.query; res.end(JSON.stringify(queryAsObject)); }).listen(port, hostname, () => { console.log('Server running at http://'+ hostname +':'+ port +'/'); });
  • 332.
    | Node.js – Créationd’un serveur web • Créer un serveur HTTP avec Node.js qui retourne des données au format JSON quand : • Il reçoit une requête GET sur l’URI « /api/formatDateFr » • L’objet JSON doit retourner les propriétés année, mois, jours, heures, minutes ainsi qu’une propriété retourner la date du type : « Mardi 23 février 2016 à 12h00 ». • Il reçoit une requête GET sur l’URI « /api/formatDatetime » • L’objet JSON doit retourner une seule propriété dont la valeur est au format YYYY-MM-DD HH:ii:ss • Ces deux requêtes acceptent un paramètre GET « time » ayant pour valeur le temps UNIX (timestamp = nombre de ms écoulée depuis le 1er janvier 1970). • Retourner une erreur 404 si une autre URI du répertoire /api/ est appelée. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 332 Exercice d’application
  • 333.
    | Aparté Heroku Déploiement de vosapplications dans le Cloud. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 333
  • 334.
    | Heroku – Déploiementde vos applications sur le cloud • Heroku est un service de cloud computing de type PaaS, créé en 2007 puis racheté depuis par Salesforce.com. Il propose des services de cloud aux entreprises et développeurs (dont une version gratuite, mais limité à 5 apps). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 334 Présentation • PaaS = Platform as a Service (Plate-forme en tant que Service) • l'entreprise cliente maintient les applications proprement dites ; • le fournisseur cloud maintient la plate-forme d'exécution de ces applications (serveur, système d’exploitation, sécurité, etc.).
  • 335.
    | Heroku – Déploiementde vos applications sur le cloud Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 335 Présentation • Le modèle de cloud computing PaaS est à différencier du modèle SaaS. • SaaS = Software as a Service (logiciel en tant que service) • Modèle d'exploitation commerciale des logiciels. • Les logiciels sont installés sur des serveurs distants plutôt que sur la machine de l'utilisateur. • Les clients ne paient pas une licence d’utilisation mais un abonnement.
  • 336.
    | Heroku – Déploiementde vos applications sur le cloud • Plusieurs runtimes pris en charge par Heroku : Ruby on Rails, Node.js, Java, Spring, Python, Scala ainsi que PHP de façon officieuse. • Ces runtimes tournent dans un stack nommé « Cedar » qui tourne sous Ubuntu. • Intérêts de Heroku : • Déploiement très rapide d'applications web dans le cloud • Prise en charge de nombreux langages / technologies Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 336 Présentation
  • 337.
    | Heroku – Déploiementde vos applications sur le cloud Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 337 Présentation Les développeurs déploient le code (en CLI ou via GitHub) Les applications s’exécutent dans des « conteneurs » Vous pouvez gérer les applications depuis un tableau de bord. Gestion de la persistance des données : Postgres, Redis, etc. Les clients initient des requêtes qui sont envoyées et traités par l’application ciblée.
  • 338.
    | Heroku – Déploiementde vos applications sur le cloud • Google Cloud Platform permet également de déployer des applications Node.js dans le Cloud. • Il est plus probable que vous rencontriez Google Cloud Platerform que Heroku en entreprise. • Il n’y a pas de formule gratuite. Cependant, Google vous offre un crédit de $300 valable pendant 60 jours. Passé ce délais, ce crédit est perdu et votre instance de test est supprimée (vous ne serez pas facturé passé cette période d’évaluation si vous n’utilisez plus la plateforme). • Google a créé une bibliothèque d’abstraction qui facilite l’usage de Node.js lors du déploiement. • Tutoriel : https://cloud.google.com/nodejs/ Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 338 Solutions alternatives
  • 339.
    | Heroku – Déploiementde vos applications sur le cloud • Modulus : cloud pour Node.js, PHP, Java, Meteor, Docker, Python, etc. • Remarque : il existe aussi des plateformes Cloud dédiées au déploiement de votre base de données. C’est le cas de Google Cloud Datastore, Compose et MongoLab. On utilisera ce dernier dans la partie relative à MongoDB. • Votre application peut donc être hébergée entièrement dans le Cloud en quelques lignes de commandes… ! Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 339 Solutions alternatives
  • 340.
    | Heroku – Déploiementde vos applications sur le cloud Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 340 Inscription (gratuite) • Rendez-vous sur https://signup.heroku.com/ et créer un compte utilisateur gratuit. • Quelques limitations cependant : l’instance se mettra en sommeil après 30 minutes d’inactivités, et devra être stoppée 6h sur une période de 24 heures. • Suffisant pour notre usage de test…
  • 341.
    | Heroku – Déploiementde vos applications sur le cloud Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 341 Votre tableau de bord
  • 342.
    | Heroku – Déploiementde vos applications sur le cloud • Suivez le « Getting Started », partie « Setup » pour installer l’environnement Heroku sur votre poste : https://devcenter.heroku.com/articles/getting-started-with-nodejs#set-up • Cet environnement va vous permettre d’utiliser les commandes heroku pour votre terminal. • Vérifier que l’installation s’est bien terminée en tapant la commande heroku. • Identifiez-vous avec la commande heroku login. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 342 Déploiement d’une application Node.js
  • 343.
    | Heroku – Déploiementde vos applications sur le cloud • Nous allons déployer un serveur web basique (dans le même principe que notre premier exercice Hello World) sur la plateforme Cloud Heroku. • Si ce n’est pas déjà fait, lancer la commande npm init pour générer un fichier package.json. • Modifier le fichier package.json généré pour spécifier le script à lancer au déploiement de l’application. Cela ce fait via la propriété start de l’objet scripts : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 343 Déploiement d’une application Node.js { "scripts": { "start": "node index.js" } }
  • 344.
    | Heroku – Déploiementde vos applications sur le cloud • On doit adapter légèrement le code du serveur web. Le numéro de port sur lequel le serveur web va écouter ne peut pas être spécifié manuellement sur Heroku. On utilisera donc la variable d’environnement PORT : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 344 Déploiement d’une application Node.js const port = process.env.PORT || 5000; http.createServer((req, res) => { ... }).listen(port);
  • 345.
    | Heroku – Déploiementde vos applications sur le cloud • Si ce n’est pas déjà fait : lancer la commande npm install : cela va créer un répertoire node_modules. • Pour déployer les application, Heroku utilise GIT. On doit donc initier un repository git avec la commande git init. Cela va créer un répertoire cache .git à la racine de votre application. • Exécuter la commande « git add . » (le point est important !) pour ajouter l’ensemble des fichiers de votre application dans votre nouveau repository. Bien sur, il faut ensuite commiter vos changement avec la commande git commit –m "Votre message". Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 345 Déploiement d’une application Node.js
  • 346.
    | Heroku – Déploiementde vos applications sur le cloud • L’idée est en fait de faire un « push » de notre code dans une branche gérer par Heroku nommé « heroku ». • Pour créer cette branche et lancer l’écoute active par Heroku, exécuter la commande heroku create. • Ensuite on exécutera la commande : git push heroku master. Analyser bien les logs sur votre terminal, toutes les actions faites par Heroku sont décrites. A la fin du traitement, l’URL de votre projet dans le cloud s’affichera. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 346 Déploiement d’une application Node.js
  • 347.
    | Heroku – Déploiementde vos applications sur le cloud Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 347 Déploiement d’une application Node.js $ git push heroku master remote: Compressing source files... done. remote: Building source: remote: remote: -----> Node.js app detected remote: remote: -----> Creating runtime environment ... remote: -----> Launching... remote: Released v3 remote: https://secret-forest-98123.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/secret-forest-98426.git * [new branch] master -> master
  • 348.
    | Heroku – Déploiementde vos applications sur le cloud • Heroku va attribuer automatiquement une URL unique à votre application. • Au lieu de copier-coller l’URL de votre app Heroku, utiliser la commande heroku open. • Cependant, vous pouvez choisir manuellement une URL. Au moment de la création de la branche heroku dans votre repository GIT, utiliser plutôt la commande suivante (le troisième paramètre étant le nom que vous souhaitez donné à votre application) : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 348 Déploiement d’une application Node.js heroku create nodejs-formation-ort • Vous pouvez aussi utiliser la commande heroku apps:rename si votre app est déjà déployée.
  • 349.
    | Heroku – Déploiementde vos applications sur le cloud • En cas de modification de votre code source : • git add <file> • git commit –m "Message" • git push heroku master Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 349 Déploiement d’une application Node.js Cette dernière commande va automatiquement relancer le déploiement de votre application sur Heroku. La même URL sera conservée : c’est simplement un remplacement des fichiers modifiés.
  • 350.
    | Node.js Manipulation de fichier (lemodule FileSystem) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 350
  • 351.
    | Node.js – Lemodule « fs » (File System) • Le module du core « fs » de Node.js fournit une API qui permet d’interagir avec le système de fichiers et d'effectuer certaines opérations IO comme créer, lire ou écrire un fichier. • Comme « fs » est un module du core, nous n’avons pas besoin de la configurer avant de l’utiliser. Pour le charger, comme tout autre module CommonJS, on utilisera l’instruction require() : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 351 Présentation var fs = require("fs");
  • 352.
    | Node.js – Lemodule « fs » (File System) • Toutes les fonctions de ce module peuvent être utilisées de manière synchrone ou asynchrone. • Si vous utilisez la forme asynchrone, vous devrez utiliser une fonction de callback. • Les arguments passés à cette fonction de callback dépendent de la fonction utilisée. • Cependant, de manière générale, le premier argument est réservé à une exception. Si l’opération s’est bien passée, la valeur retournée par cet argument sera null ou undefined. • Les fonctions synchrone reprennent souvent le nom de la fonction asynchrone suivi de « Sync ». Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 352 Synchrone ou asynchrone ?
  • 353.
    | Node.js – Lemodule « fs » (File System) • Ce code d’exemple supprime le fichier /tmp/hello. On utilise la fonction unlink() du module « fs ». Le nom de cette fonction est un héritage de la norme POSIX. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 353 Suppression d’un fichier (asynchrone) const fs = require('fs'); fs.unlink('/tmp/hello', (err) => { if (err) { throw err; } console.log('successfully deleted /tmp/hello'); });
  • 354.
    | Node.js – Lemodule « fs » (File System) • Quand vous utilisez la version synchrone, les éventuelles exceptions sont immédiatement levees. Vous devez utilizer le bloc try / catch pour gérer ces exceptions. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 354 Suppression d’un fichier (synchrone) const fs = require('fs'); fs.unlinkSync('/tmp/hello'); console.log('successfully deleted /tmp/hello');
  • 355.
    | Node.js – Lemodule « fs » (File System) • Que fait ce code ? Identifiez-vous un problème ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 355 Ordre des opérations fs.rename('/tmp/hello', '/tmp/world', (err) => { if (err) throw err; console.log('renamed complete'); }); fs.stat('/tmp/world', (err, stats) => { if (err) throw err; console.log(`stats: ${JSON.stringify(stats)}`); });
  • 356.
    | Node.js – Lemodule « fs » (File System) • Avec des fonctions asynchrones, l’ordre des opération n’est pas garantie ! • fs.stat pourrait très bien être exécuté avant fs.rename. • Donc le code suivant est sujet à erreurs. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 356 Ordre des opérations fs.rename('/tmp/hello', '/tmp/world', (err) => { if (err) throw err; console.log('renamed complete'); }); fs.stat('/tmp/world', (err, stats) => { if (err) throw err; console.log(`stats: ${JSON.stringify(stats)}`); });
  • 357.
    | Node.js – Lemodule « fs » (File System) • En programmation asynchrone, vous devez toujours vous baser sur les callbacks. • Utiliser une chaine de callback entre rename et stat. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 357 Ordre des opérations fs.rename('/tmp/hello', '/tmp/world', (err) => { if (err) { throw err; } fs.stat('/tmp/world', (err, stats) => { if (err) { throw err; } console.log(`stats: ${JSON.stringify(stats)}`); }); });
  • 358.
    | Node.js – Lemodule « fs » (File System) • Si vous faites des traitements lourd, vous êtes fortement encourager à utiliser les appels asynchrones. • La version synchrone va bloquer le processus entier jusqu’à complétion de sa tâche. Comme Node.js est mono-threadé, toutes les autres connexions vont être stoppées (voir schéma d’architecture dans les slides précédentes). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 358 Ordre des opérations
  • 359.
    | Node.js – Lemodule « fs » (File System) • Plusieurs methodes pour créer un fichier : write, writeFile ou createWriteStream. Le plus simple est d’utiliser la function writeFile() du module : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 359 Création d’un fichier var fs = require('fs'); fs.writeFile("/tmp/test", "Hey there!", function(err) { if(err) { return console.log(err); } console.log("The file was saved!"); });
  • 360.
    | Node.js – Lemodule « fs » (File System) • Créer un serveur web avec Node.js. Chaque chargement de page doit incrémenter un compteur de visite contenu dans un fichier texte. Vous devrez donc : créer le serveur web, créer le fichier texte s’il n’existe pas, puis lire son contenu et incrémenter le nombre de visite. • Vous devrez charger les modules natifs « http » et « fs ». • Utilisez les fonctions asynchrones readFile() et writeFile() du module fs. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 360 Exercice d’application
  • 361.
    | Node.js – Lemodule « fs » (File System) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 361 Exercice d’application ... http.createServer(function (request, response) { fs.readFile("test.txt", 'utf-8', function (error, data) { response.writeHead(200, { 'Content-Type': 'text/plain‘ }); // Incrémenter le nombre obtenu a partir du fichier data = parseInt(data) + 1; // Mettre à jour le fichier (numéro incrémenté) fs.writeFile('test.txt', data); response.end(‘Page rafraichie ' + data + ' fois !'); }); }).listen(port); TODO : vérifier si la requête est sur le fichier favicon.ico. Dans ce cas ne pas incrémenter le compteur.
  • 362.
    | Node.js – Lemodule « fs » (File System) • Créer un programme asynchrone qui affiche sur la console une liste de fichiers dans un répertoire choisi et filtré par extension. • 1er argument : le répertoire ciblé • 2nd argument : l’extension à filtrer (ignorer les fichiers n’ayant pas cette extension). • Charger les modules « fs » et « path ». Vous pouvez utiliser les fonctions suivantes pour vous aider : • fs.readdir() pour lire le contenu d’un répertoire • path.extname() pour récupérer l’extension d’un fichier • Récupérer les arguments de votre programma via le tableau process.argv[]. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 362 Exercice d’application (2)
  • 363.
    | Node.js – Lemodule « fs » (File System) Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 363 Exercice d’application (2) var fs = require('fs'); var path = require('path'); var directory = process.argv[2]; var ext = '.' + process.argv[3]; fs.readdir(directory, function (err, files) { if (err) { throw err; } files.filter(function (file) { return fs.statSync(file).isFile(); }).filter(function (file) { return (path.extname(file) == ext); }).forEach(function (file) { console.log("%s (%s)", file, path.extname(file)); }); });
  • 364.
    | Node.js – Lemodule « fs » (File System) • La fonction readFile() permet de lire un fichier et d’afficher son contenu. • Utiliser cette fonction pour récupérer le contenu de fichiers HTML. • Créer un serveur HTTP avec Node.js, gérer plusieurs routes, et retourner une page HTML différente en fonction de la route. • Pensez-bien à adapter le header retourné : • Content-type : text/html • Content-length : la taille de la page HTML Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 364 Exercice d’application (3)
  • 365.
    | Node.js Création d’unmodule Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 365
  • 366.
    | Node.js – Créationd’un module • Un module encapsule du code correspondant au sein d’un même fichier. • Par exemple pour créer un module « foo » on créera un fichier foo.js. Pour charger le module on utilisera la fonction require() de CommonJS. On passera en argument le chemin relatif du fichier par rapport où on écrit ce code : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 366 var foo = require('./foo'); • Si vous utiliser le code suivant, le module « foo » devra être dans le répertoire « node_modules ». var foo = require('foo'); main.js main.js
  • 367.
    | Node.js – Créationd’un module • Pour pouvoir utiliser les fonction d’un module dans un autre fichier (par exemple le fichier où on a fait l’appel de la fonction require()), il faut exporter les fonctions du module = rendre public. • On utilisera l’objet natif module.exports pour exporter des fonctions. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 367 module.exports.myModuleFunction = function() { return "Hello World"; }; module.exports.mySecondModuleFunction = function() { return "Foo Bar"; }; foo.js
  • 368.
    | Node.js – Créationd’un module • Au final, le code suivant… Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 368 var foo = { myModuleFunction: function() { console.log("Hello World"); }, mySecondModuleFunction: function() { console.log("Foo Bar"); } } var foo = require('./foo'); • …est équivalent à :
  • 369.
    | Node.js – Créationd’un module • La fonction CommonJS require() retourne un objet qui reference la valeur de module.exports pour un fichier donné. • On peut maintenant accéder aux fonctions publics de foo.js via les propriétés rendues accessibles par la variable locale foo dans main.js. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 369 var foo = require('./foo'); foo.myModuleFunction(); // Affichera « Hello World » foo.mySecondModuleFunction(); // Affichera « Foo Bar » main.js
  • 370.
    | Node.js – Créationd’un module • Remarque : si votre module exporte une seule function, vous pouvez directement assigner une function anonyme à l’objet module.exports. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 370 module.exports = function() { return "Single module function"; }; foo.js
  • 371.
    | Node.js – Créationd’un module • On va refactoriser l’exercice précédent (qui consistait à lister les fichiers d’un répertoire) en créant un module. • Le module devra exporter une seule fonction qui prendra 3 arguments : • Le chemin du répertoire • L’extension sur laquelle filtrer • Une fonction de callback, utilisant la convention de nommage de Node.js : (err, data) : • err est égale à null s’il n’y a aucune erreur, ou retourne les erreurs de fs.readdir(). • data est un tableau contenant les fichiers filtrés • Aucun console.log() doit être initié par notre module. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 371 Exercice d’application :
  • 372.
    | Node.js – Créationd’un module • Dans le fichier du module, par exemple module.js, on assignera d’abord une fonction à l’objet module.exports (pour la rendre disponible). • Charger le module dans le fichier main.js avec l’instruction require() de CommonJS. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 372 Exercice d’application :
  • 373.
    | Node.js – Créationd’un module Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 373 Exercice d’application : var fs = require('fs'); var path = require('path'); module.exports = function(directory, ext, callback) { if (err) { return callback(err); } var ext = '.' + ext; var filesFiltered = files.filter(function (file) { return fs.statSync(file).isFile() && (path.extname(file) == ext); }); callback(null, filesFiltered); }; module.js
  • 374.
    | Node.js – Créationd’un module Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 374 Exercice d’application : var module = require('./module.js'); module(process.argv[2], process.argv[3], function(err, files) { if (err) { console.log("Error: " + err); } files.forEach(function (file) { console.log("%s (%s)", file, path.extname(file)); }); }); main.js
  • 375.
    | Node.js Utiliser les WebSocketsavec Socket.io Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 375
  • 376.
    | Node.js – Socket.io •Socket.io est une bibliothèque JavaScript pour développer des applications web en temps réel via l’utilisation des WebSocket. • Permet la communication temps réel et bidirectionnelle entre un ou plusieurs clients web et un serveur. • Socket.io fonctionne en deux parties (avec des API similaires) : • Une bibliothèque côté client qui s’exécute sur le navigateur • Une bibliothèque côté serveur pour Node.js Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 376 Présentation
  • 377.
    | Node.js – Socket.io Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 377 Présentation
  • 378.
    | Node.js – Socket.io •Socket.io est principalement utilisé pour des systèmes de communication en temps réel : messagerie instantanée, édition collaborative de document (comme Google Docs), streaming de données binaires (image / vidéo / audio). • Tout comme AJAX, le protocole WebSocket était géré différemment en fonction du navigateur utilisé. Socket.io corrige ce problème en apportant un support des différents navigateurs. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 378 Présentation
  • 379.
    | Node.js – Socket.io •Le web a été construit dans l’idée que : le client requête, le serveur répond. • Ce modèle est aujourd’hui dépassé : il ne correspond plus à l’usage que l’on se fait du web. • AJAX : premier pas vers la communication temps réel. Mais AJAX n’est pas en temps réel car il faut interroger le serveur régulièrement (pooling) pour récupérer des éventuelles modifications. Cette interrogation se fait via des requêtes AJAX émises chaque X secondes. • Problème en cas de forte affluence  surcharge du serveur. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 379 Présentation
  • 380.
    | Node.js – Socket.io •Pour palier à ce problème, une évolution de Ajax à vue le jour sous le terme « Ajax Long Pooling ». • Si le serveur ne retourne aucune donnée, la connexion du client est laissée ouverte. • Si aucune réponse après un certain temps (timeout), la connexion sera fermée. • Si une réponse est retournée par le serveur, la connexion est également fermée. • Ce modèle n’est toujours pas idéal… ce qui a poussé à l’implémentation des WebSocket. • Attention : ne pas confondre avec WebRTC (technologie permettant les communications directes entre navigateurs, sans passer par un serveur – utilisé en VOIP par exemple). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 380 Présentation
  • 381.
    | Node.js – Socket.io •Standard désignant un protocole réseau permettant de créer des canaux de communication full- duplex par-dessus une connexion TCP (pour les navigateurs et serveurs web). • Full-duplex ? Si l’information peut être transporté simultanément dans les 2 sens. Un canal de communication bidirectionnel n’est pas forcément full-duplex : il peut être half-duplex. • Ce canal permet de : • notifier le client d’un changement d’état du serveur, • d’envoyer des données (push) du serveur vers les clients connectés sans que ces derniers aient à effectuer la moindre requête. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 381 WebSocket
  • 382.
    | Node.js – Socket.io •Socket.io est un module CommonJS. Il est disponible sur le catalogue d’application npm. • Pour installer Socket.io sur Node.js puis le charger : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 382 Installation côté serveur / client npm install socket.io • Pour charger Socket.io côté client (une page web par exemple) : <script src="socket.io.js"></script>
  • 383.
    | Node.js – Socket.io Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 383 Utilisation côté serveur var http = require('http').createServer(handler) var io = require('socket.io')(http); http.listen(8080); function handler (req, res) { ... } • On créé ensuite un serveur web avec Node.js et on l’attache à une instance de Socket.io (sans oublier de définir des callback pour traiter les évènements).
  • 384.
    | Node.js – Socket.io Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 384 Utilisation côté serveur io.on('connection', function (socket) { socket.emit('news', { hello: 'world' }); socket.on('my other event', function (data) { console.log(data); }); }); • La dernière étape consiste à utiliser l’évènement « connection » de Socket.io qui est lancée lorsque le serveur à pu initier une connexion avec un client. • Dans ce cas là on envoi une donnée via la fonction emit(). Dans cet exemple on écoute également sur l’évènement « my other event » envoyé par le client.
  • 385.
    | Node.js – Socket.io Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 385 Utilisation côté client <script src="/socket.io/socket.io.js"></script> <script> var socket = io('http://localhost'); socket.on('news', function (data) { console.log(data); socket.emit('my other event', { my: 'data' }); }); </script> • Ensuite il faut indiquer à notre client (une page web par exemple), qu’il va devoir communiquer avec le serveur Socket.io.
  • 386.
    | Node.js – Socket.io •Pour interagir avec un serveur Socket.io, il n’est pas forcément nécessaire d’avoir un client sous la forme d’un navigateur web. On peut utiliser un script Node.js qui jouera le rôle du client… • Cela ouvre à de nombreuses possibilités ! Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 386 Remarque
  • 387.
    | Node.js – Socket.io •On suivra le guide « Get started : Chat Application » sur http://socket.io/get-started/chat/ pour créer notre première application temps réel utilisant les WebSocket. Il s’agit d’une application basique de type « chat ». • Quand vous aurez terminé, améliorer l’application de base en : • Donnant la possibilité aux clients de spécifier un nom d’utilisateur. • Afficher l’indicateur « <user> écrit » lorsqu’un utilisateur compose un message. • Afficher les personnes en ligne (par exemple dans un sidebar à gauche). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 387 Exercice d’application : création d’un chat temps réel
  • 388.
    Partie 5 Express Node.js webapplication framework
  • 389.
    | Express – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 389
  • 390.
    | Express – Présentation •Express est un serveur web pour Node.js. Il étend les fonctionnalités de base du serveur web de Node.js (module « http » que nous avons vu dans le chapitre précédent). • Express doit être vu comme un framework dans le sens où il apporte diverses fonctionnalités : • Serveur web HTTP • Module de routage (en fonction de l’URI, exécution d’une action précise) : dans le même principe que les routeurs des framework web modernes : exemples du routeur de Symfony2 ou Laravel). • Middleware (fonctions appelées après routage) • Gestion des erreurs Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 390
  • 391.
    | Express – Installation •Express est un module CommonJS. Vous pouvez l’installer en passant par le gestionnaire de paquets npm en exécutant la commande suivante : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 391 npm install express --save
  • 392.
    | Express – HelloWorld • Créer un nouveau répertoire pour cette application de test. Bonne pratique : lancer la commande npm init pour générer un fichier package.json contenant les métadonnées propres à votre application. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 392 var express = require('express'); var app = express(); app.get('/', function (req, res) { res.send('Hello World!'); }); app.listen(3000, function () { console.log('Example app listening on port 3000!'); }); • Ajouter Express en dépendance de votre application (voir slide précédente). • Créer un fichier app.js avec le code ci-contre. Pour lancer votre application, exécuter la commande node app.js.
  • 393.
    | Express – HelloWorld • On peut noter quelques ressemblances avec l’utilisation native de module http de Node.js. • Les deux syntaxes suivantes sont identiques : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 393 var app = express(); app.get('/', function (req, res) { res.send('Hello World!'); }); app.listen(3000) var app = express(); app.get('/', function (req, res) { res.send('Hello World!'); }); http.createServer(app).listen(3000); • Remarque : app n’est en fait qu’une fonction spéciale de Express.
  • 394.
    | Express – HelloWorld Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 394
  • 395.
    | Express – Générateurd’application • En complément d’Express, il peut être intéressant d’installer le générateurs d’applications Express. Cet outil permet de créer rapidement un squelette d’application. • Installation : • La structure d’application créée par le générateur est l’une des nombreuses manières possibles de structurer les applications Express. • Vous avez toute latitude pour l’utiliser ou la modifier en fonction de vos besoins. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 395 . ├── app.js ├── bin │ └── www ├── package.json ├── public │ ├── images │ ├── javascripts │ └── stylesheets │ └── style.css ├── routes │ ├── index.js │ └── users.js └── views ├── error.jade ├── index.jade └── layout.jade npm install express-generator -g
  • 396.
    | Express – Générateurd’application • Nous avons installé le générateur avec le flag –g ce qui rend le générateur accessible depuis n’importe quel répertoire. Il a été installé globalement et non dans le répertoire « nodes_modules » de l’application. • La commande suivante va créer une application Express nommée myapp dans le répertoire de travail en cour : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 396 express myapp cd myapp npm install npm start // Va lancer la commande spécifiée dans la propriété scripts.start du package.json
  • 397.
    | Express – Routage •Dans des frameworks web moderne comme Symfony ou Laravel (pour ne citer que eux) un composant appelé « routeur » existe. C’est le point d’entrée de votre application : toutes les requêtes HTTP initiées par les utilisateurs passeront par le routeur. • L’idée est de définir les routes de notre applications, c’est-à-dire les URI (partie après l’URL de base) possibles. • Le routeur va comparer l’URI de la requête cliente avec celles définies par l’application. Si il y a une correspondance, les actions définies dans la route est exécutée. Le routage n'est effectué qu'une seule fois par requête. • Le routeur d’Express fonctionne sur le même principe. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 397
  • 398.
    | Express – Routage •Dans des frameworks web moderne comme Symfony ou Laravel (pour ne citer que eux) un composant appelé « routeur » existe. C’est le point d’entrée de votre application : toutes les requêtes HTTP initiées par les utilisateurs passeront par le routeur. • L’idée est de définir les routes de notre applications, c’est-à-dire les URI (partie après l’URL de base) possibles. • Le routeur va comparer l’URI de la requête cliente avec celles définies par l’application. Si il y a une correspondance, les actions définies dans la route est exécutée. Le routage n'est effectué qu'une seule fois par requête. • Le routeur d’Express fonctionne sur le même principe. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 398
  • 399.
    | Express – Routage •Le programme « Hello World » définie une seule route sur l’URI « / ». Toute requête HTTP de type GET correspondant à cette route va lancer l’exécution de la fonction anonyme. • Deux paramètres sont passés à la fonction de callback : req pour obtenir des informations sur la requête initiée et res pour modifier la réponse. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 399 app.get('/', function (req, res) { res.send('Hello World!'); }); • L’ordre de la définition des routes dans votre application et important.
  • 400.
    | Express – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 400 app.get('/', function (req, res) { res.send('Requête GET sur la page d’accueil'); }); app.post('/', function (req, res) { res.send('Requête POST sur la page d’accueil'); }); app.put('/user', function (req, res) { res.send('Got a PUT request at /user'); }); app.delete('/user', function (req, res) { res.send('Got a DELETE request at /user'); }); app.all('/foo', function(req, res) { ... });
  • 401.
    | Express – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 401 • Vous pouvez chainer plusieurs routes répondant à la même URI mais à une action HTTP différente. C’est très utilise dans le cas d’une architecture RESTful. app.route('/book') .get(function(req, res) { res.send('Get a random book'); }) .post(function(req, res) { res.send('Add a book'); }) .put(function(req, res) { res.send('Update the book'); });
  • 402.
    | Express – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 402 • Vous pouvez avoir des routes dynamiques. Quelques exemples : app.get('/article/:id', function(req , res) { res.render('article' + req.params.id); }); app.get('/:name(article|article2|article3)?', function(req, res) { var name = req.params.name; res.render(name); }); app.get('/:id', function(req, res) { var id = req.params.id; }); Accessible depuis /article, /article2, /article3 ou / (grâce à l’opérateur ?).
  • 403.
    | Express – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 403 • Vous pouvez effectuer des tests basiques sur les paramètres de vos routes pour vous assurer que le format est bien celui attendu. Par exemple le regex « d+ » permet de spécifier un nombre entier. • Cette possibilité n’est pas encore documentée. Le double slash permet d’échapper le premier. app.get('/:foo(d+)', function(req, res){ // Get user info based on the user id (int). } app.get('/:bar(w+)', function(req, res){ // Get user info based on the user name (string). }
  • 404.
    | Express – Middleware •Les middleware sont des fonctions qui gèrent les requêtes. Elles se situent entre la requête brute et la réponse finale (d’où le nom « middle ware » : entre deux). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 404
  • 405.
    | Express – Middleware •Le serveur créé avec Express peut avoir une pile de fonctions middleware. Quand une requête arrive, elle est déléguée à la première fonction middleware de la pile. • Les fonctions middleware sont toujours invoquées dans l’ordre où elles sont ajoutés. • Chaque fonction middleware peut accéder aux objets request et response, ainsi qu’à la fonction middleware suivante dans la pile. • Chaque fonction middleware peut décider de « répondre » en appelant des méthodes sur l’objet response, et / ou en passant la requête à la fonction middleware suivante dans la pile en appelant la fonction next(). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 405
  • 406.
    | Express – Middleware •De manière schématisée, une fonction middleware ressemble à ça : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 406 function myFunMiddleware(request, response, next) { // Do stuff with the request and response. // When we're all done, call next() to defer to the next middleware. next(); } • Si une fonction middleware ne termine pas le cycle requête / réponse, elle doit obligatoirement appeler next() pour passer le contrôle à la fonction middleware suivante.
  • 407.
    | Express – Middleware •L’application Express suivante va répondre à deux routes définies : « / » et « /help ». • Supposons maintenant que nous voulons avoir un log à chaque fois qu’une requête sur l’une de ces deux routes est faite. • Une première approche serait d’ajouter dans chaque route le code permettant de loguer la requête (console.log par exemple). • Ce n’est pas l’idéal : duplication de code. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 407 var app = express(); app.get('/', function(req, res) { res.send('Hello World!'); }); app.get('/help', function(req, res) { res.send('Nope.. nothing to see here'); });
  • 408.
    | Express – Middleware •Au lieu de ça on va utiliser un middleware : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 408 var app = express(); app.use(function(req, res, next) { console.log('%s %s', req.method, req.url); next(); }); app.get('/', function(req, res, next) { res.send('Hello World!'); }); app.get('/help', function(req, res, next) { res.send('Nope.. nothing to see here'); });
  • 409.
    | Express – Middleware •Les fonctions middleware peuvent réaliser les tâches suivantes : • exécuter n’importe quel code, • modifier les objets requête / réponse (decorator), • terminer le cycle requête / réponse, • appeler la prochaine fonction middleware de l’application avec next(). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 409
  • 410.
    | Express – Middleware •Une application Express peut utiliser les types suivants de middleware : • Application-level middleware • Router-level middleware • Error-handling middleware • Built-in middleware : 1 seule pour l’instant, static() permettant de servir des fichiers statiques • Third-party middleware : cookie parse, Passport, etc. • Nous n’allons pas voir dans cette présentation le détail de chaque type de Middleware. Si besoin, la documentation officiel donne des exemples précis : http://expressjs.com/en/guide/using- middleware.html Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 410
  • 411.
    | Express – Middleware •Exemple de Middleware permettant de gérer les sessions avec Express : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 411 var express = require('express'); var redis = require("redis"); var session = require('express-session'); var redisStore = require('connect-redis')(session); var client = redis.createClient(); var app = express(); app.use(session({ secret: '...', store: new redisStore({ host: 'localhost', port: 6379, client: client }), saveUninitialized: false, resave: false })); Le module « connect-mongo » fonctionne sur le même principe mais avec MongoDB
  • 412.
    | Express – Moteurde template • Express n’est pas un moteur de template, mais il peut faire appel à un moteur de template externe (un autre module qu’on installera via npm) pour retourner des pages HTML. • Passer par npm pour utiliser le moteur de template de votre choix. • Nous allons installer jade via la commande : • Pour indiquer à Express qu’on utilise ce moteur de rendu, et que les templates sont stockés dans le répertoire views on doit passer par des instructions set. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 412 npm install jade --save app.set('view engine', 'jade'); app.set('views', './views')
  • 413.
    | Express – Moteurde template • Création d’un template Jade (plus d’infos sur la syntaxe sur http://jade-lang.com/) : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 413 html head title!= title body h1!= message • Puis, créez une route pour générer le fichier index.jade. Si la propriété view engine n’est pas définie, vous devez spécifier l’extension du fichier view. Sinon, vous pouvez l’omettre. app.get('/', function (req, res) { res.render('index', { title: 'Hey', message: 'Hello there!'}); });
  • 414.
    | Express – Exercices •Utiliser le générateur pour créer un squelette d’application. • Nous n’avons pas encore vu comment ajouter une couche de persistance à nos applications. Créer un tableau JavaScript ayant plusieurs objets correspondant chacun à des articles de blog. Propriétés : title, content, author, created_at. • Votre application devra comporter les pages suivantes : • Page d’accueil qui listes les articles par ordre chronologique (si vous avez le temps, implémenter une pagination). • Détail d’un article Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 414
  • 415.
    Partie 6 MongoDB The next-generationdatabase that lets you create applications never before possible…
  • 416.
    | MongoDB – Présentation •Nous avons maintenant une plateforme en place (Node.js), ainsi qu’un serveur web (Express). L’architecture MEAN vue dans la partie 3 prend forme. Cependant, sans moyen de persistance des données, les applications que nous pouvons développer seront vite limités en fonctionnalités. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 416 • MongoDB est une système de gestion de base de données open source de type NoSQL. • Il a été créé en 2009 et est depuis largement utilisé du fait de sa simplicité. • Il est écrit principalement en JavaScript. L’utilisation de JavaScript et de JSON pour la représentation des données stockées, fait que MongoDB est un acteur de choix dans MEAN.
  • 417.
    | MongoDB – Basesde données relationnelles • Quand on parle de base de donnée, on pense immédiatement au langage SQL permettant de rechercher, d'ajouter, de modifier, de supprimer ou de faire des jointures sur des données dans les bases de données relationnelles. • Une base de donnée est dite relationnelle quand elle applique le modèle relationnel introduit par Edgard Codd au début des années 70, et depuis largement utilisé. • Dans ce type de base de données, l'information est organisée dans des tableaux à deux dimensions : ce qu’on appel des tables. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 417
  • 418.
    | MongoDB – Basesde données relationnelles • Les données organisées dans les tables s’appellent des enregistrements. • Les noms des colonnes sont appelées des attributs. • On parle aussi de relation pour désigner les tables. • Les opérations d'algèbre relationnelle telles que l'intersection, la jointure ou le produit cartésien sont utilisées pour faire des rapprochements entre les enregistrements et créer de nouvelles relations à partir des relations enregistrées dans la base de données. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 418
  • 419.
    | MongoDB – Basesde données relationnelles • Pour faciliter l’exploitation des données depuis une application, on peut présenter le contenu d'une base de données relationnelle sous forme d'objets. Cela passe par l’utilisation d’un ORM (Object Relational Mapping). • Un ORM donne simplement l'illusion de travailler avec une base de données orientée objet. Généralement une classe (un « Modèle ») représente une table en base de données. Par exemple on instancie cette classe pour créer un nouvel enregistrement. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 419 // Création d’un user avec Eloquent (Laravel) $user = new User; $user->name = 'John'; $user->age = 30; $user->save(); // Requêtage et mise à jour d’un vol Flight::where('active', 1) ->where('destination', 'San Diego') ->update(['delayed' => 1]);
  • 420.
    | MongoDB – Basesde données relationnelles • Un ORM est donc une couche d’abstraction : le langage SQL n’est plus manipulé de manière directe, et la manipulation des modèles est beaucoup plus aisé. • Mais par fois il est difficile pour un ORM de faire cette connexion entre un système basé sur les objets et un système relationnel. • Héritage : c’est la façon dont on définit des relations dans un langage orienté objet. Mais comment représenter ces relations dans une base de données relationnelle ? • Vous ne pouvez pas avoir des tables qui héritent d’autres tables. • Donc au final les ORM doivent forcément faire des compromis… Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 420
  • 421.
    | MongoDB – Basesde données relationnelles • Dans une base de données relationnelle, il y a plusieurs façon de simuler ce lien d’héritage : Soit l’héritage ci-contre : • Première méthode : ajouter des champs propres aux employés et managers dans une table personne. Et en fonction de la ressource, alimenter ou non ces champs. • Seconde méthode : avoir plusieurs tables Person, Employee, Manager avec des relations 1-1. Mais par contre ont doit au final gérer des jointures de tout les côtés. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 421
  • 422.
    | MongoDB – Basesde données relationnelles • Donc bien qu’a première vue les ORM semblent être simple, ils essayent de connecter ensemble des systèmes qui sont fondamentalement différents. • Dans ce cas là, si les bases de données relationnelle ne sont pas adaptés aux langages de programmation orientés objet, ne devrait t’on pas opter pour une autre solution, un autre système de représentation des données ? • Modèle relationnel  Marteau de Maslow ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 422 « Si le seul outil que vous avez est un marteau, vous tendez à voir tout problème comme un clou ». Abraham Maslow
  • 423.
    | MongoDB – Vousavez dit NoSQL ? • Le terme « NoSQL » désigne un type de base de données qui n’utilise pas le modèle relationnel. • Généralement le langage SQL n’est pas utilisé pour requête ces bases de données. Le terme NoSQL est trompeur car il signifie « Not Only SQL » (pas seulement SQL). On aurait plutôt du l’appeler « Not Only Relational Databases ». • NoSQL est une mouvance, et non une technologie spécifique ou un produit. Il y a plus de 230 SGBD NoSQL recensés en février 2016 (cf nosql-database.org). • Des acteurs comme Google, Linkedin, Amazon ou Facebook conçoivent et exploitent des bases de données de type NoSQL. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 423
  • 424.
    | MongoDB – Vousavez dit NoSQL ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 424 Quelques systèmes de gestion de base de données NoSQL
  • 425.
    | MongoDB – Vousavez dit NoSQL ? • Vous ne pouvez pas ajouter un enregistrement qui ne correspond pas au schéma. • Vous devez spécifier la valeur NULL pour les champs non renseignés d’un enregistrement. • On doit prendre en compte le type de données : vous ne pouvez pas ajouter une chaine de caractère dans un champ entier. • Vous ne pouvez pas ajouter des enregistrement dans un champ : vous devez créer une autre table et utiliser une pair de clé étrangère / clé primaire pour lier ces deux tables, et enfin faire une jointure pour récupérer les données complètes. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 425 Dans une base de données relationnelle :
  • 426.
    | MongoDB – Vousavez dit NoSQL ? • Il n’y a pas de notion de schéma : au sein d’une même « table », les « enregistrements » peuvent avoir une structure totalement différente. Les champs peuvent être ajoutés, modifiés, supprimés d’un enregistrement à l’autre et ce à n’importe quel moment ! • Il n’y a pas de champs inutilisés. • Il n’y a pas de type de données (ils sont implicites). • La plupart des traitements sont fait dans la couche application. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 426 Dans une base de données non relationnelle (= NoSQL) :
  • 427.
    | MongoDB – Vousavez dit NoSQL ? • Parfait pour les bases de données larges et distribuées. • On a par fois besoin de stocker des données qui ne sont pas structurées (à la différence de données insérées dans un table qui doivent correspondre à un schéma bien précis : les différents champs de la table) ou dont le nombre / type de champs peut varier d’un enregistrement à l’autre. • Logs, données scientifiques, pages web, (Champ 1, Champ 2, Champ 3… Champ n), etc. • Facilité de mise en place et de développement. • Scalabilité horizontale aisée (= ajout de serveur). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 427 Pourquoi utiliser NoSQL ?
  • 428.
    | MongoDB – Vousavez dit NoSQL ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 428 Pourquoi utiliser NoSQL ?
  • 429.
    | MongoDB – Vousavez dit NoSQL ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 429 Pourquoi utiliser NoSQL ?
  • 430.
    | MongoDB – Vousavez dit NoSQL ? • NoSQL supprime toute la complexité des requêtes SQL. • NoSQL fonctionne très bien en cluster. • NoSQL peut gérer une nombre très important de données (ce qu’on appel le Big Data). • Les SGBD NoSQL sont en grande partie open source. • Dans le grande majorité des bases de données NoSQL, aucune gestion des transaction n’est prévue. Elles doivent être gérées au niveau de la couche applicative. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 430 Particularités
  • 431.
    | MongoDB – Vousavez dit NoSQL ? • Donc totalement différent du modèle ACID appliqué par les SGBDR : • Atomicity / atomicité : assure qu'une transaction se fait au complet ou pas du tout. si une partie d'une transaction ne peut être faite, il faut effacer toute trace de la transaction et remettre les données dans l'état où elles étaient avant la transaction. • Consistency / cohérence : assure que chaque transaction amènera le système d'un état valide à un autre état valide ( par exemple vérification sur les contraintes d’intégrité). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 431 Particularités
  • 432.
    | MongoDB – Vousavez dit NoSQL ? • Donc totalement différent du modèle ACID appliqué par les SGBDR : • Isolation / isolation : toute transaction doit s'exécuter comme si elle était la seule sur le système. Aucune dépendance possible entre les transactions. • Durability / durabilité : assure que lorsqu'une transaction a été confirmée, elle demeure enregistrée même à la suite d'une panne d'électricité ou d’un autre problème.  ACID est pessimiste, alors que NoSQL est optimiste ! Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 432 Particularités
  • 433.
    | MongoDB – Vousavez dit NoSQL ? • Il existe plusieurs types de base de données NoSQL. On peut les classifier par la manière dont ils traitent les données. Chacune de ces solutions à ses propres forces et faiblesses. • Key-Value (ce que fait Redis par exemple) • Document-oriented (utilisé par MongoDB) • Column-oriented • Graph Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 433 Types de base de données NoSQL
  • 434.
    | MongoDB – Orientédocument • Les données sont modélisées dans des objets JavaScript appelés documents. • Les documents stockés par MongoDB sont de type BSON. Les objets BSON sont la représentation binaire des objets JSON en leur ajoutant des améliorations et des capacités supplémentaires (expressions régulières, gestion des dates, etc.). • Chaque document possède un identifiant unique généré par MongoDB : la propriété « _id ». Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 434 // Exemple de document dans MongoDB { first_name: "Paul", surname: "Miller", city: "London", location: [45.123,47.232], cars: [ { model: "Bentley", year: 1973, value: 100000, ….}, { model: "Rolls Royce", year: 1965, value: 330000, ….}, ] }
  • 435.
    | MongoDB – Orientédocument • Les documents sont stockés dans des collections (qu’on pourrait rapprocher aux tables). • Il faut voir une collection comme un amas de documents pas forcément uniformes. Car un document n’est jamais figé : les couples clé / valeur peuvent changer en fonction des données. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 435 Document
  • 436.
    | MongoDB – Orientédocument • Les documents sont stockés dans des collections (qu’on pourrait rapprocher aux tables). Il faut voir une collection comme un amas de documents pas forcément uniformes. • Ainsi, une base de données sous MongoDB contient donc des collections de documents. • Un SGBD MondoDB est composé d’une ou plusieurs base de données. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 436
  • 437.
    | MongoDB – Orientédocument Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 437 SGBDR • Les bases de données ont des tables. • Les tables ont des colonnes. • Les lignes ont de cellules. • Les champs contiennent des types de données simples. • Les schémas sont rigides. MongoDB • Les bases de données ont des collections. • Les collections ont des documents. • Les documents ont des champs. • Les champs contiennent : des types de données simples, des arrays ou d’autre documents. • Les schémas sont fluides.
  • 438.
    | MongoDB – Requêtage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 438 Création d’une collection CREATE TABLE users ( name VARCHAR(128), age NUMBER ) db.createCollection(“users”)
  • 439.
    | MongoDB – Requêtage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 439 Insertion INSERT INTO table (f1, f2, f3) VALUES (v1, v2, v3) db.collection.insert( {f1: v1, f2: v2, f3: v3} ) db.comments.insert({ 'discussion_id': discussion_id, 'slug': slug, 'posted': datetime.utcnow(), 'author': author_info, 'text': comment_text })
  • 440.
    | MongoDB – Requêtage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 440 Modification UPDATE table SET f1 = v1, f2 = v2 WHERE f3 = v3 db.collection.update( {f3: v3}, {$set: {f1: v1, f2: v2} } )
  • 441.
    | MongoDB – Requêtage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 441 Sélection SELECT f1, f2 FROM table WHERE f3 = 'foo' db.collection.find( {f3: 'foo'}, {f1: 1, f2: 1} ) db.users.find() db.invoices.find({id: 12}) db.customers.find({name:'John'})
  • 442.
    | MongoDB – Requêtage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 442 Commandes diverses show dbs // Voir les bases de données disponibles use foo // Choisir une base de données (ici switcher sur “foo”) db // Vérifier qu’elle est la base de données en cours show collections // Lister les collections de la base de données // Insérer des données foo = {"lastName": "Doe", "firstName": John, "dateBirth": 1970-06-24} db.test.insert(foo) db.test.find() // Récupérer les documents d’une collection
  • 443.
    | MongoDB – Requêtage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 443 Commandes diverses // Utiliser du JavaScript dans Mongo for (var i=0; i < 5; i++) db.test.insert({a:42, b:i}) // Vérifier l’ajout des documents db.test.find() // Retournera... {"_id": ObjectId("554a990f0ebf783b64a56776"), "a": 42, "b": 0} {"_id": ObjectId("554a990f0ebf783b64a567ce"), "a": 42, "b": 1} {"_id": ObjectId("554a990f0ebf783b64a567cf"), "a": 42, "b": 2} {"_id": ObjectId("554a990f0ebf783b64a567d0"), "a": 42, "b": 3} {"_id": ObjectId("554a990f0ebf783b64a567d2"), "a": 42, "b": 4}
  • 444.
    | MongoDB – Requêtage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 444 Commandes diverses db.test.find({ b: {$gt: 2}}).sort({b: -1}) // Retournera... {"_id": ObjectId("554a990f0ebf783b64a567d2"), "a": 42, "b": 4} {"_id": ObjectId("554a990f0ebf783b64a567d0"), "a": 42, "b": 3}
  • 445.
    | MongoDB – Installation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 445
  • 446.
    | MongoDB – Installation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 446 • Télécharger MongoDB sur mongodb.com et installer l’archive sur votre poste. Sous Windows, le répertoire d’installer par défaut est dans Program FilesMongoDBServer. • MongoDB nécessite un répertoire pour stocker toutes les données. Créons ce répertoire en invite de commandes, en tapant la commande : md datadb
  • 447.
    | MongoDB – Installation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 447 • Pour lancer MongoDB, exécutez le fichier mongod.exe depuis votre terminal. • Ceci lance le processus de la base de données MongoDB. Le message « waiting for connections » sur l'invite de commandes indique que le processus mongod.exe a bien été exécuté.
  • 448.
    | MongoDB – Installation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 448 • Pour se connecter à l’instance de MongoDB il faut utiliser le Shell Mongo. • Exécutez le fichier mongo.exe depuis une autre fenêtre de terminal (pour ne pas tuer l’instance mongod). • Après le lancement de mongo, votre session va utiliser par défaut la base de données « test ». • Taper use <database> pour changer de base de données.
  • 449.
    | MongoDB Février 2016 FormationORT 3CSi - Guillaume MOREL-BAILLY 449 Exercice d’application • Installer MongoDB sur votre poste. • Lancer mongod. • Connectez-vous en utilisant mongo. • Créer une base de données, une collection et quelques documents. • Tester les requête de modification, suppression, sélection, etc.
  • 450.
  • 451.
    | Angular – Présentation •Sur la partie serveur, Node.js a de plus en plus clairement remporté la bataille. Côté client c’est le framework JavaScript AngularJS qui est devenu une référence (47K étoiles sur GitHub !). • AngularJS est un framework JavaScript côté client open-source développé par Google en 2009. • Framework MVC (Modèle Vue Contrôleur) et / ou MVVM (Modèle Vue – Vue Modèle). • Concepts clés : • Particulièrement adapté pour du Single Page Application (SPA) • Il étend le langage HTML par des directives HTML • Data Binding bidirectionnel • Injection de dépendances Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 451
  • 452.
    | Angular – Présentation •Première version nommée « AngularJS » • Actuellement en version 1.5.0 (février 2016) • Utilisé massivement en production, mais concurrencé par l’arrivée de Angular 2. • Développement verbeux et quelques concepts difficile à assimiler. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 452 On distingue deux versions du framework Angular : • Deuxième version nommée « Angular » • Actuellement en version beta. Pas de roadmap. • Rupture totale avec la version 1 : on peut presque le considérer comme un autre framework. • Plus simple, plus rapide.
  • 453.
    | Angular – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 453
  • 454.
    | Angular – Présentation •Angular 2 est encore en cours de développement. Cependant, il est possible de développer dés maintenant des applications. Le core va être amené à évoluer, mais globalement les bases sont posées. Ne pas utiliser en production ! • Vous serez sur le marché de l’emploi d’ici 1 à 2 ans… ils est plus judicieux de découvrir Angular 2. • Pourquoi Google a retiré la mention « JS » dans « Angular 2 » ? Google pousse l’utilisation du langage TypeScript en remplacement de JavaScript. Cependant, il est toujours possible de développer directement en JavaScript. • On peut également utiliser le langage de programmation Dart (développé par Google). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 454 Angular 2
  • 455.
    | Angular – Présentation •Se base sur les futurs standards du web : • WebComponents : a voir comme des widgets réutilisables. Ils font partie intégrante des navigateurs, et ne nécéssitent donc pas de librairie comme jQuery. Un Web Component existant peut être utilisé sans écrire de code, simplement en ajout la déclaration d'un import à une page HTML. Possibilité d’utiliser nos propres balises dans un code HTML. • ES6 / ES7 (en draft) / TypeScript • Réponce face au frameworks concurrents comme Ember.js et React (Facebook). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 455 Angular 2
  • 456.
    | Angular – Présentation •Langage de programmation open-source développé en 2012 par Microsoft, comme un sur- ensemble de JavaScript (tout code JavaScript peut être utilisé dans TypeScript). • Développé dans le but d’améliorer le code JavaScript (face aux manquements d’ECMAScript 5) : typage, interfaces, classes, modules, mixin, etc. • Le code TypeScript est transcompilé / transpiler vers JavaScript. • TypeScript supporte la spécification ECMAScript 6. Son intérêt est limité depuis l’arrivée d’ECMAScript 6. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 456 TypeScript (rappel)
  • 457.
    | Angular – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 457 TypeScript (rappel) class Greeter { constructor(public greeting: string) { } greet() { return "<h1>" + this.greeting + "</h1>"; } }; var greeter = new Greeter("Hello, world!"); document.body.innerHTML = greeter.greet(); • Exemple de code TypeScript (Hello World) : Comparaison de TypeScript VS JavaScript sur typescriptlang.org/Playground
  • 458.
    | Angular – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 458 TypeScript (rappel) npm install -g typescript • Comme TypeScript n’est pas un langage de programmation directement intégré dans nos navigateurs, nous devons l’installer. Le plus simple et de passer par npm :
  • 459.
    | Angular – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 459 Prise en main du framework • Aller sur https://angular.io/docs/ts/latest/quickstart.html et suivez les différentes étapes. • Comme Google conseille d’utiliser TypeScript, et que la grande majorité des tutoriaux ainsi que la documentation officiel se basent sur ce langage, sélectionner bien « Angular 2 for TypeScript » dans le menu déroulant.
  • 460.
    Partie 8 MEAN.JS Full-Stack JavaScriptUsing MongoDB, Express, AngularJS, and Node.js
  • 461.
    | MEAN.JS – Présentation •MEAN.JS est un framework JavaScript fullstack qui permet de faire communiquer les différentes couches de l’architecture MEAN. • Cela peut demander un peu de configuration. MEAN.JS permet de se concentrer sur la partie métier de votre application, plutôt que de faire du code boileplate. • Un bon framework n’avance pas la ligne d’arrivée, il avance la ligne de départ. Il faut choisir un framework qui inclus de la génération de code, des scripts, des tests, déploiement… c’est le cas de MEAN.JS. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 461
  • 462.
    | MEAN.JS – Présentation •MEAN.JS ne doit pas être confondu avec MEAN.io. • Les deux frameworks sont quasiment identiques puisque MEAN.JS est un fork de MEAN.IO. La même personne est à l’origine de ces framework. Cette personne c’est désolidarisé de MEAN.io après des points de divergence interne. • Quelques différences dans les outils utilisés : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 462 MEAN.JS MEAN.IO Système de build : Grunt Scaffolding : Yeoman Generators Système de build : Gulp Scaffolding : custom CLI nommé « mean »
  • 463.
    | MEAN.JS – Présentation •Un système solaire composé de 4 planètes (MongoDB, Express, AngularJS et NodeJS), et de satellites : • Yo : générateur • Grunt : build script (automatisation de tâches : minification, compilation, etc.) • Bower : gestionnaire de dépendance • Bootstrap : mobile support (responsive web design) • KarmaJS : pour écrire et lancer des tests unitaires • Passport : gestion de l’authentification sur des services externes • Tout ces outils / helpers sont là pour rendre le développement d’une application MEAN le plus facile possible Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 463
  • 464.
    | MEAN.JS – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 464 Remarque importante : AngularJS (version 1) est utilisée. Les développeurs ont prévu de migrer vers la version 2 lorsqu’elle sera finalisée.
  • 465.
    | MEAN.JS – Utilisation •En cours de rédaction… Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 465
  • 466.
    Partie 9 Meteor Complete platformfor building web and mobile apps in pure JavaScript.
  • 467.
    | METEOR – Présentation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 467
  • 468.
    | METEOR – Présentation •Meteor est un framework open-source de développement web en JavaScript basé sur Node.js. • Il s’inspire fortement de l’architecture / de la philosophie MEAN. • Il s’inscrit comme un framework « nouvelle génération » car il bouscule les codes : une application peut être développée simplement et rapidement avec Meteor. • Des mécanismes complexes comme la persistance client / serveur et le temps réel sont implémentés de manière native et transparente. Meteor apporte une couche d’abstraction à de nombreux problèmes et pièges qu’on pourrait rencontrer en temps normal. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 468 Première version : décembre 2011. Dernière version 1.2.1 (octobre 2015)
  • 469.
    | METEOR – Présentation •Le partage de code entre l’environnement client et serveur est possible avec Meteor. • Meteor repose sur Node.js. C’est ce qui permet de faire le lien entre la base de données de votre application et son interface utilisateur, tout en assurant que les deux restent bien synchronisés. • Les données de la base de données côté serveur peuvent être répliquées en tout ou partie sur les clients. De manière générale, les client ne manipulent jamais directement les données du serveur. Les modifications (ajout, modification, suppression) côté client sont synchronisées avec le serveur. • Cela permet une grande flexibilité. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 469
  • 470.
    | METEOR – Présentation •On peut alors effectuer des requêtes même en étant déconnecté du serveur. Lorsque le client sera de nouveau connecté au serveur les éventuelles modifications sur les données seront envoyées vers le serveur. • Programmation réactive côté client (Latency Compensation) : l’action est immédiate pour le client, mais le traitement côté serveur peut être différé ou mis en arrière plan. Exemple : envoi immédiat d’un message dans un chat via un bouton « Envoyer », alors que la transmission et la vérification côté serveur se fait en arrière-plan. • Votre application web Meteor peut être transformée en application mobile native iOS / Android en seulement quelques lignes de commandes. Apache Cordova est utilisé. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 470
  • 471.
    | METEOR – Présentation •Vous pouvez déployer votre application dans le cloud Meteor en 1 ligne de commande (sur le même principe que Heroku que nous avons vue dans la partie Node.js). • Optionnel : vous pouvez utiliser AngularJS ou React pour le partie client. • Hot Code Reload : les modifications que vous faites dans le code sont reportées en direct sur votre page (sans avoir à recharger votre page). • Pour toutes ces raisons, grand intérêt pour ce framework JavaScript dans la communauté des développeurs. • Levée de fonds de 11,2 millions de dollars en 2012. • De nombreux Meetup chaque année en France et dans le reste du monde. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 471
  • 472.
    | METEOR – Présentation •Meteor dispose de son propre catalogue de packages / modules : Atmosphere. • Il fonctionne sur le même principe que npm. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 472
  • 473.
    | METEOR – Présentation •La documentation de Meteor permet de prendre rapidement en main le framework. • Elle est complète et comprend beaucoup d’exemple de code. • Vous pouvez la consulter via : http://docs.meteor.com/ • Sur StackOverflow, le tag meteor est très actif : http://stackoverflow.com/questions/tagged/met eor Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 473
  • 474.
    | METEOR – Présentation •Le guide de Meteor permet de connaître les bonnes pratiques à utiliser lorsque vous développerez votre application. • Ce guide vient en complément de la documentation officielle. • Vous pouvez le consulter via : http://guide.meteor.com/ Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 474
  • 475.
    | METEOR – Plateforme Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 475 Infographie par @nwientge pour Meteorjs.club
  • 476.
    | METEOR – Plateforme Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 476
  • 477.
    | METEOR – Installation Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 477 • Pour Windows : https://install.meteor.com/windows • Pour Mac OS et Linux : exécuter la commande curl https://install.meteor.com/ | sh • Au moment de l’installation, créer un compte développeur sur Meteor.
  • 478.
    | METEOR • Les slidessuivantes se basent en partie sur le livre Discover Meteor. • Une version en ligne, traduire par la communauté, est disponible depuis http://fr.discovermeteor.com. • Je vous invite à lire attentivement ce livre pour en apprendre d’avantage sur le développement d’application Meteor. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 478
  • 479.
    | METEOR – Premierspas • On suppose que vous avez installé Meteor sur votre poste. • Toute comme Node.js, Express ou MongoDB, Meteor fonctionne en ligne de commande. Une variable d’environnement a été créé vous permettant d’utiliser la commande meteor directement dans votre terminal. • Pour lister toutes les actions disponibles, exécuter la commande suivante : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 479 meteor help
  • 480.
    | METEOR – Premierspas • Nous allons maintenant créer notre premier application. La commande create de Meteor permet de créer une application basique (création du répertoire de projet, téléchargement des dépendances et génération d’un squelette basique). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 480 meteor create microscope • Exécuter la commande suivante pour lancer votre application : cd microscope meteor
  • 481.
    | METEOR – Premierspas Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 481
  • 482.
    | METEOR – Premierspas • Meteor à son propre gestionnaire de paquets et dépendance qui fonctionne sur le même principe que npm que nous avons vu dans les parties précédentes. Equivalent à la commande npm install <packageName>, la commande suivante permet d’ajouter un paquet : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 482 Ajout d’un paquet meteor add <packageName> meteor add twbs:bootstrap meteor add underscore • Ajoutons les 2 paquets suivant (Bootstrap comme framework CSS et Underscore qui apporte des fonctions utilitaires pour JavaScript.
  • 483.
    | METEOR – Premierspas Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 483 Ajout d’un paquet
  • 484.
    | METEOR – Premierspas • La commande précédente à téléchargé le paquet et ses éventuelles dépendances. • Dans le même principe que le fichier packages.json de npm, Meteor délègue la gestion des paquets installés à deux fichiers : .meteor/packages et .meteor/versions. • Vérifier que ces fichiers contiennent bien les paquets ajoutés. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 484 Ajout d’un paquet Suppression d’un paquet meteor remove <packageName>
  • 485.
    | METEOR – Premierspas • isopacks : paquets de Meteor pouvant fonctionner à la fois côté client et serveur • Paquets tiers : isopacks développés par la communauté. Dans le même principe que la catalogue npm ou que Packagist de Composer, la catalogue des paquets est géré par Atmosphere (http://atmosphere.meteor.com/). • Paquets locaux : dans le répertoire /packets • Paquets npm : ne fonctionnent pas directement avec la plateforme Meteor mais peuvent être utilisés par d’autres paquets en tant que dépendance. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 485 Types de paquet
  • 486.
    | METEOR – Premierspas • /client : exécuté que la par client • /server : exécuté que par le serveur • Tout le reste est exécuté à la fois par le client et le serveur. • /public : ressource statiques (images, css) • /lib : fichiers chargés par Meteor avant tous les autres • Fichiers main.* : chargés par Meteor après les autres Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 486 Structure d’une application Appelé par Meteor en fonction du contexte (client / serveur)
  • 487.
    | METEOR – Premierspas • Meteor trouvera et inclura automatiquement les fichiers que vous ajoutez dans le répertoire /client. • Ce qui signifie que vous n'avez jamais besoin d'écrire manuellement des chemins d'inclusion (include) pour les fichiers javascript ou CSS. • Au final, Meteor compilera tout dans un seul fichier minifié. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 487 Inclusion automatique des fichiers
  • 488.
    | METEOR – Premierspas • Les feuilles de style CSS sont automatiquement chargées et comprimées à la volée par Meteor, de sorte qu'elles doivent être placées dans le dossier /client, plutôt que /public comme le seraient les autres ressources statiques. • Même principe qu’avec Grunt (voir MEAN.JS). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 488 Feuilles de style
  • 489.
    | METEOR – Templates(Spacebars) • Meteor utilise son propre moteur de template nommé Spacebars. • https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md • Meteor garde les templates et leur logique séparés, et ces templates ne font rien par eux-même. • Un template est fichier HTML comprenant une balise ouvrante et fermante <template> • On utilise l’attribut « name » de cette balise pour spécifier le nom du template. • Donc le nom de fichier du template n’a pas d’incidence. Par convention, on nomme quand même le fichier par le nom utilisée dans l’attribut name. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 489 Présentation
  • 490.
    | METEOR – Templates(Spacebars) • Inclusion d’un template dans une page HTML : • Création du fichier de template (notez l’utilisation de la balise <template>) : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 490 Présentation <template name="postList"> <div class="posts page"> ... </div> </template> client/templates/posts/post_list.html {{> postsList}}
  • 491.
    | METEOR – Templates(Spacebars) • Itération sur une variable ici « posts » qui représente un tableau d’articles, puis appel du template permettant d’afficher le détail d’un article. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 491 {{#each posts}} {{> postItem}} {{/each}} client/templates/posts/posts_list.html <template name="postItem"> <h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3> </template> client/templates/posts/posts_item.html Appel d’une propriété de l’objet courant.
  • 492.
    | METEOR – Templates(Spacebars) • Afin d'exister, un template a besoin de helpers. • Dans l’exemple précédent, la variable « posts » est lié à un helper. • Template = affichage + itération (aucune logique métier ou de framework) • Helpers = assigne et prépare une variable à chaque variable  logique du template • On parle de « helpers du template » dans la terminologie Meteor. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 492 Helpers de template
  • 493.
    | METEOR – Templates(Spacebars) var postsData = [ { title: 'Introducing Telescope', url: 'http://sachagreif.com/introducing-telescope/' }, { title: 'Meteor', url: 'http://meteor.com' } ]; Template.postsList.helpers({ posts: postsData }); Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 493 client/templates/posts/posts_list.js Ces données viendraient normalement de la base de données… mais c’est un premier pas.
  • 494.
    | METEOR – Templates(Spacebars) • Tester l’application Microscope (celle du livre Discover Meteor) : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 494 // Cloner l’application depuis GitHub git clone https://github.com/DiscoverMeteor/Microscope.git github_microscope cd github_microscope // Changer de branche (chapitre 3:2 = templates) git checkout chapter3-2 // Lancer l’application meteor
  • 495.
    | METEOR – Collectionstemps réel • Les collections temps réel sont au cœur de Meteor. • Quelque soit l’application Meteor développé, les collections sont des éléments centraux. • A placer dans le répertoire « lib » pour quelles soient lancer en premier. • Nous allons voir comment synchroniser automatiquement des données et intégrer des collections dans les templates. • Une collection (à comprendre dans le sens MongoDB du terme) est une structure de données qui prend soin de conserver les données en base de données côté serveur et côté client. Une synchronisation est ensuite faite, en temps réel, avec chaque navigateur connecté. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 495
  • 496.
    | METEOR – Collectionstemps réel Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 496 Posts = new Mongo.Collection('posts'); lib/collections/posts.js • La collection Posts est disponible à la fois sur le client et sur le serveur (car dans /lib). • Collection (dans le sens Meteor) : librairie standard pour manipuler la couche persistance (MongoDB et local storage côté client). • Sur le client la collection est une copie d'un sous-ensemble de la réelle et canonique collection. La collection côté client est constamment mise à jour avec ce sous-ensemble, (la plupart du temps) de manière transparente.
  • 497.
    | METEOR – Collectionstemps réel • Agit comme une API dans votre base de donnée MongoDB. • Permet d'écrire des commandes Mongo telles que Posts.insert() ou Posts.update(). • On peut manipuler directement des collections / documents depuis le shell MongoDB. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 497 Collections côté serveur meteor mongo > db.posts.insert({title: "A new post"}); > db.posts.find(); { "_id": ObjectId(".."), "title" : "A new post"};
  • 498.
    | METEOR – Leshell meteor • Appelé depuis le terminal avec meteor shell • Donne un accès direct au code côté serveur de l’application. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 498
  • 499.
    | METEOR – Leshell mongo • Appelé depuis le terminal avec meteor mongo • Donne l'accès direct à la base de donnée de l'application. • Similaire au shell Mongo vu dans le chapitre précédent sur MongoDB. • Meteor inclue sa propre instance de MongoDB (vous n’avez pas besoin de l’installer). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 499
  • 500.
    | METEOR – Collectionstemps réel • Quand vous déclarez Posts = new Mongo.Collection('posts'); sur le client, ce que vous êtes en train de créer est un cache local dans le navigateur de la collection Mongo réelle. • Collection côté client en tant que “cache”  contient le sous-ensemble des données, et offre un accès rapide à ces données. • Ces documents sont stockés dans la mémoire du navigateur, ce qui signifie qu'y accéder est tout simplement instantané. • L'implémentation de Mongo côté client s'appelle MiniMongo. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 500 Collections côté client
  • 501.
    | METEOR – Collectionstemps réel • Comment la collection côté client synchronise ses données avec la collection côté serveur ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 501 Communication client / serveur // Changer de branche (chapitre 4:1 = collections) git checkout chapter4-1 meteor • Ouvrer deux fenêtre de votre navigateur, et accéder à la console JavaScript dans l’un des deux. Ouvrez aussi le shell Mongo (voir slide précédente). • Dans le shell Mongo, exécuter : db.posts.find();
  • 502.
    | METEOR – Collectionstemps réel • Dans le console du premier navigateur : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 502 Communication client / serveur Posts.findOne(); • Créer un nouveau article. Dans l'une des consoles navigateur, exécutez une commande d'insertion : Posts.find().count(); // 1 Posts.insert({title: "A second post"}); Posts.find().count(); // 2 • Vérifier sur le shell Mongo : db.posts.find();
  • 503.
    | METEOR – Collectionstemps réel • Ouvrir la console du 2nd navigateur et exécuter : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 503 Communication client / serveur db.posts.find(); // 2 • La collection côté serveur a été informé par la collection côté client d'un nouvel article, et a pris en charge la tâche d'insérer l'article dans la base de données Mongo et de renvoyer l'information à toutes les autres collections post connectées.
  • 504.
    | METEOR – Collectionstemps réel • En phase de développement vous serrez amené à manipuler souvent votre base de données en ajoutant des collections, créer des documents de tests… Il est par fois utile de repartir sur une base de données vierge. • La commande suivante permet de remettre à zéro les données. Avant d’exécuter cette commande, vous devez arrêter l’instance Meteor (CTRL + C sur la console Meteor). • Puis relancer votre application Meteor : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 504 meteor reset meteor
  • 505.
    | METEOR – Collectionstemps réel • Toujours en phase de développement, il est intéressant d’ajouter automatiquement des données de tests en base de données à chaque démarrage de l’application. • On utilise une fixture, représenté par un fichier JavaScript créé dans le répertoire /server (donc jamais chargé dans le navigateur d'un utilisateur). • Le code sera exécuté immédiatement quand le serveur démarrera, et fera des appels d'insertion sur la base de données. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 505 meteor reset
  • 506.
    | METEOR – Collectionstemps réel Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 506 if (Posts.find().count() === 0) { Posts.insert({ title: 'Introducing Telescope', url: 'http://sachagreif.com/introducing-telescope/' }); Posts.insert({ title: 'Meteor', url: 'http://meteor.com' }); } server/fixtures.js
  • 507.
    | METEOR – Collectionstemps réel • Maintenant que nous avons des articles en base de données, modifions le helper de template pour récupérer ces articles directement en base, au lieu d’un tableau statique depuis une variable. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 507 Template.postsList.helpers({ posts: function() { return Posts.find(); } }); client/templates/posts/posts_list.js
  • 508.
    | METEOR – Collectionstemps réel • Ajouter maintenant un article depuis la console d’un des deux navigateurs. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 508 Posts.insert({ title: 'Meteor Docs', author: 'Tom Coleman', url: 'http://docs.meteor.com' }); • Dans le navigateur, l’article apparait maintenant dans la liste (l’interface a été automatiquement mis à jour).
  • 509.
    | METEOR – Collectionstemps réel • Par défaut le paquet autopublish est activé. Dans ce cas là on a pas besoin de penser aux publications. • Permet de partager chaque collection dans sa totalité à chaque client connecté. • En production il ne faut pas activer le paquet autopublish, au risque de dévoiler des informations confidentielles (comme la base user contenant les mots de passe) ! Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 509 Publication et souscriptions des collections
  • 510.
    | METEOR – Collectionstemps réel • Instantanément les articles ne sont plus affichés (et donc plus contenu dans la base locale de chaque client connecté). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 510 Publication et souscriptions des collections meteor remove autopublish • Désactiver l’autopublish :
  • 511.
    | METEOR – Collectionstemps réel • Comment transférer seulement les articles que l'utilisateur a besoin de voir (en prenant en compte les choses comme la pagination) ? Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 511 Publication et souscriptions des collections Meteor.publish('posts', function() { return Posts.find(); }); server/publications.js Meteor.subscribe('posts'); client/main.js
  • 512.
    | METEOR – Publicationset Souscriptions • Meteor peut gérer une large quantité de données et être sécurisé. Il faut cependant comprendre comment le système de publications et souscriptions fonctionne. • Meteor = client + serveur. • Architecture appelée Database Everywhere : Meteor va prendre un sous-ensemble de votre base de données et le copier sur le client. • Au lieu d'envoyer du code HTML au client, une application Meteor va envoyer la donnée brute (data on the wire). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 512
  • 513.
    | METEOR – Publicationset Souscriptions • On peut accéder aux données instantanément, et même les modifier, sans attendre un aller-retour client > serveur (principe de Latency compensation). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 513
  • 514.
    | METEOR – Publicationset Souscriptions • Principe de la publication : décider quelles données vont être publiées sur les copies locales côté client. On parle alors de sous-ensemble. • Protocol appelé DDP (Distributed Data Protocol). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 514 Publication
  • 515.
    | METEOR – Publicationset Souscriptions • Cela assure qu'il n'y a aucun moyen possible qu'un client soit capable d'accéder à un article signalé. Assurez-vous juste que vous publiez seulement les données que vous voulez fournir au client. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 515 Publication Meteor.publish('posts', function() { return Posts.find({flagged: false}); }); server/publications.js
  • 516.
    | METEOR – Publicationset Souscriptions • Exemple : publier une collection dans sa totalité (ce que fait autopublish quand il est activé). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 516 Publication Meteor.publish('allPosts', function(){ return Posts.find(); }); server/publications.js
  • 517.
    | METEOR – Publicationset Souscriptions • Exemple : publier une collection partielle. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 517 Publication Meteor.publish('somePosts', function(){ return Posts.find({'author':'Tom'}); }); server/publications.js
  • 518.
    | METEOR – Publicationset Souscriptions • Exemple : publier des propriétés partielles. Exclusion de certains champs. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 518 Publication Meteor.publish('allPosts', function(){ return Posts.find({}, {fields: { date: false }}); }); server/publications.js
  • 519.
    | METEOR – Publicationset Souscriptions • On peut aussi combiner les deux exemples précédents (filtrer sur un auteur et retourner seulement les champs avec date = false). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 519 Publication Meteor.publish('allPosts', function(){ return Posts.find({'author':'Tom'}, {fields: { date: false }}); }); server/publications.js
  • 520.
    | METEOR – Publicationset Souscriptions Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 520 Souscription • Principe : spécifier aux clients quel sous-ensemble de données ils ont besoin à un moment donné. • Les données auxquelles vous souscrivez seront dupliquées sur le client grâce à Minimongo (implémentation de MongoDB côté client). Affichage seulement des articles écrits par un utilisateur précis.
  • 521.
    | METEOR – Publicationset Souscriptions Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 521 Souscription Meteor.publish('posts', function(author) { return Posts.find({flagged: false, author: author}); }); server/publications.js Meteor.subscribe('posts', 'bob-smith'); client/main.js
  • 522.
    | METEOR – Publicationset Souscriptions Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 522 Trouver (filtrer les données de la base locale) Template.posts.helpers({ posts: function(){ return Posts.find({author: 'bob-smith', category: 'JavaScript'}); } }); Côté client • Sélectionner un sous-ensemble précis de données.
  • 523.
    | METEOR – Routage •Iron Router est un package de routage qui a été créé spécialement pour les applications Meteor. • La commande suivante permet d’installer le paquet. Pensez à redémarrer votre instance de Meteor. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 523 Installation du routeur meteor add iron:router
  • 524.
    | METEOR – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 524 Relier des URLS à des templates
  • 525.
    | METEOR – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 525 Relier des URLS à des templates <head> <title>Microscope</title> </head> client/main.html • Le layout sera intégré dans ce template basique (nécessaire avec Meteor / handlebars).
  • 526.
    | METEOR – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 526 Relier des URLS à des templates <template name="layout"> <div class="container"> <header class="navbar navbar-default" role="navigation"> <div class="navbar-header"> <a class="navbar-brand" href="/">Microscope</a> </div> </header> <div id="main"> {{> yield}} </div> </div> </template> client/templates/application/layout.html Remplace notre précédent postsList
  • 527.
    | METEOR – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 527 Relier des URLS à des templates Router.configure({ layoutTemplate: 'layout' }); Router.route('/', {name: 'postsList'}); lib/router.js • Indique au routeur d’utiliser le layout précédent (« layout » correspond au nom du fichier). • Définition d’une nouvelle route appelée postsList. Assignation à l’URI « / ».
  • 528.
    | METEOR – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 528 Relier des URLS à des templates <header class="navbar navbar-default" role="navigation"> <div class="navbar-header"> <a class="navbar-brand" href="{{pathFor 'postsList'}}">Microscope</a> </div> </header> client/templates/application/layout.html
  • 529.
    | METEOR – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 529 Router vers un article spécifique <template name="postPage"> <div class="post-page page"> {{> postItem}} </div> </template> client/templates/posts/post_page.html
  • 530.
    | METEOR – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 530 Router vers un article spécifique ... Router.route('/', {name: 'postsList'}); Router.route('/posts/:_id', { name: 'postPage‘ }); lib/router.js • Nous allons créer une autre route nommée, cette fois en associant les chemins d'URL de la forme /posts/<ID> au template postPage :
  • 531.
    | METEOR – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 531 Router vers un article spécifique • Nous routons maintenant vers le template correct, mais il nous manque encore quelque chose : le routeur connaît l’_id de l'article que nous voulons afficher, mais le template n'a toujours pas d'indice. • Heureusement, le routeur a une solution intégrée intelligente : il vous laisse spécifier un contexte de données (data context). C’est ce avec quoi vous remplissez votre template.
  • 532.
    | METEOR – Routage Février2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 532 Router vers une page d’erreur Router.configure({ layoutTemplate: 'layout', loadingTemplate: 'loading', notFoundTemplate: 'notFound', }); lib/router.js <template name="notFound"> <div class="not-found page jumbotron"> <h2>404</h2> <p>Désolé, nous ne pouvons pas trouver une page à cette adresse.</p> </div> </template> client/templates/application/not_found.html
  • 533.
    | METEOR – Ajoutd’une donnée côté client • On a vu comment ajouter des données depuis la console du navigateur côté client. Pour rappel, dans l’application d’exemple on affiche une liste d’article. Pour ajouter un article on appelait l’instruction Posts.insert(). • On créera une interface graphique pour permettre aux utilisateurs d’ajouter un article. • On ajoute la route suivante dans le routeur : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 533 Construction de la page d’ajout d’article Router.route('/submit', {name: 'postSubmit'}); lib/router.js Correspond au nom du template. Meteor analysera le code de chacun des fichiers HTML de notre application à la recherche d’une balise <template> ayant pour attribut « name » la valeur « postSubmit ».
  • 534.
    | METEOR – Ajoutd’une donnée côté client • Ajout d’un lien dans l’entête de page. On référence directement la route plutôt que d’écrire l’adresse en dur : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 534 Construction de la page d’ajout d’article <ul class="nav navbar-nav"> <li><a href="{{pathFor 'postSubmit'}}">Créer un post</a></li> </ul> client/templates/includes/header.html
  • 535.
    | METEOR – Ajoutd’une donnée côté client Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 535 Construction de la page d’ajout d’article <template name="postSubmit"> <form class="main form page"> <input name="url" id="url" type="text" value="" placeholder="Votre URL" /> <input name="title" id="title" type="text" value="" placeholder="Nommez votre article" /> <input type="submit" value="Submit" /> </form> </template> client/templates/posts/post_submit.html • Inutile de préciser l’attribut « action » dans le formulaire HTML, car nous allons intercepter l’évènement d’envoi (submit) sur ce formulaire.
  • 536.
    | METEOR – Ajoutd’une donnée côté client • Pour plus de simplicité on utilise la bibliothèque jQuery. C’est tout à fait possible avec Meteor (après avoir installé le paquet correspondant). • L’utilisateur envoi le formulaire, un nouveau article est créé. Puis avec Router.go(), l’utilisateur est instantanément redirigé vers une autre page. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 536 Construction de la page d’ajout d’article Template.postSubmit.events({ 'submit form': function(e) { e.preventDefault(); var post = { url: $(e.target).find('[name=url]').val(), title: $(e.target).find('[name=title]').val() }; post._id = Posts.insert(post); Router.go('postPage', post); } }); client/templates/posts/post_submit.js
  • 537.
    | METEOR – Ajoutd’une donnée côté client Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 537 Sécurisation (validation d’accès) meteor remove insecure • Seul les utilisateurs authentifiés doivent pouvoir accéder au formulaire d’ajout d’article. • La sécurité des données est incluse dans les collections Meteor, mais elle est désactivée par défaut pour faciliter le développement. • Pour réactiver cette sécurité, on doit supprimer le paquet insecure :
  • 538.
    | METEOR – Ajoutd’une donnée côté client Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 538 Sécurisation (validation d’accès) • Sans ce paquet, les insert() côté client sur la collection des articles ne sont plus autorisés ! • Donc 2 solutions : • Définir quand un client et autorisé ou non à insérer un article. • Faire les insertions côté serveur.
  • 539.
    | METEOR – Ajoutd’une donnée côté client Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 539 Sécurisation (validation d’accès) • Définir quand un client et autorisé ou non à insérer un article : Posts = new Meteor.Collection('posts'); Posts.allow({ insert: function(userId, doc) { // autoriser les posts seulement si l'utilisateur est authentifié return !! userId; } }); lib/collections/posts.js !! : convertie une valeur en booléen Si useId est égale à 0, null ou undefined  retournera false.
  • 540.
    | METEOR – Ajoutd’une donnée côté client Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 540 Sécurisation (validation d’accès) • Grâce au code précédent (fonction allow), même en utilisant la console navigateur, l’utilisateur ne peut pas ajouter d’article s’il n’est pas authentifié.
  • 541.
    | METEOR – Ajoutd’une donnée côté client Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 541 Sécurisation (validation d’accès) • Définir quand un client et autorisé ou non à insérer un article – Sécuriser l’accès au formulaire. Router.route('/submit', {name: 'postSubmit'}); var requireLogin = function() { if (! Meteor.user()) { this.render('accessDenied'); } else { this.next(); }} Router.onBeforeAction(requireLogin, {only: 'postSubmit'}); lib/router.js On appelle ça un « hook de routage ». Peut être comparé aux middlewares de Express.
  • 542.
    | METEOR – Ajoutd’une donnée côté client Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 542 Sécurisation (validation d’accès) • Définir quand un client et autorisé ou non à insérer un article – Sécuriser l’accès au formulaire. // On va cacher le lien d’ajout si l’utilisateur n’est pas connecté <ul class="nav navbar-nav"> {{#if currentUser}}<li><a href="{{pathFor 'postSubmit'}}">Créer un post</a></li>{{/if}} </ul> client/templates/includes/header.html
  • 543.
    | METEOR – Ajoutd’une donnée côté client Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 543 Sécurisation (validation d’accès) • Définir quand un client et autorisé ou non à insérer un article – Sécuriser l’accès au formulaire.
  • 544.
    | METEOR – Session •Utile pour stocker des états éphémères (sans passer par une transmission de paramètre par URL). • Manipulation des sessions via l’objet natif et global Session. • Une session est caractérisée par une clé et une valeur. • Ajout ou modification d’une donnée en session : • Lecture d’une donnée en session : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 544 Session.set('foo', 'Lorem ipsum'); Session.get('foo');
  • 545.
    | METEOR – Gestiondes utilisateurs • La gestion des utilisateurs est facile avec Meteor. En quelques minutes on peut mettre en place un système d’authentification complet. • Meteor inclus nativement l’authentification. Cependant, il faut installer des paquets additionnel pour ajouter des connecteurs en fonction du ou des types d’authentification que vous souhaitez mettre en place. • Connexion par mot de passe (local) : accounts-password • Connexion depuis un compte Google : accounts-google • Connexion depuis un compte Twitter : accounts-twitter • Connexion depuis un compte Facebook : accounts-facebook Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 545 Utilise le protocole OAuth2 pour se connecter à des services tiers. meteor add accounts-password
  • 546.
    | METEOR – Gestiondes utilisateurs • Meteor permet de gérer nativement : • Connexion / Déconnexion • Création de compte • Validation de compte par email • Fonctionnalité mot de passe perdu • Possibilité d’utiliser le protocole OAuth 2 pour se connecter via un service tiers Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 546
  • 547.
    | METEOR – Gestiondes utilisateurs • Les comptes utilisateurs sont stockés dans la collection MongoDB « users » qui est automatiquement créé par Meteor sur le serveur. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 547 Collection « users » { _id: "bbca5d6a-2156-41c4-89da-0329e8c99a4f", // Meteor.userId() username: "cool_kid_13", emails: [ { address: "[email protected]", verified: true }, { address: "[email protected]", verified: false } ], createdAt: Wed Aug 21 2013 15:16:52 GMT-0700 (PDT), ... (voir slide suivante) }
  • 548.
    | METEOR – Gestiondes utilisateurs { ... (voir slide précédente) profile: { // The profile is writable by the user by default. name: "Joe Schmoe" }, services: { facebook: { id: "709050", // facebook id accessToken: "AAACCgdX7G2...AbV9AZDZD" } } } Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 548 Collection « users »
  • 549.
    | METEOR – Gestiondes utilisateurs Meteor.user(); // Retourne null si l’utilisateur n’est pas connecté Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 549 Collection « users » • Récupération de l’utilisateur courant : • Remarque : même avec l’auto-publication désactivée, Meteor (via le paquet comptes) auto-publie les détails de base du compte de l'utilisateur actuellement authentifié. Un utilisateur ne peut donc pas voir les détails d'un autre compte. • La publication publie donc seulement un objet utilisateur par utilisateur authentifié (et aucun si vous n'êtes pas authentifié).
  • 550.
    | METEOR – Gestiondes utilisateurs Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 550 Collection « users » • Par mesure de sécurité, le document user retourné par la collection pour l’utilisateur courant ne contient pas le même nombre de champs entre MongoDB côté serveur et la base de donnée côté client. • On remarque alors qu’une collection locale peut être un sous-ensemble sécurisé (dans le sens où les données retournées sont limitées). L'utilisateur authentifié voit seulement les informations nécessaires à son bon fonctionnement. ❯ Meteor.users.findOne(); Object {_id: "kYdBd8hr3fMPGPcii", username: "john"} Console navigateur
  • 551.
    | METEOR – Gestiondes utilisateurs • L’algorithme de chiffrement bcrypt est utilisé (particulièrement recommandé pour le chiffrement de données sensibles comme des mots de passe). • Documentation complète sur le module natif de gestion des utilisateurs / de l’authentification : • https://www.meteor.com/accounts • http://docs.meteor.com/#/full/accounts_api Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 551
  • 552.
    | METEOR – Gestiondes utilisateurs • Plutôt que de créer manuellement des templates d’authentification (formulaire de connexion, création de compte, etc.), vous pouvez installer le paquet suivant : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 552 Interface utilisateur meteor add accounts-ui-unstyled // Version sans aucune mise en forme meteor add accounts-ui // Version non Bootstrap meteor add ian:accounts-ui-bootstrap-3 // Version Bootstrap {{> loginButtons}} • Le template « loginButtons » est disponible. Il permet d’afficher un menu déroulant contenant les formulaires. On utilisera la syntaxe habituelle pour insérer le template :
  • 553.
    | METEOR – Gestiondes utilisateurs Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 553
  • 554.
    | METEOR – Gestiondes utilisateurs • Les utilisateurs assument généralement que leur état de connexion est partagée entre tous les onglets ouverts dans leur navigateur. • C’est-à-dire que si l’utilisateur à ouvert plusieurs onglets de votre application sur son navigateur, et qu’il se connecte sur l’un des onglets, il s’attend à être connecté automatiquement sur les autres onglets. • En pratique peut de site implémentent ce comportement. L’utilisateur doit recharger les autres onglets pour profiter de l’authentification (relecture de la session). • Meteor gère ça nativement en utilisant la base de donnée cliente (local storage) pour synchroniser l’état de connexion de l’utilisateur entre les onglets. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 554 Synchronisation de l’état de connexion
  • 555.
    | METEOR – Déploiementsur le cloud • Nous avons vu dans le chapitre consacré à la plateforme Node.js que nous pouvions déployer rapidement une application dans le cloud. Plusieurs solutions PaaS existent. Nous avions utilisé Heroku pour sa simplicité et sa gratuité. • Meteor met également à disposition une solution PaaS entièrement gratuite. • Documentation complète sur http://guide.meteor.com/deployment.html • Votre application sera déployée sur un sous-domaine du type http://yourApp.meteor.com. • Une seule ligne de commande suffit pour le déploiement des sources ! Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 555 meteor deploy your-app.meteor.com
  • 556.
    | METEOR – Déploiementsur le cloud • Suppression d’une application déployée sur Meteor.com : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 556 Commandes utiles meteor deploy --delete your-app.meteor.com • Voir les derniers logs : meteor logs your-app.meteor.com • Accéder à la base de données mongo : meteor mongo your-app.meteor.com
  • 557.
    | METEOR – Déploiementsur le cloud • La commande meteor deploy créé bien une base de données mais ne transfert par défaut pas vos collections MongoDB. Quelques étapes sont nécessaires pour déployer également votre base de données. • Les programmes mongodump et mongostore sont nécessaires. Ils peuvent être téléchargés sur mongodb.org/downloads (inclus dans le bundle). • Faire un dump de votre base de données MongoDB locale (-d : nom de votre base de données, -o : répertoire de destination du dump) : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 557 Déploiement de la base de données Mongo mongodump -h 127.0.0.1:3002 -d meteor -o meteor
  • 558.
    | METEOR – Déploiementsur le cloud • Exécuter la commande suivante pour connaitre l’URL de votre base de données distante MongoDB (créée lors du déploiement de votre application) : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 558 Déploiement de la base de données Mongo meteor mongo --url your-app.meteor.com // Retounera une adresse au format : mongodb://user:[email protected]:27017/your_app_meteor_com • La chaine « user:password » correspond au nom d’utilisateur et au mot de passe de votre instance distante MongoDB créés spécifiquement par Meteor.com lors du déploiement. Le nom du serveur peut changer.
  • 559.
    | METEOR – Déploiementsur le cloud • A partir de l’adresse récupérée dans le slide précédent, exécuter la commande suivante pour déployer vos collections (bien sûr, adapter les paramètres) : Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 559 Déploiement de la base de données Mongo mongorestore -u client -h sky.member1.mongodirector.com:27017 -d your_app_meteor_com -p 'password' folder/ Source : http://stackoverflow.com/questions/11024888/is-there-a-simple-way-to-export-the-data-from-a-meteor-deployed- app/16380978
  • 560.
    | METEOR – Déploiementsur le cloud • Le déploiement sur Meteor.com est parfait en phase de développement, mais n’est pas vraiment adaptée pour de la production (performances limités : chaque application est lancée dans un processus unique). • Galaxy est la solution PaaS professionnelle de Meteor. C’est un système distribué qui repose sur Amazon AWS. Plus d’infos sur https://galaxy.meteor.com/ Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 560
  • 561.
    | Meteor Exercice d’application : Créationd’une application Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 561
  • 562.
    | METEOR – Créationd’une application • Le développement de cette application compte pour votre partiel. • Vous pouvez vous baser sur les slides précédentes, mais également sur les autres chapitres de Discover Meteor qui n’ont pas été abordés ici. Le but est d’implémenter un maximum de choses dans le temps impartis. • Soyez créatif et appliquez-vous. • Vous avez passé un partenariat avec les boulangeries et restaurants de votre quartier. Vous souhaitez offrir un service à vos utilisateurs, pour leur permettre de passer commande de leur déjeuner, à partir d’un catalogue de restaurants (et leurs menus) directement depuis votre application. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 562
  • 563.
    | METEOR – Créationd’une application • Cela va permettre aux restaurateurs / boulangers (qu’on va simplifier par le terme « commerce ») de préparer leurs commandes en avance. Les clients n’auront plus qu’à aller récupérer leurs commandes prêtes. On pourrait même aller plus loin en imaginant un système de paiement en ligne… mais ce sera pour une autre fois. • Votre application aura plusieurs page : • Page d’accueil : affichage des commerces. • Détail d’un commerce : affichage des menus disponibles dans ce commerce et des informations sur le commerce (nom, horaires d’ouverture, téléphone, etc.). Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 563
  • 564.
    | METEOR – Créationd’une application • Votre application aura plusieurs page : • Un menu est caractérisé par un nom, un texte de description, un prix, et éventuellement une photo, un nombre de produit restant. • En face de chaque menu, un bouton permet de passer commande. Le passage d’une commande modifie le nombre de produit restant. • Si vous voulez allez plus loin, vous pouvez ajouter un espace d’administration permettant de gérer les commerces et leurs menus. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 564
  • 565.
    | METEOR – Créationd’une application • Bien sûr vous devez authentifier vos clients : l’idéal est de passer par un espace client (page d’inscription, de connexion, récupération du client connecté). Peut être qu’il y a des paquets tout prêt sur Atmosphere. • Votre base de données MongoDB contiendra plusieurs collections. • Cahier des charges : • Vous devez publier votre projet sur GitHub. • Vous pouvez publier votre application sur le cloud Meteor. • Vous devez utiliser Bootstrap pour votre interface utilisateur. Février 2016 Formation ORT 3CSi - Guillaume MOREL-BAILLY 565
  • 566.
    |Février 2016 FormationORT 3CSi - Guillaume MOREL-BAILLY 566 Merci de votre attention !