Heritiana Antonio Frond end Designer | Developer

Hello, I am

Heritiana Antonio

Frond end Designer | Developer

Chapitre 8 : Modules et organisation du code

1 min de lecture

Chapitre 8 : Modules et organisation du code

Objectif

À la fin de ce chapitre, index.html charge seulement main.js. Ce fichier importe phraseEssai, les valeurs de l’essai, et une fonction qui demande fiche.json. Chaque fichier exporte les noms que les autres ont le droit d’appeler, et garde le reste. Le dossier premiere-page et fiche.json restent en place. Le premier clic affiche encore « Aina, essai 1 sur 3. ». Dans la console, phraseEssai produit une ReferenceError.

Tout tient dans script.js

Le serveur du chapitre 7 doit tourner. Dans le terminal, placez-vous dans premiere-page et lancez :

python3 -m http.server 8000

Laissez ce terminal ouvert. Si le port est pris, relancez avec 8001. Ouvrez http://127.0.0.1:8000/. Le titre affiche « Les essais », la fiche « Trois essais sont permis. », le premier clic « Aina, essai 1 sur 3. ».

script.js mélange encore prenoms, phrases, essai, sessionOuverte, phraseEssai, les quatre getElementById, le fetch et l’écouteur. Dans la console, phraseEssai("Aina", 1, 3) répond : un script classique laisse ce nom visible dans la page.

Ce qu’un fichier expose

Un module est un fichier. export met un nom à sa porte. import le reçoit ailleurs. Sans export, le nom reste dans le fichier : aucun autre fichier ne peut le citer.

Le chemin après from commence par ./ et finit par .js. ./phrase.js est le fichier voisin. phrase.js seul n’est pas une adresse du dossier. Le serveur du chapitre 7 livre les fichiers tels quels : rien ne les rassemble à votre place.

index.html ne liste pas les modules. Il charge le point d’entrée. Les import de ce fichier font venir les autres.

Trois fichiers, trois rôles

Créez phrase.js. Le corps est celui du chapitre 3. export est devant function. Les comparaisons restent à l’intérieur : elles ne sont pas des noms exportés.

export function phraseEssai(personne, nombre, maximum) {
  if (nombre < maximum) {
    return personne + ", essai " + nombre + " sur " + maximum + ".";
  } else if (nombre === maximum) {
    return personne + ", dernier essai.";
  } else {
    return "Limite dépassée.";
  }
}

Créez etat.js. Il garde les valeurs du chapitre 4, plus sessionOuverte. essai.prenom reçoit une copie de prenoms[0] à la lecture de ce fichier.

export const prenoms = ["Aina", "Ravo", "Hery"];
export const phrases = [];

export const essai = {
  prenom: prenoms[0],
  tentatives: 0,
  limite: 3
};

export const sessionOuverte = true;

prenoms est exporté : un autre fichier a le droit de lire la liste. Le clic utilisera essai.prenom, déjà rempli. const refuse de remplacer le tableau ou l’objet. essai.tentatives = essai.tentatives + 1 reste permis.

Créez fiche.js. chargerFiche reçoit les deux éléments. Le fetch est celui du chapitre 7, avec les mêmes phrases et catch en function (). L’adresse "fiche.json" est dans la fonction, sans export. Ce fichier n’appelle pas getElementById et ne connaît pas phraseEssai.

export function chargerFiche(titre, fiche) {
  fetch("fiche.json").then(function (reponse) {
    if (reponse.ok === false) {
      titre.textContent = "Fiche indisponible";
      fiche.textContent = "L’adresse n’a pas renvoyé la fiche.";
      return;
    }
    return reponse.json();
  }).then(function (donnees) {
    if (!donnees) {
      return;
    }
    titre.textContent = donnees.titre;
    fiche.textContent = donnees.texte;
  }).catch(function () {
    titre.textContent = "Fiche indisponible";
    fiche.textContent = "L’adresse ne répond pas.";
  });
}

main.js, le point d’entrée

Créez main.js. Les trois import sont les premières lignes. Les accolades citent les noms exportés. Le chemin suit from.

import { phraseEssai } from "./phrase.js";
import { phrases, essai, sessionOuverte } from "./etat.js";
import { chargerFiche } from "./fiche.js";

const message = document.getElementById("message");
const bouton = document.getElementById("action");
const titre = document.getElementById("titre");
const fiche = document.getElementById("fiche");

chargerFiche(titre, fiche);

bouton.addEventListener("click", function () {
  if (sessionOuverte === false) {
    message.textContent = "Connectez-vous pour continuer.";
  } else {
    essai.tentatives = essai.tentatives + 1;
    const phrase = phraseEssai(essai.prenom, essai.tentatives, essai.limite);
    phrases.push(phrase);
    message.textContent = phrase;
  }
});

main.js n’importe pas prenoms : etat.js a déjà copié "Aina" dans essai.prenom. Les quatre getElementById sont ici, avant chargerFiche et avant l’écouteur. L’écouteur reste function (), sans paramètre, sans parenthèses après l’accolade, sans console.log. C’est la dernière instruction.

Le navigateur charge d’abord les trois fichiers importés. fetch ne part qu’à l’appel de chargerFiche, après les quatre getElementById. La réponse écrit dans titre et fiche. Le clic écrit dans message. phrases.push et l’addition modifient les objets créés dans etat.js.

Une seule balise

Dans index.html, remplacez la balise de script.js. La nouvelle reste en bas de body, après le bouton.

<script type="module" src="main.js"></script>

type="module" autorise import. Le navigateur attend d’avoir lu le HTML avant de lancer main.js, donc les quatre getElementById trouvent les paragraphes et le bouton. script.js peut rester sur le disque. Aucune balise ne doit plus le charger.

Rechargez http://127.0.0.1:8000/. Le titre affiche « Les essais », la fiche « Trois essais sont permis. », le premier clic « Aina, essai 1 sur 3. ».

Un double-clic sur index.html ouvre file://. Le module est refusé, main.js ne part pas, et le catch ne s’exécute pas. Le titre reste « Chargement… », la fiche « La fiche n’est pas encore arrivée. ». Revenez à http://127.0.0.1:8000/.

Si la balise de script.js est encore là, ce fichier écoute aussi le bouton, avec son propre essai. Retirez-la. Seule la balise de main.js reste.

Quand le nom n’est pas à la porte

Ajoutez dans le premier import un nom que phrase.js n’exporte pas.

import { phraseEssai, joindre } from "./phrase.js";

Rechargez. La console affiche une SyntaxError : ./phrase.js ne fournit pas d’export nommé joindre. chargerFiche n’est pas appelée. Le titre reste « Chargement… », la fiche « La fiche n’est pas encore arrivée. », le clic laisse « En attente d’un clic. ». Retirez , joindre. « Les essais » revient.

Enlevez type="module" et gardez les import. Rechargez. Une SyntaxError signale que ces lignes se lisent dans un module. Les textes du HTML restent. Remettez type="module".

Remplacez "./phrase.js" par "phrase.js". Rechargez. Une TypeError signale que l’adresse ne commence pas par ./. Le titre reste « Chargement… ». Remettez "./phrase.js". Le premier clic affiche « Aina, essai 1 sur 3. ».

L’import se lit, il ne se remplace pas

Dans le else de l’écouteur, avant l’addition, ajoutez :

essai = { prenom: "Ravo", tentatives: 0, limite: 3 };

Rechargez, cliquez. La console affiche une TypeError. Le paragraphe reste « En attente d’un clic. ». essai vient d’un import : on le lit, on ne le remplace pas. Retirez la ligne. Gardez essai.tentatives = essai.tentatives + 1, qui change une propriété de l’objet créé dans etat.js. Rechargez. Le premier clic affiche « Aina, essai 1 sur 3. ».

La console ne voit plus phraseEssai

Rechargez http://127.0.0.1:8000/. Dans la console, tapez phraseEssai("Aina", 1, 3). Vous obtenez ReferenceError et le texte phraseEssai is not defined. Le paragraphe ne change pas. essai et prenoms produisent la même erreur. Le clic appelle pourtant phraseEssai, parce que main.js l’a importée.

N’ajoutez pas window.phraseEssai = phraseEssai. La console répondrait, et un script de la page pourrait appeler la fonction sans import. Les quatre fichiers restent sans window et sans console.log.

Exercice

  1. Avec le serveur lancé, ouvrez http://127.0.0.1:8000/. Le titre est « Les essais », la fiche « Trois essais sont permis. », le premier clic « Aina, essai 1 sur 3. ».
  2. Dans la console, appelez phraseEssai("Aina", 1, 3). Notez la ReferenceError. Le paragraphe ne change pas.
  3. Importez joindre depuis ./phrase.js, rechargez, puis retirez ce nom. Le titre redevient « Les essais ».
  4. Retirez type="module", rechargez, puis remettez-le. Une seule balise script vise main.js. Le premier clic affiche « Aina, essai 1 sur 3. ». Aucun des quatre fichiers ne contient console.log.

À retenir

  • index.html charge main.js avec type="module". Les autres fichiers arrivent par import. L’adresse reste http://127.0.0.1:8000/.
  • Le chemin s’écrit ./phrase.js. export choisit les noms qu’un autre fichier peut citer.
  • phrase.js exporte phraseEssai. etat.js exporte prenoms, phrases, essai et sessionOuverte. fiche.js exporte chargerFiche et garde "fiche.json".
  • Les quatre getElementById sont dans main.js. L’écouteur reste function (), sans parenthèses d’appel.
  • Un nom importé ne se remplace pas. La console répond ReferenceError pour phraseEssai.

La suite

Le cours JavaScript s’arrête sur cette frontière. premiere-page garde fiche.json, phrase.js, etat.js, fiche.js et main.js. La balise vise le point d’entrée. Le prochain cours, Apprendre TypeScript, ouvrira une autre page : la première leçon s’appelle « Pourquoi typer du JavaScript ». Laissez le fetch dans chargerFiche, et l’écouteur en function (), sans console.log.