c) Les outils modernes pour développer des UI
Quels outils modernes seraient intéressants ?
Jusque-là, nous avons développé des applications web façon "old school".
Dans un précédent tutoriel, nous avons créé la HomePage
du site d'une pizzeria, en y ajoutant facilement deux animations grâce à une librairie externe (Animate.css).
Imaginez maintenant que le site web de la pizzeria continue à grandir.
Au fur et à mesure que nous allons lui ajouter des fonctionnalités, nous allons souhaiter utiliser de nouvelles librairies externes.
Pour chaque librairie externe que nous souhaitons ajouter, nous aurons à inclure une balise <script>
a sein d'index.html
.
Nous allons donc facilement, lors du développement d'une application web, utiliser une ou plusieurs dizaine(s) de librairies externes, que l'on appelle aussi dépendances.
La gestion de ces dépendances est difficile à gérer et à maintenir :
- Si vous souhaitez avoir des versions locales de ces dépendances, vous devez vous même manuellement télécharger les fichiers
.js
et.css
associés à vos librairies, inclure ensuite le bon chemin pour la propriétésrc
des balisesscripts
associées. - En cas de nouvelle version d'une librairie, vous êtes difficilement informé.
- La mise à jour d'une dépendance impose pas mal de manipulations : si vous utilisez des versions locales des dépendances, vous devez re-télécharger celles-ci, changer les propriétés
src
des balisesscripts
impactées... - Lorsque vous travaillez à plusieurs développeurs sur un même projet, pour que tout le monde obtienne les dépendances si vous utiliser des versions locales au serveur web, vous risquez de devoir mettre celles-ci en configuration (via Gitlab ou Github) ; c'est inapproprié de mettre en configuration le code de quelqu'un d'autre qui est déjà offert sur des web repos.
Ainsi, pour créer des IHM de manière moderne, nous souhaiterions bénéficier d'outils facilitant le développement.
Nous souhaiterions :
- une gestion moderne des dépendances (et de leur dépendances), via un gestionnaire de packages ;
- écrire du JS moderne et utiliser, si nécessaire, un outil pour transpiler le code vers du JS pour d'anciens browsers ;
- du hot reload: lorsque l'on modifie un script, l'application web doit se rafraichir automatiquement dans le browser ;
- que notre éditeur de code nous informe quand nous écrivons du JS qui ne répond pas à des conventions de programmation (linter) et qu'il nous aide à écrire du code conforme aux conventions (formatter) ;
- transformer les assets à la compilation (optimisation d'images, SASS vers CSS...)
- ...
Ainsi, à partir de maintenant, nous allons abandonner la programmation "old school" et découvrir des outils de programmation modernes, principalement les module bundlers.
Les modules bundlers
Un module bundler est un outil mis à la disposition des développeurs.
Il permet la gestion aisée des modules, packages et de leurs dépendances.
Probablement sa plus grande utilité et de permettre d'utiliser des packages faits pour Node.js (un environnement serveur) au sein d'un browser (un environnement client).
Certains modules bundler permettent d'autres fonctionnalités comme la gestion aisée des assets, la transpilation de code moderne vers du code ancien…
Voici quelques modules bundlers parmi les plus connus : Webpack [R.33], browserify, parcel.
Dans le cadre de ce cours, nous avons choisi Webpack.
Pour pouvoir installer cet outil, tout comme n'importe quel package, nous utiliserons le gestionnaire de packages de Node.js : npm.
A ce stade-ci, si ce n'est pas déjà fait, il est important que vous installiez l'environnement Node.js en version LTS [R.34]:
⚡ Attention à ne pas installer la dernière version de Node.js, mais bien la version LTS, sinon vous risquez beaucoup d'incompatibilités lors de l'exécution des boilerplates, tutoriels & démos du cours.
Comment démarrer la création d'une IHM moderne ?
Nous avons vu que pour créer une application web moderne, il est important d'utiliser un module bundler.
Il reste néanmoins encore à décider comment nous allons initier la création de nos projets pour bénéficier d'outils de développement modernes.
Voici les options possibles :
- Utiliser un boilerplate contenant le squelette d'une IHM (incluant une bonne configuration des outils de développement) et ses dépendances ; nous allons utiliser cette option dans le cadre de ce cours ;
- Utiliser un framework ou une librairie comme React, Vue ou Angular ; comme expliqué dans l'introduction, nous n'allons pas utiliser de Framework pour créer nos IHM. Nous trouvons ces frameworks très utiles, néanmoins nous estimons qu'il est primordial de bien pratiquer le Vanilla JS avant de se lancer dans un framework pour nos applications frontend.
- Créer et configurer son projet "from scratch" ; c'est une partie qui sera faite par les initiés ; en règle générale, les développeurs préfèrent utiliser des outils de développement déjà configurés plutôt que de devoir mettre en place tout l'environnement de développement. C'est ce qui fait notamment le succès de l'utilisation de frameworks, car ils offrent des outils de développement généralement bien configurés "out of the box" (en fournissant des boilerplates de base).
Comme expliqué ci-dessus, vous ne devez pas connaître comment configurer un module bundler pour bénéficier d'outils de développement modernes.
Nous estimons qu'il est important que vous compreniez comment pouvoir utiliser, et éventuellement modifier, une configuration de base offerte au sein d'un boilerplate.
🍬 Si néanmoins vous souhaitez approfondir la configuration d'un environnement de développement pour un frontend, à l'aide de Webpack, vous pouvez suivre ces deux tutoriels :
Ces deux tutoriels, totalement optionnels, expliquent comment le boilerplate de base du cours a été créé.
Création du squelette d'une IHM à partir d'un boilerplate
Nous allons faire un refactor du site de la pizzeria développé façon "old school" au module 1 en utilisant des outils de développement modernes.
Pour ce faire, nous allons utiliser le boilerplate de base du cours qui met à disposition un projet bien configuré.
Au fur et à mesure du tutoriel qui suit, nous allons comprendre ce qu'offre Webpack en tant que module bundler.
Dans votre repo web2
, nous allons créer le répertoire /tutorials/pizzeria/hmi/modern
en clonant le boilerplate.
Pour ce faire, veuillez ouvrir un terminal dans le répertoire /tutorials/pizzeria/hmi
.
NB : Il est possible de faire un clic droit dans l'Explorer de VS Code sur le répertoire hmi
, Open in Integrated Terminal
pour ouvrir un terminal au bon endroit :

NB : Nous vous conseillons, au sein de VS Code, de configurer pour avoir comme Terminal par défaut Git Bash. Pour ce faire, vous devez avoir installé Git sur votre machine.
Cliquez à droite du + au sein d'un terminal ouvert dans VS Code, clic sur Select Default Profile, puis sélectionnez "Git Bash".
Tous les prochains terminaux que vous ouvrirez le seront sous Git Bash, nettement plus coloré et intéressant que les autres terminaux 😎.

Pour cloner le boilerplate dans /tutorials/pizzeria/hmi
en portant le nom de projet modern
, veuillez tapez au sein du terminal :
bashgit clone https://github.com/e-vinci/js-basic-boilerplate.git modern
A ce stade-ci, tous les fichiers nécessaires sont disponibles dans votre répertoire modern
.
⚡ Comme vous avez cloné votre projet au sein d'un repo existant (web2
), Git ne trackera pas ce nouveau projet ; en effet, Git ne tracque pas des projets Git dans des projets Git.
Pour vous assurer que Git traque votre nouveau projet modern
, vous devez effacer le répertoire .git
se trouvant dans votre nouveau projet.
package.json
est le fichier de configuration de votre projet. Veuillez le mettre à jour afin de :
- donner un nom à votre projet & une description ;
- vous identifier comme auteur.
Installation de toutes les dépendances d'une application
Veuillez entrer dans le répertoire modern
à l'aide d'une commande bash, au sein du Terminal de VS Code :
bashcd modern # (or the name given to your project)npm i # (equivalent to `npm install` to install all dependencies )npm start # run the project
Veuillez ensuite installer toutes les dépendances, c'est-à-dire tous les packages qui sont indiqués dans package.json
bashnpm i # (equivalent to `npm install` to install all dependencies )
Notons que dans ce cas-ci, ce sont tous ces packages qui sont installés (voir package.json
):
json"devDependencies": {"@babel/core": "^7.14.3","@babel/preset-env": "^7.14.4","babel-loader": "^8.2.2","css-loader": "^5.2.6","eslint": "^8.18.0","eslint-config-airbnb-base": "^15.0.0","eslint-plugin-import": "^2.26.0","eslint-webpack-plugin": "^3.2.0","html-loader": "^2.1.2","html-webpack-plugin": "^5.3.1","prettier-airbnb-config": "^1.0.0","style-loader": "^2.0.0","webpack": "^5.38.1","webpack-cli": "^4.7.0","webpack-dev-server": "^3.11.2"},"dependencies": {"@popperjs/core": "^2.9.2","bootstrap": "^5.0.1"},
💭 Mais où sont installé tous ces packages ?
C'est dans le répertoire node_modules
. Il peut vite s'y trouver plusieurs centaines de MB de dépendances. C'est donc très important de ne jamais mettre ce dossier sur vos web repository, via Git. Pour ce faire, n'oubliez pas d'inclure un fichier .gitignore
dans vos projets pour ignorer node_modules
.
Pour la suite de ce tutoriel, nous considérons que tous les chemins absolus démarrent du répertoire /tutorials/pizzeria/hmi/modern
(ou /web2/tutorials/pizzeria/hmi/modern
si l'on considère le nom du répertoire du repo).
🍬 Installation des extensions pour le linter et le formatter
Introduction
Cette partie est optionnelle car normalement vous avez déjà installé ces outils dans le cadre du développement de services web (Partie 1 de ce cours).
Le linter
Cet outil permet de détecter des erreurs de programmation lors de l'écriture de nos scripts.
Nous voulons que le linter impose le style d'Airbnb décrit dans le Airbnb JS style guide.
Pour ce faire, grâce au boilerplate, lorsque nous lançons la commande npm start
, nous utilisons ESLint (cet outil est aussi utilisé par Facebook au sein d'applications React) qui impose un style de programmation conforme aux règles d'Airbnb.
Lors du build de l'application, nous bénéficions de feedback sur notre code.
Pour bénéficier de plus de feedback sur le code, veuillez installer l'extension ESLint au sein de VS Code.
Vous ne devez plus attendre le build pour avoir du feedback sur votre code, cela se fait dès l'écriture ! Vous avez même des propositions de "Quick fix" !
Pour votre info, la configuration des règles de ESLint se fait dans le fichier .eslintrc.js
devant se trouver à la racine d'un projet et offert au sein du boilerplate.
Le formatter
Pour formater facilement votre code, le boilerplate fournit une configuration de prettier conforme à ce qui est attendu pour coller au style imposé par le linter, c'est à dire au style d'Airbnb.
Pour que la configuration du formater offerte dans le boilerplate soit utile, veuillez installer l'extension prettier au sein de VS Code.
Une fois prettier installé dans VS Code, vous pouvez facilement formatter votre code conformément au style d'Airbnb :
- soit en tapant
Shift Alt F
; - soit en faisant un clic droit sur votre script,
Format Document
; la première fois, il se peut que vous deviez sélectionner prettier comme formatter.
Pour votre info, la configuration des règles de prettier se fait dans le fichier .prettierrc.js
devant se trouver à la racine d'un projet et offert au sein du boilerplate.
Exécution de l'application à l'aide du serveur de développement de Webpack
Veuillez exécuter l'application de base offerte par le boilerplate :
bashnpm start # run the project, equivalent of : npm run start
package.json
indique les scripts de démarrage, en fonction de la façon dont nous souhaitons démarrer l'application :
json"scripts": {"dev": "webpack --mode development","build": "webpack --mode production","start": "webpack serve --mode development"},
Lorsque nous tapons npm start
à la racine du projet (modern
ici), c'est en fait le serveur de développement de Webpack qui va démarrer notre application, et une page s'ouvre dans notre browser par défaut, affichant le texte "Replace with your page content".
Webpack offre de nombreux outils de développement qui sont configurés dans le fichier webpack.config.js
.
Veuillez jeter un oeil à ce fichier. Vous verrez notamment qu'un serveur web de développement doit démarrer sur le port 8080
.
Il n'est désormais plus nécessaire d'utiliser le Live Server de VS Code pour visualiser nos applications. Cela est directement géré par Webpack.
Pour stopper l'application, et donc le serveur de développement de Webpack, il suffit de taper sur CTRL + c
au sein du terminal.
Et pour la redémarrer ?
npm start
.
Fonctionnement de Webpack pour gérer des assets
Webpack a été configuré afin de générer une fichier index.html
sur base d'un template donné dans /src/index.html
.
Ce template HTML ne contient pas de balises <script>
.
C'est Webpack qui va s'occuper d'aller chercher toutes les dépendances qui doivent être indiquées via des imports dans le fichier /src/index.js
. Webpack va générer un bundle, une sorte de paquet cadeau, reprenant toutes les dépendances ainsi que vos scripts JS et vos autres assets (fichiers CSS, images...).
Dans le boilerplate du cours, src/index.js
fait l'import de tout ce qui est nécessaire pour pouvoir utiliser Bootstrap pour pouvoir styler ses pages web à l'aide de classes prédéfinies ; de plus, /stylesheets/main.css
est importé afin de pouvoir créer votre propre style :
js// Import Bootstrap CSSimport 'bootstrap/dist/css/bootstrap.min.css';// Custom stylesimport './stylesheets/main.css';
Nous verrons plus tard comment utiliser Bootstrap.
Nous comprenons donc que pour importer une librairie, un asset (image, CSS...), il suffit de le faire à l'aide du mot-clé import
.
Pour comprendre l'utilisation de Webpack, nous allons maintenant faire un refactor de notre site de la pizzeria, réalisé dans un tutoriel précédent, en l'intégrant à notre nouveau projet.
Veuillez copier/coller le CSS qui était contenu dans /stylesheets/style.css
au sein de /stylesheets/main.css
:
csshtml, body {height: 100%;margin: 0;}body {/*to easily deal with sticky footer*/display: flex;flex-direction: column;background-image : url(../img/pizza.jpg);background-size : cover;}header{text-align: center;}main{text-align: center;/*to easily deal with sticky footer:grow the main to fill the space*/flex: 1 0 auto;}footer{text-align: center;}footer img {height: 50px;}footer h1{color: white;}
Nous allons maintenant créer le layout HTML de base de notre application sur base de l'ancien index.html
.
Les changements à opérer sont :
- Enlever l'import de la feuille de style directement dans l'HTML :
<link rel="stylesheet" href="./stylesheets/style.css" />
- Enlever l'import de la librairie externe directement dans l'HTML :
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
- Enlever l'import du script externe
index.js
directement dans l'HTML :<script src="./index.js"></script>
Le contenu de /src/index.html
doit devenir :
html<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Pizzeria</title><link rel="icon" href="./img/pizza-svgrepo-com.svg" type="image/svg+xml" /></head><body><header><h1 class="animate__animated animate__bounce">We love Pizza</h1></header><main><audio id="audioPlayer" controls autoplay><source src="./sound/Infecticide-11-Pizza-Spinoza.mp3" type="audio/mpeg" />Your browser does not support the audio element.</audio></main><footer><h1 class="animate__animated animate__bounce animate__delay-2s">But we also love JS</h1><img src="./img/js-logo.png" alt="" /></footer></body></html>
Veuillez ajouter les images et le son du tutoriel précédent dans les répertoires /src/img
et src/sound
.
Veuillez ajouter le contenu de l'ancien index.js
au sein de /src/index.js
afin de gérer les clics sur toute la page :
js// Import Bootstrap CSSimport 'bootstrap/dist/css/bootstrap.min.css';// Custom stylesimport './stylesheets/main.css';const body = document.querySelector('body');body.addEventListener('click', startOrStopSound);function startOrStopSound() {const myAudioPlayer = document.querySelector('#audioPlayer');if (myAudioPlayer.paused) myAudioPlayer.play();else myAudioPlayer.pause();}
Veuillez exécuter l'application.
On voit que quasi tout est fonctionnelle. Nous allons nous occuper des animations des titres un peu plus tard.
Il est important de comprendre que le chargement d'un fichier (image ou son) à l'aide de Webpack se fait lors du build de votre application.
Lorsque vous tapez npm start
, vous lancez le build de votre application.
Grâce à l'installation et à la configuration du module html-loader
, Webpack émet le fichier dans le "output directory", généralement /dist
, et remplace la valeur de src
avec le chemin final vers le fichier.
Pour vous en rendre compte, au sein de votre browser, allez dans vos outils de développeur de Chrome (F12
par exemple), au sein de l'onglet Sources
. Vous allez pouvoir observer :
bundle.js
: c'est le fichier contenant notamment toutes les dépendances ainsi que votre code JS.index.html
ou(index)
dans Chrome : c'est votre page web, il est intéressant de voir son contenu. On voit que le bundle y est intégré dans le<head>
, l'attributdefer
assurant que l'exécution du script ne se fasse qu'une fois que le parsing de la page, la création du DOM, soit terminée !- des fichiers avec des noms du style
c731ea9152350c35fb1d.jpg
: ce sont vos assets, vos images, dont le nom et chemin ont été modifiés lors du build de votre application. Notez que Webpack pourrait transformer ces fichiers (par exemple en créant une représentation mémoire en base64 des images) lors du build. - tout les assets sont gérés par le serveur de développement, il n'y a rien de mis dans le répertoire
/dist
. Nous allons voir juste après comment gérer un build de production et observer la création du répertoire/dist
.
Pour le chargement d'une photo via le CSS, du moment que la photo est dans /src
, le Asset Module de Webpack reconnaît la photo localement et va remplacer le chemin final de la photo lors du build.
Nous allons maintenant stopper l'exécution de notre serveur (au sein du terminal, tapez CTRL C
).
Nous pouvons lancer la création d'un build de production.
Un build de production est une version optimisée de votre application web, les espaces blancs sont retirés, les commentaires...
Pour lancer le build, veuillez taper cette commande dans un terminal :
bashnpm run build
Veuillez observer ce qui est offert dans le répertoire /dist
du projet.
On voit notamment que bundle.js
et index.html
ont été optimisé pour la production.
Pour mettre à disposition un build de production par un serveur web, nous pouvons utiliser le package serve
qui offre un serveur de fichiers statiques. Nous allons utiliser une version temporaire de cette application, à l'aide de la commande npx
, qui permet d'installer une copie locale et temporaire d'une application, et de directement exécuter cette application.
Veuillez vous rendre dans le répertoire /dist
et exécuter le serveur serve
. Pour ce faire, tapez dans votre terminal :
bashcd distnpx serve
🎉 Le serveur web tombe sur le fichier index.html
et met à disposition votre build de production !
Pour terminer le refactoring du site de la pizzeria, il reste à installer la dépendance permettant de créer des animations.
Veuillez stopper l'exécution du serveur web (au sein du terminal, tapez CTRL C
) et revenir à la racine du projet.
bashcd ..
Installation d'un package
Afin de gérer des animations, il faut réinstaller la dépendance via npm
, le gestionnaire de packages.
Pour installer un package (ou une dépendance), il suffit de faire : npm i nomDuPackage
ou npm install nomDuPackage
.
Pour installer la librairie Animate.css [R.32], il suffit de taper dans un terminal, lorsqu'on se trouve à la racine du projet (modern
ici) :
bashnpm install animate.css
Veuillez aller jeter un oeil à votre fichier package.json
.
Lors de l'installation d'un package, celui-ci s'ajoute à la liste des dépendances.
Ainsi, si des développeurs trouvent votre projet sur Git, ils n'auront qu'à exécuter npm i
afin d'installer toutes les dépendances.
En lisant la documentation, nous voyons que pour utiliser la librairie au sein de notre application, il suffit de faire l'import de celle-ci.
Veuillez faire l'import de Animate.css
au sein de index.js
en ajoutant cette ligne :
jsimport 'animate.css';
Une fois la librairie importée, le refactoring du site de la pizzeria est terminé.
Vérifiez bien que tout est fonctionnel !
Si tout fonctionne bien, faites un commit de votre repo (web2
) avec comme message : modern-hmi tutorial
.
En cas de souci, vous pouvez accéder au code de ce tutoriel ici : modern-hmi.
Exercice 2.5 : module bundler
Dans le cadre des exercises sur le développement de services web (Partie 1), vous avez créé une RESTful API pour gérer des films. Nous allez maintenant démarrer le développement d'un frontend permettant de partager des informations sur vos films préférés.
NB : Dans un premier temps, nous allons oublier qu'il existe un web service offrant des opérations sur des films.
Veuillez créer un nouveau projet dans votre repository local et votre web repository (normalement appelé web2
) nommé /exercises/2.5
sur base du boilerplate : boilerplate de base.
Veuillez créer la Homepage
de votre application myMovies en y incluant au minimum deux images et un peu de texte pour présenter vos deux films favoris, tout en utilisant des outils modernes de développement à l'aide du boilerplate offert.
Veuillez créer de l'HTML de manière statique : vous ne devez pas gérer de JS à ce stade-ci (index.js
du boilerplate ne doit pas être complété).
Veuillez faire un commit
de votre code avec le message suivant : 2.5 : HMI : module bundler
.
Projet 2.6 : Planning de votre projet
Dans le fichier README.md
présent dans votre répertoire /web2/project
, veuillez y ajouter une liste de tous les cas d'utilisation que vous souhaitez développer. Il est important que vous puissiez donner une priorité aux fonctionnalités que vous aller développer.
Cela pourrait ressembler à qqch du style :
- Afficher la liste films (High)
- Ajouter un film (High)
- Effacer un film (High)
- Animer la HomePage (High)
- Mettre à jour un film (Medium)
- Enregistrer un utilisateur (Medium)
- Ajouter un commentaire à un film (Low)
- ...