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 "wombat@npmjs.com" 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: "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) }
  • 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: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.
  • 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 !