Adloun

Projet : la Librairie interactive

Cours · JavaScript : rendre le Web interactif (école d'ingénieur), chapitre 12 · école d'ingénieur, informatique · le début du chapitre, la suite sur Adloun

Chapitre après chapitre, la Librairie du Campus a appris à se servir de JavaScript : un menu qui se replie (chapitre 7), un catalogue fabriqué à partir de données et filtré à la frappe (chapitre 8), un chargement qui ne gèle pas la page (chapitre 9), des livres venus d'un serveur (chapitre 10), un panier conservé dans le navigateur (chapitre 11). Il reste à en faire un site que l'on peut utiliser de bout en bout : choisir un livre, le mettre au panier, ajuster les quantités, commander, recevoir un numéro de commande. Et à le faire proprement : un code organisé, testé, accessible, qui résiste aux pannes.

Ce dernier chapitre est un projet. Il ne présente presque aucune notion nouvelle ; il montre comment les assembler, et comment vérifier le résultat. Le site complet est dans le dossier code/ch12/librairie/ du livre ; on l'ouvre, comme aux deux chapitres précédents, avec le serveur du livre :


$ node outils/serveur.mjs

puis l'adresse http://localhost:8000/code/ch12/librairie/ dans le navigateur.

Objectifs du chapitre

  • Organiser une application en modules qui ont chacun une responsabilité : affichage, règles, accès aux données.
  • Ajouter au catalogue un tri, et garder l'état de la recherche dans l'adresse de la page.
  • Construire la page du panier : quantités modifiables, retrait, total, présentation sur un petit écran.
  • Envoyer la commande au serveur en traitant les trois issues : acceptée, refusée (avec les raisons), impossible (panne).
  • Vérifier le tout : tests, analyse statique, validation HTML, parcours au clavier, essais dans le navigateur.

12.1 Le cahier des charges

Avant d'écrire du code, on écrit ce que le site doit permettre, du point de vue du client, puis les exigences de qualité.

Exigences de qualité : chaque page affiche ses états (chargement, erreur avec possibilité de réessayer) ; tout se fait au clavier ; les messages sont annoncés aux lecteurs d'écran ; aucune page ne déborde horizontalement sur un téléphone ; les règles (panier, tri, filtre) sont couvertes par des tests ; le code passe ESLint et le HTML le validateur.

12.2 L'architecture

Le site compte douze modules JavaScript, un peu plus de six cents lignes en tout, commentaires compris. Pour qu'un tel ensemble reste compréhensible, chaque module a une seule responsabilité, et les dépendances vont toujours dans le même sens : les modules d'affichage utilisent les règles et l'accès aux données, jamais l'inverse.

(La figure omet quelques flèches, comme celles de script.js, qui importe tous les modules d'affichage, ou de compteur.js vers panier.js.)

moduleresponsabilité
script.jspoint d'entrée : active ce que contient la page
catalogue.jscartes, recherche, tri, état dans l'adresse
fiche.jsla fiche d'un livre
ajout-panier.jsles boutons « Ajouter au panier »
commande.jsla page Panier et l'envoi de la commande
compteur.jsle nombre d'articles dans l'en-tête
menu.jsle menu repliable
panier.jsles règles du panier (chapitre 11)
temps.jsattendre, retarder
donnees.jsl'API du serveur : livres, commande
requete.jsobtenirJson, ErreurHttp
stockage.jsle panier dans localStorage

Toutes les pages chargent le même script.js. Il regarde ce que contient la page et n'active que ce qui la concerne : le catalogue s'il trouve la liste des livres, la page Panier s'il trouve son conteneur, et ainsi de suite. Le chargement des livres, commun au catalogue et au panier, est écrit une seule fois, avec ses trois états :


// Charge les livres en affichant les trois états (chargement, erreur avec
// « Réessayer », données), puis passe les livres à la page.
async function chargerAvecEtats(etat, texteChargement, utiliser) {
  const alerte = document.querySelector("#alerte");
  alerte.hidden = true;
  etat.textContent = texteChargement;
  try {
    utiliser(await chargerLivres());
  } catch (e) {
    console.error(e); // le détail technique, pour le développeur
    etat.textContent = "";
    alerte.querySelector(".message").textContent = messageUtilisateur(e);
    alerte.hidden = false;
    alerte.querySelector("#reessayer")?.addEventListener(
      "click",
      () => chargerAvecEtats(etat, texteChargement, utiliser),
      { once: true },
    );
  }
}

La suite du cours est sur Adloun

Le chapitre en entier, formules et figures comprises, avec le tuteur, les fiches, les QCM et les exercices.

Lire la suite du cours

En accès libre, sans inscription.

Exercices corrigés de ce chapitre

Lire la suite du cours →