Nodefony 10.0.0-beta.6
Framework Node.js fullstack — HTTP & WebSocket, même contexte

Barre de débogage — nodefony/debugbar

stablenodefony (cœur)mis à jour 2026-10-24

Une bande fine en bas de page, en développement, qui montre ce que le serveur est en train de faire : le débit temps réel, la charge, la mémoire, les requêtes réseau et les journaux — sans quitter l’écran qu’on est en train de construire.

Elle est livrée avec le cœur et ne dépend d’aucun cadre front : elle s’installe dans une page rendue par un serveur comme dans une application React, Vue, Angular ou Svelte.

📍 Documentation › nodefony — le cœur › Barre de débogage

Démarrage rapide#

/// <reference types="vite/client" />
// Dans un front servi par Vite : `import.meta.env.DEV` vaut true en développement.
import { mountDebugBar } from "nodefony/debugbar";

// En développement uniquement — la barre n'a rien à faire en production.
if (import.meta.env.DEV) mountDebugBar();

Sur une page rendue par le serveur, sans étape de construction :

<script
  type="module"
  src="/node_modules/nodefony/dist/client/debugbar.standalone.js"
></script>

La barre lit le canal temps réel de l’application. Elle n’ouvre aucune seconde connexion : elle partage la socket déjà présente si la page en a une. Et elle ne l’ouvre pas au montage : la socket appartient à l’application, qui décide quand l’ouvrir (la console d’administration attend le login). La barre ne se connecte que quand on lui demande des données — panneau ouvert, ou temps réel démarré.

Ce qu’on voit, et ce qu’on peut faire#

Le bandeau porte l’essentiel en une ligne : le logo, l’environnement du serveur (connu dès le rendu de la page), la branche git (une fois connue), le contrôle « Temps réel », puis le débit, la charge processeur et la mémoire, enfin les compteurs réseau, rechargements à chaud (hmr, avec un front Vite), journaux et erreurs. Ce qui n’est pas encore connu ne s’affiche pas : un badge vide se lirait comme une valeur.

Chaque élément du bandeau porte une aide qui s’ouvre au survol et au focus clavier, et chaque indicateur est un raccourci : cliquer « cpu » ouvre l’onglet qui le détaille. Le bandeau lui-même ne se replie pas au clic : seuls le logo et le bouton « Ouvrir / Fermer » basculent le panneau.

Contrôle Ce qu’il fait
logo ◆ nodefony Ouvre ou ferme le panneau.
Temps réel · <état> Démarre ou arrête les mesures et journaux en direct. Arrêté par défaut (voir ci-dessous).
Réduire Réduit la barre en pastille, dans un coin de l’écran ; la pastille la rouvre.
Ouvrir / Fermer Ouvre ou ferme le panneau.
réglages : À gauche/droite Coin où se pose la pastille réduite (onglet Runtime, carte « Barre de debug · ce navigateur »).

Le contrôle « Temps réel » dit son état en toutes lettres : arrêté, connexion…, en direct, en pause (la socket est ouverte par l’application, mais la barre ne reçoit rien), ou accès refusé — la barre lit les données d’administration, et sans session administrateur le serveur refuse le handshake (401/403, avant toute ouverture). Le refus se lit, il ne se confond pas avec une panne.

Pourquoi le temps réel est arrêté par défaut : l’abonnement fait tourner des compteurs et un émetteur de journaux côté serveur. En développement on ouvre beaucoup d’onglets ; les laisser tous branchés en permanence ferait payer à l’application un travail que personne ne regarde. C’est un choix d’adhésion, pas une option cachée.

Les sept onglets#

Hors Realtime et Requêtes, chaque onglet est fait de cartes, comme la console d’administration : une carte répond à une question. Chaque libellé souligné porte une explication courte, au survol comme au clavier.

Realtime — débit, transport, protocole, état de la socket, frames reçues, pic. C’est la vue de la socket elle-même.

Nodefony Socket et Nodefony SSE — une connexion à la fois, choisie par une rangée de boutons en haut de l’onglet : chaque socket de la page (celle de la barre comprise, étiquetée « barre de debug »), chaque flux SSE vu par l’intercepteur réseau. Pour la connexion choisie : ce qu’elle sait d’elle-même (adresse, état, format, identité, canaux, actions), ses dernières trames, ses notifications par méthode, ses incidents. Rien n’est lu tant que l’onglet est fermé ; l’aller-retour se mesure à l’ouverture et au bouton, jamais en boucle.

Requêtes — les requêtes de la page (fetch et XHR), chacune avec les lignes que le serveur a écrites pour elle, et les autres journaux du serveur en direct. Voir la section suivante.

Perf — une carte par mesure du serveur : processeur, mémoire (tas), boucle d’événements. Chacune donne sa valeur, son pic, sa moyenne sur les 60 dernières secondes et ses seuils — les mêmes paliers que la couleur de la jauge. Tant qu’aucune mesure n’est arrivée, la carte affiche « — », jamais un zéro qui passerait pour une mesure. Temps réel arrêté, un bandeau le dit et l’allume d’un clic. Une dernière carte, Cette page, dit ce que le navigateur sait du chargement : premier octet, DOM prêt, page chargée, ressources et leur poids.

Nodefony client — tout Nodefony dans ce navigateur, que la page compose un noyau client (NodefonyKernel) ou non. Six cartes :

Une puce « client · prêt » apparaît dans la bande dès qu’un noyau est détecté — qu’il soit né avant ou après la barre. Le noyau publie cette sonde en développement seulement : en production, rien n’est posé sur la page.

Runtime — le résumé de la page « Runtime & Lancement » de la console, lu aux mêmes sources : le mode d’exécution (développement, production, cluster — la même règle que la console, runtimeMode), le serveur, ses process, sa charge, Vite et ses fronts. Lu à l’ouverture de l’onglet et au bouton ⟳, jamais en boucle. Sans session administrateur, une phrase le dit et aucune requête ne part. En bas, ce que la barre garde sur ce navigateur.

L’onglet Requêtes#

Trois vues, au choix en haut de l’onglet :

WebSocket et flux d’événements#

La vue Page montre aussi les connexions longues que la page ouvre : une WebSocket (WS), un EventSource ou un fetch qui reçoit text/event-stream (SSE, ce que fait le client NodefonySse). La socket que la page partage avec la barre y figure comme les autres.

Ce que la ligne montre, c’est ce que seul le navigateur sait : la connexion en cours, l’ouverture (101, 200), la fermeture et son code (1000 normale, 1006 coupée, en rouge), un refus avant l’ouverture, les reconnexions d’un EventSource. La colonne durée dit « ouvert » tant que la connexion vit, puis sa durée de vie. Aucune trame n’est lue ni comptée, binaire compris : ce que la socket transporte reste à l’application.

Choisie, une socket retrouve son requestId par sa ligne d’accès dans les journaux, car le navigateur ne lit pas ses en-têtes. Elle se déplie alors sur ses lignes serveur. Le volet liste les appels passés par la socket, c’est-à-dire chaque api.request. Une connexion n’a pas de profil à elle, puisqu’elle ne se termine qu’à sa fermeture, mais chacun de ses appels en a un. Un clic sur un appel affiche ses phases et ses requêtes SQL, comme pour une requête HTTP. Sur une page de la console, choisir la socket ouvre aussi son Suivi de requête, qui reconstitue tout son cycle.

Un flux SSE n’écrit sa ligne d’accès qu’à sa fermeture : son requestId ne se lit qu’alors, sauf s’il passe par fetch, qui lit ses en-têtes dès l’ouverture. Un flux reçu par fetch se sait fermé par son signal d’abandon : sans signal, la ligne reste « ouvert ».

Un clic ouvre le détail dans un seul volet, à côté : pour une requête, ce qui en a été vu, puis son profil serveur (route, contrôleur, utilisateur, chronologie des phases, requêtes SQL) ; pour une ligne, son horodatage complet, sa catégorie, son worker et sa requête — de quoi coller une trace dans un ticket. Le volet s’ouvre à côté plutôt que dans la liste, qui ne bouge donc pas.

La plus récente est en haut, visible sans défiler. Tant que la liste est tout en haut, elle suit le flux. Dès qu’on descend lire, elle se fige : ni les nouvelles qui arrivent au-dessus, ni les anciennes qui partent en dessous, ni une requête qu’on déplie ne déplacent la ligne qu’on lit, et un bouton « ↑ N nouvelles » ramène au flux (Début au clavier fait de même).

La barre d’outils permet de :

Sans interception réseau (network: false), l’onglet ne montre que les lignes du serveur : c’est la seule partie de la barre qui instrumente des fonctions globales du navigateur.

Ce que l’onglet coûte à l’application#

Ce que la barre garde sur votre navigateur#

Huit valeurs, uniquement d’apparence, dans le stockage local — visibles dans l’onglet Runtime, avec un bouton pour les effacer :

Clé Ce qu’elle retient
nf.debugbar.v version du format ci-dessous
nf.debugbar.visible barre affichée ou masquée
nf.debugbar.min réduite en pastille
nf.debugbar.side côté du dock
nf.debugbar.open panneau déplié
nf.debugbar.tab dernier onglet ouvert
nf.debugbar.h hauteur du panneau
nf.debugbar.live flux en direct activé

Rien d’autre n’est stocké : aucun journal, aucune donnée d’application, aucune identité. L’état est versionné — si le format change, l’ancien est effacé au chargement plutôt que réinterprété, ce qui éviterait un état incohérent qu’on ne saurait pas défaire.

Options#

mountDebugBar({
  url: "/nodefony/studio/api/realtime", // adresse du canal temps réel
  client: maSocket, // socket déjà ouverte à partager
  position: "bottom", // ou "top"
  open: true, // force le panneau déplié au montage (absent : l'état laissé par l'utilisateur)
  network: true, // requêtes de la page dans l'onglet Requêtes (instrumente fetch/XHR)
  env: "development", // environnement affiché avant toute mesure (posé par le serveur)
  page: { requestId }, // la requête qui a rendu la page (posé par le serveur)
});

mountDebugBar() est idempotent : une seule barre par page.

Accessibilité#

Tous les contrôles sont des boutons : ils s’atteignent au clavier, portent un nom et annoncent leur état (le replieur et le logo exposent aria-expanded, le temps réel aria-pressed). Leur nom est leur texte visible (WCAG 2.5.3), et leur cible fait 28 px de haut. La pastille réduite est un bouton, atteignable au clavier. Vérifié par axe-core sur la barre repliée et dépliée : aucun défaut. L’aide de chaque indicateur s’ouvre aussi bien au focus qu’au survol. La barre se déclare comme un contenu d’appoint (complementary), ce qui évite que tout ce qu’elle affiche soit compté hors de tout point de repère par un audit de la page hôte.

Coût#

La barre est une entrée séparée du paquet (nodefony/debugbar) : elle ne pèse rien sur une application qui ne l’importe pas. Son budget est vérifié à chaque publication (npm run size:check).

📖 Lexique#

Terme Ce que c’est
Entrée séparée Un sous-chemin du paquet (nodefony/debugbar) importé à part. Ce qui n’est pas importé n’entre pas dans votre bundle.
mountDebugBar La seule fonction à appeler (index.ts#mountDebugBar). Elle installe la barre et rend une poignée pour la piloter ou la retirer.
Poignée (handle) Ce que le montage rend en retour (DebugBarHandle, DebugBar.ts#DebugBarHandle) : de quoi fermer, rouvrir ou démonter proprement.
Options Ce qu’on passe au montage (DebugBarOptions, DebugBar.ts#DebugBarOptions) — l’adresse du socket, la position (bottom ou top), le panneau ouvert d’emblée, et l’interception réseau, qu’on peut refuser entièrement.
Charge utile Ce que le serveur pousse : statistiques (StatsPayload, model.ts#StatsPayload) et journaux (LogEntry, model.ts#LogEntry).
requestId L’identifiant qu’une requête porte de bout en bout. C’est lui qui relie une ligne de journal à l’appel réseau qui l’a produite.

⚠️ Pièges#

🧪 Tests & couverture#

Les chiffres exacts vivent dans la carte de l’aperçu, régénérée en comptant — jamais figés ici.

Type Où Ce qui est prouvé
Unitaires nodefony DebugBar.test.ts le montage, les options, ce que la poignée rend, le rendu des onglets
Unitaires (interaction) nodefony debugbarInteraction.test.ts l’ouverture et la fermeture, le filtrage des journaux, ce qui est gardé d’une visite à l’autre
Unitaires (onglet Requêtes) nodefony debugbarRequestsTab.test.ts, debugbarRequests.test.ts, debugbarFeedView.test.ts les trois vues sur le back des Journaux, le dépliage relu à la demande, le volet unique, les requêtes de la page jamais masquées, une liste fenêtrée qui ne bouge pas sous l’œil
Unitaires (onglet Runtime) nodefony debugbarRuntimeTab.test.ts les quatre sources lues une fois, relues à la réouverture et au bouton, jamais en boucle ; une phrase et zéro requête sans session ; la règle runtimeMode partagée avec la console
Unitaires (onglet Perf) nodefony debugbarPerfTab.test.ts « — » sans mesure, le bandeau qui allume le temps réel, valeur, pic et moyenne en français, la carte « Cette page » hors navigateur
Unitaires (onglet Nodefony client) nodefony debugbarKernel.test.ts la détection du noyau avant ou après la barre, six cartes à une question chacune, chaque valeur expliquée, le compte reconnu par le serveur sans noyau, les raccourcis de la console, aucun écouteur laissé
Unitaires (session) nodefony debugbarSession.test.ts un refus de session se relit, seul l’accord se mémorise

🔗 Pour aller plus loin#