Master 2 INTENSE 2019-2020 : Frameworks JavaScript et Server-Side JavaScript BD NoSQL Cloud etc.

De $1

Version de 11:15, 19 Avr 2024

cette version.

Revenir à liste des archives.

Voir la version actuelle

Introduction

Dans ce cours nous allons voir plusieurs aspects du développement Web Moderne :

  • Frameworks front end React, Angular, (VueJS a été vu l'an dernier)
  • Server Side JavaScript : NodeJS et principaux packages
  • Utilisation de la BD NoSQL MongoDB
  • Utilisation de base de données dans le cloud adaptées aux applis mobiles (syncrhonisées) comme FireBase
  • Hébergement dans le cloud, authentification via des services en ligne comme Oauth2
  • Développement en mode PAAS (Platform As A Service)

A faire : si vous êtes sous windows, installer un bon terminal en ligne de commande comme  http://cmder.net/ ou autre (github bash, etc.) si je vous vois avec une fenêtre DOS basique vous allez m'entendre !

Séance 1 : état des lieux du développement Web, intro à VueJS

Exemple de ce que peut apporter un framework par rapport à du pur JavaScript, ou à de simples librairies, ici le même exemple codé de trois manières différents:

  1. Avec pur JavaScript + DOM API : http://jsbin.com/gaqugic/edit
  2. Avec des librairies comme jQuery et Lodash : http://jsbin.com/posowem/edit?html,js
  3. Avec VueJS (et API Rest) : http://jsbin.com/dizigehata/1/edit?h...console,output

A propos de REST:

Remarque : on peu faire des requêtes REST avec XhR2fetch API(pour les curieux : quelques mots sur GraphQLet Appolo

On peut aujourd'hui gérer la progression des uploads et downloads avec fetch et l'API des streams (voir https://streams.spec.whatwg.org/demos/)

Avoir une vue de l'écosystème JavaScript (sites vus en cours)

 

Introduction à React

Supports de cours :

Exercices d'introduction, dans une IDE en ligne

On peut faire du react dans JsBin/JsFiddle/CodePen, mais croyez-moi, juste pour de petits exemples !

Exercice à faire en vous aidant des exercices précédents:

Pour vous donner une idée du résultat attendu,voici l'équivalent en VueJS: http://jsbin.com/guwetoy/1/edit?html,output

Je conseille de partir de cet exemple React: le composant en classe ES6 

En vous aidant de l'exemple fait en classe en live coding, voud devrez faire incrémentalement, en testant après chaque étape :

  1. Créez un <div> et affichez dedans un composant Root avec React (l'App des exemples)
     
  2. Affichez un tableau de hobbies dans ce <div> (foot, tennis, jeux video, etc.) sous la forme d'une liste. Chaque hobby sera un <li>. Vous fournirez des hobbies par défaut.
     
  3. Ajoutez un bouton 'Nouveau Hobby' et un champ input pour saisir le nom du hobbie à rajouter. La liste doit se mettre à jour.
     
  4. Rendez les hobbies clickables pour qu'on puisse les supprimer
     
  5. Un message <p>Hobby supprimé !</p> devra apparaitre lorsqu'un hobby est supprimé
     
  6. Ajoutez un compteur de hobbies (<p>Hobbies: 4</p>) au-dessus de la liste des hobbies, qui indiquera le nombre de hobbies dans la liste.
     
  7. Vous changerez les styles CSS des éléments de la liste pour qu'ils s'affichent en rouge et vert à chaque ligne, en alternance. Vous utiliserez aussi des classes CSS dynamiques pour afficher le compteur en rouge si le nombre de hobbies est supérieur à trois, en vert sinon. 
     
  8. Chaque <li>, chaque hobby, sera maintenant dans un composant <Hobby/> 

ICI UNE CORRECTIONhttps://codepen.io/w3devcampus/pen/xxKeJZW

Exercices avec un environnement "CLI"

Si on va voir la page de facebook sur "how to start with React", il y a un chapitre qui concerne le mode "CLI": https://reactjs.org/docs/add-react-to-a-new-app.html

  1. Vous devez avoir nodeJS correctement installé (node, npm, etc, tout ceci doit fonctionner...)
     
  2. Installez l'extension Google Chrome "React Developer Tools" (https://chrome.google.com/webstore/d...jfkapdkoienihi), elle existe aussi pour Firefox.
     
  3. Installez une bonne fenêtre terminal pour Windows -si vous êtes sous windows comme http://cmder.net/ ou autre (github bash, etc.) si je vous vois avec une fenêtre DOS basique vous allez m'entendre !
     
  4. Installer les packages "babel" et "emmet" si vous êtres sous Sublime Text 3 ou Atom. Ca doit etre ok pour Visual Studio Code, WebStorm etc.
     
  5. Ouvrir la ligne de commande et exécuter la commande "npm install -g create-react-app",
    • Pour vérifier que ça fonctionne, créez un autre répertoire nommé "react_cli" et cd dedans,
    • Executez "create-react-app hello-world" (ça prend du temps, quelques minutes)...
    • Allez dans le répertoire créé (cd hello-world), et faites "npm install" (là aussi, quelques minutes)
    • Exécutez le programme en tapant "npm start", ça doit ouvrir automatiquement le browser sur le port 3000 et afficher une page avec le logo React qui tourne.
    • Editez le code du fichier src/App.js, changez le texte et sauvez -> la page Web de l'application doit se rafraichir automatiquement.
       
  6. Maintenant on va étudier le code, regardez les fichiers html, js, les configs etc.
     
  7. Essayez de modifier la partie "render" de App.js... hmmm ok. Bon, on va faire un simple composant <Username name="toto"/> qu'on va mettre dans un sous répertoire "components" dans les sources, il va simplement afficher un nom passé en attribut/props dans un paragraphe en couleur. Vous ajouterez dans <App/> Plusieurs instances de ce composant.

Exercice: refaire dans le projet les hobbies en mode CLI !

Séance 2 : Utilisation de FireBase, une base de données basée cloud synchronisée

  1. Voir demo du prof :-)
     
  2. Vous allez le faire vous-même:

ETAPE 1 : Il faut commencer par modifier l'exemple des hobbies pour qu'il fonctionne non pas avec un tableau mais avec un objet. Firebase ne sais synchroniser que des objets, pas des tableaux:

Dans App.js :

   this.state = {
      hobbies : {
        hobby0: 'tennis',
        hobby1: 'golf'
      }
      // ...
    };

 Il faudra modifier plusieurs parties du code en conséquence...

  • addHobbies, removeHobbies...

    Hints: vous pouvez utiliser l'opérateur ES6 ... pour cloner un objet. 
     
  • render (il faudra itérer sur les propriétés d'un objet maintenant, excellent exercice !)

    Hint: Object.keys(this.state.hobbies).map((key, index) => {... }

Ex de code:

addHobby() {
/* OLD VERSION WITH ARRAY
const oldHobbies = this.state.hobbies;
this.setState({
hobbies: oldHobbies.concat(this.state.input),
input : ""
});
*/
 
  // faire une copie de l'objet hobbies
const hobbies = {...this.state.hobbies};
// Ajouter le nouveau hobby
const timestamp = Date.now();
hobbies[`hobby-${timestamp}`] = this.input.value;
 
this.setState({hobbies});
console.log(this.state.hobbies)
}
removeHobby(key) {
/* OLD VERSION WITH ARRAYS
const oldHobbies = this.state.hobbies;
const position = oldHobbies.indexOf(hobby);
this.setState({
hobbies: oldHobbies.filter((el, index) => {
return (index !== position)
}),
hobbyWasDeleted : true
});
*/
  // faire une copie de l'objet hobbies
     const hobbies = {...this.state.hobbies};
 
// Supprime le hobby dont la cle key a ete passee en parametres
//delete hobbies[key]; // ne marche pas avec firebase
hobbies[key] = null;
 
// Mettre a jour l'etat
// En ES6 vous pouvez juste taper {'hobbies'} au lieu de {hobbies:hobbies}
this.setState({hobbies});
}

Et pour render, exemple d'iterateur sur un objet, comparer par rapport au code qui itere sur un tableau, dans les exemples vus precedemment:
 

// iterateur sur les proprietes de l'objet
let list = Object.keys(this.state.hobbies).map((key, index) => {
// key = element courant (propriete courante de l'objet)
consthobby = this.state.hobbies[key];
const liStyle = {
backgroundColor:index % 2 === 0 ? 'lightpink' : 'red'
};
return <li key={key} style={liStyle} onClick={() => this.removeHobby(key)}>{hobby}</li>
});

ETAPE 2 : on va devoir, comme pour les exemples faits avec vueJS, utiliser le "cycle de vie" du composant (https://reactjs.org/docs/react-component.html#the-component-lifecycle), et charger des données distantes depuis FireBase quand le composant est "monté", et aussi fermer la connexion quand il est "démonté". On va pour cela définir les méthodes 

App.js : 

  componentWillMount() {
    console.log("Will mount")
    // this runs right before the <App> is rendered
  }

  componentWillUnmount() {
      console.log("Will unmount")
  }

  Implémentez ces méthodes et vérifiez bien qu'elles sont appelées...

ETAPE 3 : on va créer une base sur FireBase

  • Allez sur https://firebase.google.com/
     
  • Cliquez sur "accèder à la console" ou "Get Started" selon la langue...
     
  • Cliquez sur "+" pour ajouter un projet, appelez-le "React-INTENSE-hobbies" par exemple. Dans les fenêtres de dioaglogue ne cochez que la dernière case dans la première fenêtre, aucune dans la seconde.
     
  • Cliquez à gauche sur "database" et créer une "realtime database". Pas le choix en haut de la fenêtre (FireCloud)
     
  • Choisissez le mode "test" sans authentification.
     
  • Cliquez sur "ignorer" pour virer le warning.
     
  • Cliquez à gauche sur "Project Overview", et au milieu de la page sur "Ajouter Firebase à votre application Web", une fenêtre s'ouvre avec des bouts de JS. Voir cette image 
  • Gardez cet onglet ouvert

ETAPE 4 : on ajoute au projet le code pour se connecter à la base:

Dans votre projet, au même niveau que index.js, créez un fichier base.js, et mettez ceci dedans (attention a copier/coller les infos depuis le site, pour que cela corresponde à VOTRE BD)

import Rebase from 're-base';

const base = Rebase.createClass({
// copier les 3 premières lignes de VOTRE config de votre base !!!
 // NE PRENEZ PAS LES VALEURS QUI SONT ICI !!!
    apiKey: "AIzaSyCW_WJJb16YVDlsdsd9c0YNNGnfdssorzWGFRU2ScU",
    authDomain: "react-mbds-firebase.firebaseapp.com",
    databaseURL: "https://react-mbds-firebase.firebaseio.com" // pas de , à la fin
});


export default base;


ETAPE 5 : on ajoute le module npm re-base pour "parler à firebase"

On ajoute une ligne au fichier package.json pour installer la lib npm qui va bien:

  "dependencies": {
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "react-scripts": "1.0.17",
    "re-base": "2.2.0"// -> ajouter cette ligne, mettez bien 2.2.0 !
  },

 Faites "npm install", ça va installer re-base dans node_modules

ETAPE 6 : on va utiliser re-base pour synchroniser l'état du composant, c'est-à dire les hobbies:

Dans App.js:

....
import base from './base';
....

componentWillMount() {
    //alert("toto")
    // this runs right before the <App> is rendered
    this.ref = base.syncState("hobbies", {
      context: this,
      state: 'hobbies'
    });
  }

  componentWillUnmount() {
    base.removeBinding(this.ref);
  }


Etape 7 : testez !

Sauvez, testez. Ouvrez dans un onglet votre base et regardez les données en sync. Ouvrez deux onglets avec l'appli React, regardez...

Correction

Etape 8 (facultative) : héberger votre application sur firebase.com

A FAIRE POUR SEANCE SUIVANTE :

  • Regarder le livre sur React (celui sur les bases)
  • Regarder https://material-ui.com le site de la librairie de composants graphiques pour react la plus populaire. Ici un livre pour démarrer .
  • Essayer d'inclure cette librairie dans votre projet CLI et utiliser quelques composants graphiques pour le rendu.

Séance 3 : Node, MongoDB, cloud, Web Services RESTful

1 - installation (si ce n'est pas déjà fait) de MongoDB  et d'un outil d'administration

Nous allons poursuivre le cours en gérant maintenant un Back-End NoSQL, en l'occurence une base MongoDB, que nous utiliserons indifféremment localement ou dans le cloud.

Pour vérifier que vous avez bien installé MongoDB:

  1. Ouvrir une fenêtre de terminal et taper la commande "mongod"
    • Si tout va bien, cela devrait afficher une liste de traces et ne pas rendre la main. Bravo, MongoDB est correctement installé.
    • Si vous avez "command not found", vérifiez que 1) vous avez déjà installé MongoDB et 2) que votre variable PATH est correctement positionnée.
  2. Lancez un outil d'administration (peu importe celui que vous utilisez, l'outil officiel MongoDB Compass, ou un outil comme Studio 3T, ou un autre...)
  3. Vérifiez que vous avez encore la base de données de test des restaurants de l'année dernière, on va l'utiliser pour le TP... si ce n'est pas le cas, voici le fichier à importer: primer-dataset.json 

2 - Exemple de client de ces WebServices, en pur HTML/CSS/JS et utilisation de l'API fetch

  1. Récupérez cette archive qui est une version modifiée de l'exercice précédent: TPRoutageExpressWithMongo3.zip 
     
  2.  Dezipper, allez dans le répertoire créé (TPRoutageExpressWithMongo3) et faites "npm install"
     
  3. Exécutez node serverCrudWithMongo (ou nodemon)
     
  4. Ouvrez localhost:8080

  5. Etudiez le code, regardez en particulier comment, quand on clique sur le premier bouton GET AJAX un tableau est construit dynamiquement. 

3 - Ajouter le support "cross domain" à votre projet node/MongoDB

Ajouter les lignes suivantes dans la configuration de votre serveur (fichier serverCrudWithMongo.js), ça se passe dans la configuration de express, c'est l'équivalent des "Servlet Filters" en JavaEE :

app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE »);

    next();
});

4 - Heberger la base Mongo dans le cloud sur mlab.com et modifier votre programme

  1. Allez sur mlabs.com et ouvrez un compte
  2. Créez une base de donnée (mode Sandbox gratuit)
  3. Ajouter un utilisateur, par exemple admin/admin2019
  4. Lancez l'outil d'administration de MongoDB et connectez-vous sur la base que vous venez de créer
  5. Essayer d'importer à l'aide de l'outil d'admin les données JSON de :  primer-dataset.json ce sont les mêmes données utilisées par le programme de l'étape 3 du TP.
  6. Modifier le programme précédent (partie app-modules/crud-mongo.js) pour utiliser maintenant la BD située dans le cloud, sur mlabs.com. Attention vous devrez sans doute ouvrir un VPN ou utiliser votre téléphone en partgae de connexion car mlabs expose les BDs sur un port qui ne passe pas par unice-hotspot ou eduroam.
  7. Comment faire pour que votre programme travaille indifféremment sur mlabs ou en local sans le modifier ?

5  - Développer un client qui fait le CRUD sur les restaurants, mais en React

A RENDRE POUR SEANCE SUIVANTE. Noté.

Vous allez créer un autre projet react, dans un autre répertoire, à l'aide de la commande create-react-app.

Aide : refaire quelque chose de ce genre (ici en VueJS), mais avec React. Vous pourrez regarder les différents appels CRUD effectués à l'aide de la fetch API, que vous réutiliserez dans votre code React

  1. Récupérez cette archive 
  2. Dezippez-là
  3. Allez dans le répertoire et faites "npm install"
  4. Assurez-vous que MongoDB tourne (lancer mongod dans une fenêtre si ce n'est pas le cas)
  5. Exécutez "node serverCrudWithMongo.js"
  6. Ouvrez localhost:8080/tableVue.html
  7. Testez les fonctionnalités
  8. Regardez le code de tableVue.html pour une application VueJS assez "classique" réalisée sans utiliser le mode CLI de VueJS.

Démarrer le codage du client React : vous commencerez pas simplement afficher des restaurants dans une table. Peu importe si ce n'est pas joli... En vous inspirant du TP de la séance prtécédente sur les Hobbies, vous devriez y arriver sans problèmes.

On utilisera un tableau de restaurants dans le "state" de React en s'inspirant des exemples vus précédemment avec les hobbies. On utilisera la méthode componentDidMount() pour faire un fetch sur les restaurants avant l'affichage du composant principal (voit cycle de vie des composants React):

componentDidMount() {
    console.log("Composant avant premier affichage")
    // ici aller chercher des données dans une source de données (ex: GET /api/restaurants)
  }

Si vous avez récupéré le livre recommandé au début de cette section, il y a un chapitre qui s'intitule "Aller chercher les données" qui montre des exemples d'utilisation de fetch en React.