Public cible
Débutants, étudiants et professionnels qui souhaitent acquérir une pratique structurée dans ce domaine.
Comprendre ce qu'un framework règle réellement, puis maîtriser React, Angular et Vue : composants, état, cycle de vie, formulaires, performance, accessibilité et tests. Le cours ne désigne pas de gagnant : le projet final exige un choix argumenté.
Débutants, étudiants et professionnels qui souhaitent acquérir une pratique structurée dans ce domaine.
Comprendre les notions essentielles et les appliquer dans un projet vérifiable.
Aucune connaissance préalable n’est strictement obligatoire ; les prérequis détaillés sont précisés dans les ateliers.
Tous niveaux
La validation repose sur les évaluations actives et les livrables pratiques du cours.
Un ordinateur, un navigateur et les outils indiqués dans le premier atelier sont suffisants pour commencer.
Construire un composant avec ses états de chargement, d'erreur et de succès.
Obligatoire ConsulterÉvaluer une architecture front et justifier un choix de framework.
Obligatoire ConsulterConstruire un composant avec ses états de chargement, d'erreur et de succès.
Obligatoire ConsulterÉvaluer une architecture front et justifier un choix de framework.
Obligatoire ConsulterConstruire un composant avec ses états de chargement, d'erreur et de succès.
Obligatoire ConsulterÉvaluer une architecture front et justifier un choix de framework.
Obligatoire ConsulterConstruire un composant avec ses états de chargement, d'erreur et de succès.
Obligatoire ConsulterÉvaluer une architecture front et justifier un choix de framework.
Obligatoire ConsulterConstruire un composant avec ses états de chargement, d'erreur et de succès.
Obligatoire ConsulterÉvaluer une architecture front et justifier un choix de framework.
Obligatoire ConsulterUn framework n'accélère pas le code. Il change la façon dont on décrit l'interface, et c'est là qu'est le gain.
Sans outil, on écrit à la main trois choses à chaque modification de l'écran : retrouver l'élément du DOM, le mettre à jour, et gérer le cas où l'état a changé entre deux actions de l'utilisateur. Ce code est fait de cas particuliers, et il en manque toujours un.
Un framework inverse la responsabilité : on décrit ce que l'écran doit afficher pour un état donné, et lui se charge de calculer la différence avec l'écran réellement affiché. C'est une description, pas une séquence d'instructions.
L'état est la donnée qui décrit la situation courante : l'utilisateur connecté, la panier, la valeur d'un champ, l'état de chargement. Un composant est une fonction de l'état vers l'affichage.
La conséquence pratique est la plus importante du cours : deux états qui produisent le même écran n'ont aucune raison d'être distincts. Corriger l'état plutôt que l'affichage — au lieu de « cacher le bouton », on change l'état qui décide de son affichage. C'est la source de la majorité des bugs évités.
Un framework bien maîtrisé dans une mauvaise architecture produit une application inutilisable. L'inverse est vrai aussi.
Les trois sont des réponses au même problème. Les présenter comme « le bon », « le mauvais » est une erreur : ils optimisent pour des contraintes différentes.
| Critère | React | Angular | Vue |
|---|---|---|---|
| Philosophie | bibliothèque, on assemble | framework complet, tout fourni | incrémental, on choisit le niveau |
| Langage | JavaScript, TypeScriptoptionnel | TypeScript obligatoire | JavaScript, TypeScript optionnel |
| Outillage | à choisir soi-même | fourni et cohérent | progressif, migration possible |
| Conventions | peu, donc libre | fortes, donc cadrées | faibles à moyennes |
Le critère décisif n'est presque jamais technique : c'est ce que l'équipe saura maintenir dans deux ans. Un framework impair son état s'explique en une phrase ; une pile mal choisie se decouvre a la premiere evolution, quand le code est deja en production. Ce cours présente les trois, mais il ne prétend pas qu'il y en a une bonne : les étudiants devront trancher pour un besoin donné, et savoir justifier ce choix.
Quel que soit le framework, TypeScript est devenu l'attente par défaut sur du code qui dépasse quelques centaines de lignes. Il vérifie les types à la compilation, ce qui déplace la détection d'erreur du moment où l'utilisateur clique vers celui où le code est écrit.
Le type ne vérifie pas la logique. Il vérifie la cohérence des formes, pas l'exactitude des comportements. Un tableau typé comme un tableau de nombres reste faux si on y met des nombres au hasard.
Erreur fréquente en formation : écrire
as ou any pour faire
disparaître une erreur de type. Le message ne disparaît
pas, il perd sa valeur : la vérification a été
désactivée sur ce point, et le bug est maintenant
invisible au lieu d'être signalé.
Un transtypage doit être justifié par un motif
réel, et écrit en commentaire. Un
any non expliqué est un bug en attente.
Les tests ci-dessous rendent la violation visible.
React est une bibliothèque d'interface. Elle ne favorise aucune architecture : elle fournit un mécanisme de composition, et c'est à l'équipe de décider de la manière de l'organiser.
Un composant prend des propriétés (props) en entrée et rend du JSX en sortie. Il ne contient pas de logique de gestion d'état global : il décrit ce qui doit s'afficher, et rien d'autre.
function CarteUtilisateur({ nom, role }: { nom: string; role: string }) {
return (
<div className="carte">
<h3>{nom}</h3>
<p>{role}</p>
</div>
);
}
C'est le principe central de React, et il faut le retenir tel quel : les données circulent dans un seul sens. Un parent transmet une donnée à un enfant, l'enfant ne peut jamais la modifier directement. S'il doit agir dessus, il remonte un événement, et le parent décide.
Ce qui paraît être une contrainte est un garde-fou : impossible qu'un enfant modifie un état partagé sans que le parent le sache. Les bugs d'état impossible à retrouver disparaissent, parce que le chemin de modification est unique et visible.
En JSX, une expression conditionnelle simple s'écrit
avec l'opérateur logique. Le rendu conditionnel n'est pas
une déclaration if à écrire dans la
balise, mais une expression à évaluer.
Ce que les framework modernes corrigent par rapport aux premières versions : le retour direct d'un fragment de liste sans clé. La clé d'un élément de liste n'est pas décorative — elle indique à React quel élément est lequel entre deux rendus. Une clé absente ou generada par l'index produit des mélanges d'état silencieux quand la liste est réordonnée : les données restent dans la mauvaise ligne sans aucune erreur visible.
Les hooks sont des fonctions qui permettent d'utiliser
l'état et le cycle de vie dans un composant fonction.
Ils commencent par use, et c'est la convention
de les appeler au niveau racine du composant.
Il retourne l'état et une fonction pour le modifier. La fonction de mise à jour ne fusionne pas la valeur : elle la remplace et ne reçoit pas l'ancienne automatiquement. C'est la source d'erreur la plus fréquente de l'apprentissage : deux mises à jour dans la même boucle, et la seconde écrase la première.
La forme « mise à jour par fonction » existe précisément pour cela : elle reçoit la valeur précédente, et deux mises à jour successives se cumulent correctement.
Un effet sert à synchroniser le composant avec une ressource extérieure : appel réseau, abonnement à un événement, minuterie, manipulation directe du DOM. Ce n'est pas un « code qui s'exécute après le rendu », c'est une synchronisation dont il faut nettoyer l'effet précédent.
La fonction de retour est le nettoyage : elle annule l'abonnement, annule la requête en cours, arrête la minuterie. Oublier ce retour est un bug qui ne se voit pas : l'application fonctionne, et fuit des ressources à chaque changement d'état.
La seconde règle du tableau de dépendances compte autant : une dépendance manquante produit un comportement faux parce que l'effet lit une valeur qui sera périmée. Ce n'est pas un avertissement, c'est la définition même d'une closure obsolète.
React rejoue le rendu d'un composant quand son état change ou quand une prop change de valeur. C'est généralement ce qu'on veut, et c'est la base de la simplicité du modèle.
La longueur de la prop est le coût réel. Un rendu de composant ne coûte pas cher en soi ; ce qui coûte est le travail déclenché en aval, sur des sous-arbres volumineux. Un parent qui rejoue son rendu n'a pas forcément un problème, si ses enfants sont peu nombreux ou peu coûteux.
useCallback et
useMemo servent à cela ;memo) : le dernier recours, car ça
complique la lecture et ça a un coût mémoire.Un hook de performance s'écrit avec une
justification mesurée : quel rendu a été mesuré
comme coûteux, avec quel outil, à quel seuil. Sans
mesure, useMemo everywhere n'améliore rien
et rend le code nettement plus difficile à suivre. Le
profil de rendu reste la seule preuve acceptable — et
l'optimisation non mesurée est une dette, pas une
amélioration.
Angular n'est pas une bibliothèque d'interface, c'est un framework. Il fournit le routeur, les formulaires, le client HTTP, la compilation, les tests et l'outillage de build dans une seule chaîne cohérente.
Le prix à payer est la courbe d'apprentissage : plus de concepts à connaître avant d'écrire une première ligne. Le choix se joue là — sur la taille de l'équipe et sur la complexité attendue de l'application, pas sur une préférence de syntaxe.
Le modèle historique d'Angular repose sur la détection de changement : l'Angular parcourt l'arbre des composants et vérifie ce qui a changé. Les signaux introduisent un modèle où la dépendance est déclarative : un composant indique qu'il utilise une valeur, et il n'est rejoué que si cette valeur change.
Un signal est une valeur qui « porte » sa dépendance. Une valeur calculée se dérive d'autres signaux et ne se recalcule que si une de ses sources a changé. Le résultat est le même écran, mais le travail est limité au sous-arbre réellement concerné.
La leçon qui vaut pour les trois frameworks : une règle de dépendance explicite coûte moins cher qu'une dépendance implicite qu'on découvre en production.
L'outillage Angular brille sur les deux besoins quotidiens d'une application d'entreprise : formulaires et accès aux données.
Les formulaires réactifs décrivent le modèle et les règles de validation dans le code, indépendamment du gabarit. Deux bénéfices directs : les règles sont testables sans navigateur, et la validation peut être partagée entre le formulaire et une soumission programmatique.
Une application réelle a trois états par requête réseau, et il faut les traiter tous les trois :
Traiter seulement le succès est l'erreur la plus répandue du domaine. L'utilisateur clique, rien ne se passe, et l'application passe pour cassée. Le chargement doit bloquer l'action pour éviter les doubles envois, et l'erreur doit être visible et actionnable — jamais un échec silencieux.
Un dernier piège, plus rare mais plus coûteux : si l'utilisateur déclenche deux fois une recherche, les réponses peuvent revenir dans le désordre. La réponse la plus ancienne peut alors écraser la plus récente, affichant des résultats qui ne correspondent pas à la dernière saisie. Les bibliotheques modernes fournissent un mécanisme d'annulation ; s'il est ignoré, ce defaut est pratiquement impossible à reproduire en test et se manifeste sporadiquement chez les utilisateurs.
Vue se définit par une propriété précise : il peut être introduit par petits morceaux dans une page existante, sans réécrire l'application.
Cette propriété a une conséquence très concrète : sur un site existant, on peut commencer par le seul composant qui pose problème, et décider plus tard si on va plus loin. C'est souvent ce qui rend Vue convaincant pour une équipe qui part d'un parc applicatif existant.
Vue transforme l'objet de données du composant en objet surveillé. Quand une propriété est lue dans un gabarit, l'accès est enregistré ; quand elle est écrite, le rendu correspondant est déclenché. L développeur écrit l'état et le gabarit, sans décrire la mise à jour.
La conséquence à connaître : la réaction est déclenchée par la lecture dans un gabarit ou un observateur. Une propriété lue uniquement dans du code ordinaire ne déclenche rien — ce qui est correct, mais surprend si on l'attendait autrement.
Un composant Vue tient dans un fichier, qui contient ensemble le gabarit, le script et le style. C'est l'inverse de la séparation stricte en plusieurs fichiers, et c'est un choix d'outillage autant que d'architecture.
Un composant qui contient six zones fonctionnelles distinctes est un composant à six problèmes. Le découpage n'est pas une question de taille de fichier : c'est une question de raison d'être.
Test simple à appliquer : si une partie du composant peut être décrite par une phrase qui commence par « il affiche », cette partie est probablement un composant distinct. Le bénéfice n'est pas la Reduction du fichier, c'est la testabilite : un composant affichant « l'utilisateur connecté » se teste seul, sans approvisionner tout le contexte de la page.
Comme en React, les données descendent par propriétés et les intentions remontent par événements. La cohérence entre les trois frameworks sur ce point n'est pas un hasard : c'est la solution la plus lisible quand plusieurs personnes font évoluer le même code.
Quand plusieurs composants ont besoin du même état, il faut une source unique. Un store partagé évite de recopier la donnée et de la resynchroniser à la main — source classique de désynchronisation.
Un store expose des getters en lecture seule et des actions qui sont les seules à pouvoir modifier l'état. Cette discipline n'est pas cosmétique : elle rend la traçabilité immédiate. On peut répondre à « qui a modifié cette valeur » en regardant les actions, sans chercher une affectation dans tout le code.
C'est la même exigence que les enzymes de de la duplication, appliquée à l'état : une donnée modifiable depuis partout est une donnée dont on ne saura pas qui l'a modifiée.
Le troisième temps est celui qu'on oublie. Une minuterie, un écouteur d'événement global ou un abonnement laissés actifs après le démontage gardent une référence sur un composant qui n'existe plus : la mémoire ne se libère pas, et l'erreur peut se manifester beaucoup plus tard, dans un autre composant, ce qui la rend très difficile à rattacher à sa cause.
Un site perçu comme lent est presque toujours un problème de chargement et de rendu, pas un problème de framework. Les métriques de terrain de la plateforme centrale, de reference pour le secteur, tiennent compte du poids total et du temps d'exécution : c'est ce que l'utilisateur perçoit, pas le nombre de millisecondes que le framework met à jour un composant.
Le découpage du code (code splitting) et le chargement différé des composants non visibles au premier écran. Une page qui affiche une liste n'a pas besoin du composant de détail d'un élément tant que l'utilisateur n'en a pas cliqué un. Les trois framework l'intègrent, et la négligence est l'erreur la plus courante : le premier écran attend un composant que personne ne voit.
Sur un site institutionnel, les images et les polices pèsent souvent plus lourd que tout le reste du code. Elles ne relèvent pas du framework, et c'est précisément pourquoi elles sont souvent oubliées : optimiser React n'a aucun effet sur une photo de 2 Mo. Formats modernes, dimensions servies adaptées à l'affichage, et polices préchargées uniquement pour celles réellement utilisées.
L'accessibilité n'est pas une option. C'est une obligation légale dans l'Union européenne, et c'est surtout le meilleur test de la qualité réelle d'une interface.
Sans accessibilité, une application monopage est navigation au clavier, donc inutilisable. Avec un framework, les composants produisent un balisage cohérent : une application bien écrite est accessible presque naturellement, parce que la structure du composant et la structure sémantique du document coïncident. C'est un vrai gain du modèle à composants, à condition de ne pas remplacer les balises par des conteneurs neutres sans raison.
Les outils automatiques détectent les erreurs mécaniques : attribut manquant, contraste insuffisant, libellé vide. Ils ne détectent rien à l'ordre de lecture des titres, à la pertinence des messages d'erreur, ni à la lisibilité réelle. Ces points se vérifient au clavier, sur la page rendue, par une personne qui ne voit pas l'écran.
Tester une application monopage ne signifie pas automatiser les clics. Cela signifie tester l'état, et laisser l'interface s'en déduire.
Un composant pur se décrit par ses entrées et ses sorties : un état, plus des propriétés, donnent un rendu. On peut donc l'appeler sans navigateur, sans DOM, en quelques millisecondes. C'est ce qui rend le test unitaire possible là où il ne l'était pas avec un modèle centré sur la manipulation du DOM.
Le critère est simple : le test doit échouer quand le comportement change, et seulement dans ce cas. Un test qui échoue quand on change une couleur est un test à supprimer, pas à corriger.
Le passage en production n'est pas une étape technique, c'est un changement de environnement. Ce qui marche en développement peut échouer en production pour des raisons qui n'ont rien à voir avec le code.
Après un déploiement, l'utilisateur peut continuer de voir l'ancienne version si les fichiers portent le même nom. Le nom des fichiers produits doit contenir une empreinte de leur contenu : quand le contenu change, le nom change, et le navigateur recharge. C'est le mécanisme de versionnement des ressources, et son absence se traduit par des signalements de bogues du type « vous avez oublié de déployer ».
Le navigateur est un environnement hostile. Tout ce qui s'y exécute peut être lu et modifié par l'utilisateur. La conséquence est une règle unique, à ne jamais négocier.
Une vérification faite dans le navigateur n'est pas une sécurité, c'est un confort d'affichage. Masquer un bouton, désactiver un champ, mettre une condition dans l'interface : l'utilisateur voit une application proprement presentee, et la requete qu'il avait interdite part quand même s'il l'envoie lui-même.
Les secrets dans le paquet livré. Une clé d'API embarquée dans le JavaScript est publique : le paquet se télécharge. Si la clé doit rester côté serveur, l'appel doit passer par votre serveur.
Le stockage local persistant. Le stockage local du navigateur n'est pas protégé : il est lisible par tout script de la même origine, et il survit à la fermeture du navigateur. Un jeton de session qui y dort est un jeton qui finira dans une sauvegarde de navigateur ou sur un poste partagé.
Réaliser en React, Angular ou Vue — au choix, avec justification écrite du choix — une application petite mais complète : authentification, liste paginée avec recherche, formulaire de création et de modification, détail, gestion des états de chargement et d'erreur.
Ce n'est pas le nombre d'écrans. C'est la gestion des situations peu frequentes : une réponse en erreur du serveur affichée proprement, une double soumission bloquée, une recherche dont les réponses arrivent dans le désordre et n'écrasent pas le résultat courant. Ces trois points séparent une application qui marche d'une application qui tient en production — et ce sont exactement ceux que les entreprises signalent le plus souvent après la livraison.
Le livrable inclut un paragraphe expliquant le choix, avec le critère qui l'a déterminé et ce qu'il a coûté. C'est la compétence la plus transférable du cours : dans un service réel, on ne choisira pas le framework le plus connu, on choisira celui que l'équipe saura maintenir.
Ecrire un composant a partir d’un besoin, et le faire relire par quelqu’un qui n’a pas le code.
Publié le 29/09/2026