12k
All articles

Les fondamentaux dont vous avez toujours besoin pour coder avec des agents

Évaluez le code généré par l’IA avec confiance. Maîtrisez les bases du Web : HTTP, navigateur, état, sécurité, débogage, Git et architecture.

OpenReplay Team
OpenReplay Team
Les fondamentaux dont vous avez toujours besoin pour coder avec des agents

Vous avez besoin de suffisamment de bases en programmation pour évaluer le code écrit par un agent, et non pour le taper vous-même, car un code qui s’exécute peut tout de même être mal conçu, vulnérable ou lent.

La situation habituelle : l’agent annonce qu’il a terminé, la page se charge, les tests passent, et pourtant vous seriez incapable d’expliquer le diff si un relecteur vous posait la question. Ce doute est légitime. Il révèle généralement une lacune précise dans vos connaissances.

Cet article ne traite ni du prompting ni de la configuration des outils. Pour cela, consultez comment obtenir les meilleurs résultats avec les outils de codage IA et trucs et astuces pour coder avec l’IA. Il passe plutôt en revue sept fondamentaux du Web et associe à chacun une erreur réaliste d’agent ainsi que les connaissances nécessaires pour la repérer.

Points clés

  • Dans le navigateur, fetch() ne rejette sa promesse que lorsque la requête elle-même échoue, par exemple en cas d’erreur réseau : un code qui ne vérifie jamais response.ok traite donc une 404 ou une 500 comme un succès.
  • Toute valeur intégrée au JavaScript frontend est publique, y compris les variables d’environnement que le framework expose au client.
  • Masquer un bouton ne constitue pas une autorisation : le serveur doit vérifier les permissions à chaque requête.
  • git add -p permet d’accepter les modifications d’un agent hunk par hunk, et git revert annule un commit sans réécrire l’historique.
FondamentalErreur typique de l’agentCe qui permet de la repérer
HTTP200 avec un corps d’erreurSémantique des codes de statut
NavigateurÉcouteur sans nettoyageCycle de vie des effets
ÉtatDonnées serveur copiées dans un storeSource unique de vérité
SécuritéSecret dans le bundle clientSavoir ce qui est envoyé au navigateur
DébogageErreur avaléeStack traces, DevTools
GitTout accepter d’un coupIndexation par hunk, revert
ArchitectureNouvelle dépendance pour une seule ligne de codeAPI natives de la plateforme

Pourquoi les codes de statut HTTP et la mise en cache comptent-ils toujours ?

Les codes de statut et les en-têtes de cache permettent aux clients, aux proxys et aux outils de supervision de savoir ce qu’il est advenu d’une requête. Un endpoint qui renvoie 200 OK avec un message d’erreur dans le corps indique à chaque client, cache et outil de supervision que la requête a réussi. La RFC 9110 définit les codes 2xx comme des succès : le suivi des erreurs et les mécanismes de nouvelle tentative ne se déclencheront donc pas. Gardez la référence des codes de statut HTTP à portée de main lorsque vous relisez des handlers.

Côté client, le piège est symétrique. fetch() ne rejette pas sa promesse sur les statuts d’erreur HTTP, uniquement lorsque la requête elle-même échoue ; vous devez donc vérifier Response.ok vous-même :

const res = await fetch('/api/save', { method: 'POST', body });
if (!res.ok) throw new Error(`Save failed: ${res.status}`);

Les agents ont aussi tendance à interroger en boucle (polling) des données qui changent rarement. Pour une configuration ou des listes de référence, l’en-tête Cache-Control (défini dans la RFC 9111) associé à une revalidation par ETag (qui renvoie 304 Not Modified, défini dans la RFC 9110) élimine les requêtes redondantes. Les données qui évoluent réellement en temps réel relèvent d’un autre problème.

Comment le navigateur gère-t-il le rendu et les événements ?

Les écouteurs d’événements et les écritures dans le DOM ont un cycle de vie, et le navigateur vous fait payer le fait de l’ignorer. Une erreur fréquente des agents consiste à ajouter un écouteur dans un effet dépourvu de fonction de nettoyage et de tableau de dépendances. React exécute cet effet après chaque rendu : chaque rendu ajoute donc un nouvel écouteur resize. La correction consiste à renvoyer une fonction de nettoyage et à déclarer les dépendances :

useEffect(() => {
  window.addEventListener('resize', onResize);
  return () => window.removeEventListener('resize', onResize);
}, [onResize]);

La fonction de nettoyage renvoyée s’exécute avant la prochaine exécution de l’effet et lors du démontage. Le second schéma à repérer côté navigateur est le layout thrashing : une boucle qui écrit un style puis lit offsetHeight, encore et encore. Chaque lecture qui suit une écriture peut forcer un calcul de mise en page synchrone. La solution consiste à effectuer d’abord toutes les lectures, puis toutes les écritures.

Où l’état doit-il résider et comment les données doivent-elles circuler ?

Chaque donnée doit avoir un seul propriétaire. Copier des données serveur dans un store côté client crée une seconde source de vérité, et les deux copies divergent dès que l’une change sans l’autre. Dans une version typique produite par un agent, une liste est récupérée, placée dans useState ou dans un store Zustand, puis modifiée localement, tandis qu’un nouveau fetch met à jour une autre copie.

Les recommandations de React sur la structure de l’état mettent en garde contre la duplication de l’état. Pour les données serveur, une couche de cache comme TanStack Query ou SWR détient les données et gère leur invalidation. Pour tout ce qui peut être calculé à partir de l’état existant, dérivez la valeur pendant le rendu.

Bases de la sécurité : authentification, XSS, secrets et entrées non fiables

La sécurité frontend repose sur la connaissance de ce qui s’exécute dans le navigateur et de ce qui s’exécute sur le serveur. Toute valeur intégrée au JavaScript frontend est publique. Dans Next.js, les variables d’environnement sont réservées au serveur par défaut. Ajouter le préfixe NEXT_PUBLIC_ intègre la valeur de la variable dans le bundle client au moment du build : un agent qui applique ce préfixe à une clé d’API vient donc de la publier.

Masquer un bouton dans l’interface ne constitue pas une autorisation. N’importe qui peut appeler l’API directement : le serveur doit donc vérifier les permissions à chaque requête. Cette défaillance relève de la catégorie OWASP Top 10:2025, A01 Broken Access Control.

Affecter une saisie utilisateur à innerHTML amène le navigateur à l’analyser comme du balisage, y compris des attributs comme onerror qui exécutent du JavaScript. textContent insère la même saisie sous forme de texte brut. JSX échappe par défaut les chaînes interpolées, et dangerouslySetInnerHTML désactive cette protection. L’OWASP XSS Prevention Cheat Sheet couvre le reste.

Comment déboguer du code que vous n’avez pas écrit ?

Déboguer, c’est trouver la cause d’un bug, pas faire disparaître le symptôme. Les agents « corrigent » souvent une erreur en l’enveloppant dans un try/catch qui l’avale, ou en ajoutant un chaînage optionnel qui masque une valeur undefined au lieu de remonter à son origine. L’erreur disparaît de la console, mais le bug est toujours là.

Avant d’accepter une correction, lisez la stack trace, reproduisez le bug et examinez le panneau Network des Chrome DevTools pour voir ce que contenaient réellement la requête et la réponse. Certains bugs n’apparaissent que chez de vrais utilisateurs. Le session replay montre ce que fait le code écrit par l’agent pour ces utilisateurs en production, par exemple une boucle de nouvelles tentatives qui martèle un endpoint ou un formulaire qui échoue silencieusement, et c’est souvent là que les lacunes sur ces fondamentaux deviennent visibles.

Maîtriser Git suffisamment pour relire et annuler les modifications d’un agent

Git vous permet d’accepter une partie du travail d’un agent et d’annuler le reste. Les agents ont tendance à effectuer des modifications de grande ampleur, et les accepter en bloc masque des changements sans rapport. Quatre commandes couvrent l’essentiel de vos besoins :

git diff                 # read every change
git add -p               # stage hunk by hunk
git restore -p src/x.ts  # discard unwanted hunks
git revert <commit>      # undo a committed change

git add -p vous interroge sur chaque hunk avant de l’indexer, et git restore -p supprime les hunks de l’arbre de travail un par un. git revert ajoute un nouveau commit qui inverse un commit antérieur. Cette commande est donc sûre sur les branches partagées, alors que reset réécrit l’historique.

Suffisamment d’architecture pour repérer une solution surdimensionnée

Une bonne architecture résout le problème du moment avec ce dont le projet dispose déjà. Les agents recourent souvent à une nouvelle dépendance, ou à une couche de type factory ou strategy, pour traiter une tâche ponctuelle. Installer une bibliothèque de dates pour formater une seule date en est un cas typique, puisque Intl.DateTimeFormat le fait nativement. Lorsqu’un diff ajoute des fichiers, des paquets ou des abstractions, demandez-vous si le code existant pourrait faire le travail avec moins de fichiers. Si c’est le cas, rejetez la modification ou demandez-en une plus restreinte.

Les habitudes qui vous gardent aux commandes

  • Demandez à l’agent de justifier ses choix. Si vous n’êtes pas en mesure d’évaluer l’explication, vous avez trouvé le prochain fondamental à étudier.
  • Lisez le diff avant d’accepter. Relisez chaque hunk, à chaque fois.
  • Effectuez les petites modifications à la main. Taper une correction vous-même entretient votre compréhension du code.

Les tests transforment votre jugement en vérifications exécutées à chaque modification.

Conclusion

Les agents peuvent écrire le code, mais c’est vous qui êtes responsable de ce qu’il fait. Apprenez la sémantique HTTP, le modèle de rendu du navigateur, la propriété de l’état, les frontières de sécurité, le débogage, Git et la retenue nécessaire pour garder les choses simples : vous serez alors capable de rejeter un mauvais diff et d’expliquer pourquoi. La prochaine fois qu’un agent vous soumet une modification, commencez par lire git diff et identifiez une décision que vous ne savez pas encore expliquer.

FAQ

Axios présente-t-il le même problème d'erreurs HTTP que fetch ?

Non. Par défaut, axios rejette la promesse pour tout statut de réponse en dehors de la plage 200 à 299 : une 404 ou une 500 aboutit donc dans le bloc catch. L'option validateStatus contrôle ce comportement et peut être redéfinie. Une API qui renvoie 200 avec un message d'erreur dans le corps est toutefois résolue avec succès aussi bien par axios que par fetch : le serveur doit donc envoyer des codes de statut corrects.

Est-il sûr de placer des clés d'API dans les variables d'environnement de Vite ?

Uniquement si la variable ne porte pas le préfixe VITE_. Vite expose les variables préfixées par VITE_ au code client via import.meta.env et les remplace de manière statique au moment du build : leurs valeurs se retrouvent donc dans le bundle client. Les variables sans préfixe ne sont pas exposées au code client. Comme NEXT_PUBLIC_ dans Next.js, le préfixe signifie que vous acceptez de publier la valeur et ne la protège en rien : les secrets doivent donc rester sur un serveur.

Comment afficher en toute sécurité du HTML fourni par l'utilisateur lorsque textContent ne suffit pas ?

Assainissez le HTML avant de l'insérer. L'OWASP recommande DOMPurify : passez la chaîne à DOMPurify.sanitize et utilisez le résultat avec innerHTML ou dangerouslySetInnerHTML. Ne modifiez pas la sortie assainie par la suite, car ces changements peuvent réintroduire du balisage dangereux. Maintenez la bibliothèque d'assainissement à jour, car de nouveaux contournements sont régulièrement découverts. Les éditeurs de texte enrichi et le Markdown rédigé par les utilisateurs sont les cas typiques où cette approche est nécessaire.

Pourquoi mon effet React s'exécute-t-il deux fois en développement ?

En développement, le Strict Mode de React monte les composants une fois de plus afin de révéler les effets dépourvus de fonction de nettoyage. Cela ne se produit pas en production. Si la seconde exécution crée des écouteurs, des requêtes ou des abonnements en double, l'effet a besoin d'une fonction de nettoyage qui annule sa mise en place. Désactiver le Strict Mode ou ajouter une garde basée sur une ref pour ignorer la seconde exécution ne fait que masquer le bug.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.