Menu
Français

Console et DevTools : déboguer au-delà du console.log

Les méthodes de la console et les fonctionnalités des DevTools qui rendent le débogage JavaScript bien plus efficace que des console.log à la pelle.

La console, c'est bien plus que log

console.log est souvent le premier outil de débogage qu'on apprend en JavaScript, et pour beaucoup, c'est aussi le dernier. Ça marche, certes, mais l'objet console cache une dizaine d'autres méthodes qui rendent le débogage plus rapide et plus lisible. Et une fois qu'on prend ses marques dans les Chrome DevTools — points d'arrêt, pile d'appels, expressions surveillées —, on finit par sortir log bien moins souvent qu'avant.

Commençons par un tour d'horizon rapide :

index.js
Output
Click Run to see the output here.

Les quatre méthodes écrivent dans la même console, mais les navigateurs les affichent différemment : les avertissements apparaissent sur fond jaune, les erreurs en rouge avec une icône, et les deux incluent la stack trace. Les filtres des DevTools permettent de masquer ou d'isoler chaque niveau — indispensable dès qu'une application génère des centaines de messages.

Afficher plusieurs valeurs sans se fatiguer

Quand tu veux inspecter plusieurs variables d'un coup, évite de les concaténer dans une chaîne de caractères. Passe-les plutôt en arguments séparés — ou mieux, regroupe-les dans un objet pour que chacune porte son étiquette :

index.js
Output
Click Run to see the output here.

L'astuce { user, count } repose sur le raccourci d'objet : le nom de la variable devient la clé. Dans la console, tu verras { user: { name: "Rosa", age: 30 }, count: 3 } et tu pourras déplier user pour l'inspecter. Pas besoin de passer par JSON.stringify, la structure de l'objet reste intacte.

console.table javascript pour les tableaux d'objets

Face à un tableau d'objets, console.log t'affiche un truc replié, illisible. console.table javascript, lui, le rend sous forme de vrai tableau :

index.js
Output
Click Run to see the output here.

Dans la console du navigateur, le premier appel affiche les trois lignes avec des colonnes triables. Le second se limite à name et role. C'est un vrai gain de confort dès qu'on manipule des données structurées — réponses d'API, résultats de requêtes, CSV parsés.

console.dir vs console.log

À première vue, elles se ressemblent, mais leur comportement diffère dès qu'on leur passe un élément du DOM :

const el = document.querySelector("button");

console.log(el);   // affiche le HTML : <button>Click me</button>
console.dir(el);   // affiche la vue objet JS avec toutes les propriétés

log met en forme les éléments comme du HTML. dir, lui, te montre l'objet brut — chaque propriété, chaque gestionnaire d'événement, chaque référence de style calculé. Quand tu veux savoir quelles méthodes ou quels attributs possède un élément, c'est dir qu'il te faut.

Regrouper les messages liés avec console.group

Pendant une longue session de débogage, la console finit vite par être saturée de messages. Les méthodes console.group et console.groupEnd permettent justement d'encadrer les messages liés dans un bloc repliable :

index.js
Output
Click Run to see the output here.

Chaque appel crée un groupe nommé que tu peux replier. Utilise console.groupCollapsed si tu veux que les groupes démarrent repliés par défaut — pratique quand tu ne veux ouvrir que ceux qui te semblent louches.

Mesurer le temps d'exécution avec console.time

Pour un petit check de performance rapide, difficile de faire mieux que console.time et console.timeEnd :

index.js
Output
Click Run to see the output here.

Les étiquettes passées à time et timeEnd doivent être identiques. Rien ne vous empêche de lancer plusieurs chronos en parallèle avec des étiquettes différentes. Cela dit, dès que vous allez plus loin qu'un simple « est-ce que cette boucle rame ? », mieux vaut basculer sur l'onglet Performance des DevTools, qui enregistre toute la timeline et affiche un flame chart complet.

Les assertions : logger uniquement en cas de problème

console.assert n'affiche quelque chose que si la condition est fausse. C'est une façon discrète de laisser des vérifications de cohérence dans votre code sans polluer la console quand tout va bien :

index.js
Output
Click Run to see the output here.

Pratique pour les invariants qui devraient toujours être vrais. Mauvaise idée pour des cas qui peuvent légitimement échouer — dans ces situations-là, mieux vaut lever une erreur.

Afficher la pile d'appels à la demande

console.trace affiche la pile d'appels courante sans rien déclencher. Super utile quand on cherche à savoir qui a appelé une fonction :

index.js
Output
Click Run to see the output here.

La console affiche inner → outer → (top level). Concrètement, dans une vraie appli, c'est comme ça que tu te rends compte que le gestionnaire de clic que tu déboguais est en fait déclenché depuis trois endroits différents.

L'instruction debugger en JavaScript

Le moyen le plus rapide de mettre en pause l'exécution de ton code JavaScript tient en un seul mot :

function computeTotal(items) {
    const subtotal = items.reduce((s, i) => s + i.price, 0);
    debugger;
    return subtotal * 1.08;
}

Quand les DevTools sont ouverts, debugger; se comporte comme un point d'arrêt : l'exécution s'arrête sur cette ligne et tu as accès à tout le débogueur — les variables du scope, la pile d'appels, les contrôles pas-à-pas (step over, step into), et la possibilité d'évaluer des expressions dans le contexte courant. Quand les DevTools sont fermés, debugger; ne fait rien du tout.

La première fois qu'on utilise un vrai débogueur à la place des console.log, ça a un petit côté magique. Plus besoin de décider à l'avance ce qu'on veut afficher : on voit toutes les variables accessibles. On peut avancer pas à pas dans les conditions et observer en direct quelle branche s'exécute. Un bug tordu qui prenait plusieurs minutes se règle en quelques secondes.

Pense à retirer la ligne debugger avant de commit — ou mieux, pose directement des points d'arrêt dans les DevTools en cliquant sur un numéro de ligne dans le panneau Sources.

Astuces Chrome DevTools à connaître

Quelques fonctionnalités qui passent sous le radar pendant des années :

  • Points d'arrêt conditionnels : clic droit sur un numéro de ligne dans Sources, puis définis une condition du genre user.id === 42. Le point d'arrêt ne se déclenche que si la condition est vraie.
  • Logpoints : même menu, « Add logpoint ». Ça affiche un message sans mettre en pause et sans toucher à ton code.
  • $_ dans la console : la dernière expression évaluée. Tu exécutes quelque chose, puis tu récupères le résultat avec $_.
  • $0 : l'élément actuellement sélectionné dans le panneau Elements. $0.textContent inspecte ce sur quoi tu as cliqué.
  • Stocker en variable globale : clic droit sur n'importe quelle valeur dans la console et choisis « Store as global variable ». Tu obtiens temp1, temp2, etc., pour aller bidouiller.
  • Network → Copy as fetch : transforme n'importe quelle requête en appel fetch() que tu peux coller dans la console et modifier.

Aucune de ces astuces n'est indispensable. Mais toutes font gagner du temps une fois qu'elles sont entrées dans les doigts.

Nettoyer avant de déployer

Les console.log oubliés sont sans conséquence en développement, mais polluent la production. Quelques réflexes utiles :

  • Active une règle de lint (no-console dans ESLint) pour repérer les logs qui traînent, avec une exception pour warn et error.
  • Entoure les logs verbeux d'une condition : if (process.env.NODE_ENV !== "production") console.log(...).
  • Privilégie console.debug pour les sorties de type trace — la plupart des bundlers et des agrégateurs de logs savent les filtrer.
  • Encore mieux : écris un petit module de logger (ou utilise une lib comme debug) pour activer et désactiver des catégories de logs sans toucher au code.

Logger n'est pas gratuit. Chaque appel sérialise ses arguments et écrit dans un buffer. Dans une boucle chaude, un log oublié peut ralentir les choses de façon mesurable.

La suite : les expressions régulières

Tu vas passer pas mal de temps à déboguer du code qui manipule des chaînes, et une bonne partie de ce code repose sur les regex — la fonctionnalité la plus compacte et la plus cryptique du langage. Le prochain chapitre commence par une visite en douceur des expressions régulières en JavaScript et des méthodes qui les utilisent.

Questions fréquentes

Quelle est la différence entre console.log et console.dir ?

console.log affiche les valeurs avec le formatage par défaut du navigateur — pour un élément du DOM, ça veut dire qu'il est rendu en HTML. console.dir, lui, affiche toujours la vue objet JavaScript avec toutes ses propriétés. C'est exactement ce qu'il vous faut quand vous voulez inspecter les propriétés d'un élément plutôt que son balisage.

Comment déboguer du JavaScript dans Chrome DevTools sans passer par console.log ?

Ouvrez l'onglet Sources, trouvez votre fichier et cliquez sur un numéro de ligne pour poser un point d'arrêt. Quand l'exécution atteint cette ligne, elle se met en pause : vous pouvez alors inspecter les variables, avancer pas à pas et évaluer des expressions dans la console. Autre option : glisser une instruction debugger; directement dans le code pour déclencher un point d'arrêt depuis la source.

Comment mesurer le temps d'exécution d'un bout de code JavaScript ?

Encadrez le code avec console.time('label') et console.timeEnd('label') en utilisant le même label des deux côtés. La console affiche alors le temps écoulé en millisecondes. Pour un profilage plus poussé, passez par l'onglet Performance des DevTools : il enregistre un flame chart détaillé de tout ce qui s'est exécuté.

À quoi sert console.table ?

console.table affiche les tableaux et les objets sous forme de table triable dans la console, bien plus lisible qu'un objet imbriqué affiché brut. C'est idéal pour un tableau d'objets : chaque objet devient une ligne et ses clés deviennent les colonnes. Un second argument permet en plus de limiter les colonnes affichées.

Apprendre à coder avec Coddy

COMMENCER