Débogage Web moderne dans les outils pour les développeurs Chrome

Introduction

Aujourd'hui, les auteurs peuvent utiliser de nombreuses abstractions pour créer leurs applications Web. Au lieu d'interagir directement avec les API de niveau inférieur fournies par la plate-forme Web, de nombreux auteurs tirent parti des frameworks, des outils de création et des compilateurs pour écrire leurs applications dans une perspective de niveau supérieur.

Par exemple, les composants basés sur le framework Angular sont créés en TypeScript avec des modèles HTML. En arrière-plan, la CLI Angular et le Webpack compilent tous les éléments en JavaScript dans un groupe, qui est ensuite envoyé au navigateur.

Lors du débogage ou du profilage d'applications Web dans les outils de développement, vous pouvez actuellement voir et déboguer cette version compilée de votre code plutôt que le code que vous avez réellement écrit. En tant qu'auteur, ce n'est toutefois pas ce que vous voulez:

  • Vous ne voulez pas déboguer le code JavaScript réduit, mais votre code JavaScript d'origine.
  • Lorsque vous utilisez TypeScript, vous ne souhaitez pas déboguer JavaScript, mais votre code TypeScript d'origine.
  • Lorsque vous utilisez des modèles, par exemple avec Angular, Lit ou JSX, vous ne devez pas toujours déboguer le DOM obtenu. Vous voudrez peut-être déboguer les composants eux-mêmes.

Dans l'ensemble, vous souhaiterez probablement déboguer votre propre code tel que vous l'avez écrit.

Même si les cartes sources permettent déjà de combler cette lacune dans une certaine mesure, les outils pour les développeurs Chrome et l'écosystème offrent d'autres possibilités dans ce domaine.

Penchons-nous là-dessus.

Code créé et code déployé

Actuellement, lorsque vous parcourez l'arborescence de fichiers dans le panneau "Sources", vous pouvez voir le contenu du groupe compilé, et souvent minimisé. Il s'agit des fichiers que le navigateur télécharge et exécute. Dans les outils de développement, il s'agit du code déployé.

Capture d'écran de l'arborescence de fichiers dans les outils pour les développeurs Chrome montrant le code déployé.

Ce n'est pas très pratique et souvent difficile à comprendre. En tant qu'auteur, vous souhaitez voir et déboguer le code que vous avez écrit, et non le code déployé.

Pour compenser, vous pouvez désormais faire en sorte que l'arborescence affiche le code créé à la place. L'arborescence ressemble ainsi davantage aux fichiers sources que vous voyez dans votre IDE, et ces fichiers sont désormais séparés du code déployé.

Capture d'écran de l'arborescence de fichiers dans les outils pour les développeurs Chrome montrant le code créé.

Pour activer cette option dans les outils pour les développeurs Chrome, accédez à Paramètres > Tests, puis cochez la case Regrouper les sources dans les arbres créés et déployés.

Capture d'écran des paramètres des outils de développement.

"Seulement mon code"

Lorsque vous utilisez des dépendances ou utilisez un framework, les fichiers tiers peuvent vous gêner. La plupart du temps, vous souhaitez uniquement afficher votre code, et non celui d'une bibliothèque tierce cachée dans le dossier node_modules.

Pour compenser, un paramètre supplémentaire est activé par défaut dans les outils de développement: Ajouter automatiquement des scripts tiers connus à la liste des éléments à ignorer. Vous pouvez le trouver dans DevTools > Settings > Ignore List (Outils de développement > Paramètres > Liste d'éléments à ignorer).

Capture d'écran des paramètres des outils de développement.

Lorsque ce paramètre est activé, les outils de développement masquent tous les fichiers ou dossiers qu'un framework ou un outil de compilation a marqués comme à ignorer.

Depuis la version Angular v14.1.0, le contenu de ses dossiers node_modules et webpack est marqué comme tel. Par conséquent, ces dossiers, les fichiers qu'ils contiennent et les autres artefacts tiers ne s'affichent pas à différents endroits dans les outils de développement.

En tant qu'auteur, aucune action de votre part n'est requise pour activer ce nouveau comportement. Il appartient au cadre de mettre en œuvre ce changement.

Code à ignorer dans les traces de la pile

Ces fichiers de la liste des éléments à ignorer ne s'affichent plus dans les traces de la pile. En tant qu'auteur, vous avez désormais accès à des traces de pile plus pertinentes.

Capture d'écran d'une trace de la pile dans les outils de développement.

Pour voir tous les frames d'appel de la trace de la pile, vous pouvez toujours cliquer sur le lien Show more frames (Afficher plus de frames).

Il en va de même pour les piles d'appels que vous voyez lors du débogage et de l'exécution du code. Lorsque les frameworks ou les bundlers informent les outils de développement sur les scripts tiers, ils masquent automatiquement tous les frames d'appel non pertinents et passent au-dessus du code de la liste des éléments à ignorer lors du débogage par étapes.

Capture d'écran du débogueur des sources d'outils de développement lors du débogage.

Code à ignorer dans l'arborescence de fichiers

Pour masquer les fichiers et dossiers ajoutés à la liste des éléments à ignorer dans l'arborescence de fichiers Code créé dans le panneau Sources, cochez la case Masquer le code de la liste des éléments à ignorer dans l'arborescence des sources dans Paramètres > Tests dans les Outils de développement.

Capture d'écran des paramètres des outils de développement.

Dans l'exemple de projet Angular, les dossiers node_modules et webpack sont désormais masqués.

Capture de l'arborescence de fichiers dans les outils pour les développeurs Chrome montrant le code créé, mais pas node_modules.

Code à ignorer dans le menu "Ouverture rapide"

Le code figurant dans la liste des éléments ignorés est masqué dans l'arborescence des fichiers. Il est également masqué dans le menu "Ouverture rapide" (Ctrl + P (Linux/Windows) ou Commande + P (Mac)).

Capture d'écran des outils de développement avec le menu "Ouverture rapide".

Autres améliorations apportées aux traces de la pile

Après avoir traité les traces de pile pertinentes, les outils pour les développeurs Chrome apportent encore plus d'améliorations.

Traces de pile associées

Lorsque certaines opérations sont planifiées de manière asynchrone, les traces de la pile dans les outils de développement ne racontent actuellement qu'une partie de l'histoire.

Par exemple, voici un planificateur très simple dans un fichier framework.js hypothétique:

function makeScheduler() {
  const tasks = [];

  return {
    schedule(f) {
      tasks.push({ f });
    },

    work() {
      while (tasks.length) {
        const { f } = tasks.shift();
        f();
      }
    },
  };
}

const scheduler = makeScheduler();

function loop() {
  scheduler.work();
  requestAnimationFrame(loop);
};

loop();

... et comment un développeur peut l'utiliser dans son propre code dans un fichier example.js:

function someTask() {
  console.trace("done!");
}

function businessLogic() {
  scheduler.schedule(someTask);
}

businessLogic();

Lorsque vous ajoutez un point d'arrêt dans la méthode someTask ou que vous inspectez la trace imprimée dans la console, vous ne verrez aucune mention de l'appel businessLogic() qui était la "cause racine" de cette opération.

À la place, vous ne voyez que la logique de planification du framework qui a conduit à l'exécution de la tâche, et aucun fil d'Ariane dans la trace de la pile pour vous aider à déterminer les liens de cause à effet entre les événements menant à cette tâche.

Trace de la pile d'un code asynchrone exécuté sans informations sur la date de planification

Grâce à une nouvelle fonctionnalité appelée "Tag de pile asynchrone", il est possible de raconter toute l'histoire en associant les deux parties du code asynchrone.

L'API Async Stack Tagging a été introduite par une nouvelle méthode console nommée console.createTask(). La signature de l'API se présente comme suit:

interface Console {
  createTask(name: string): Task;
}

interface Task {
  run<T>(f: () => T): T;
}

L'appel console.createTask() renvoie une instance Task que vous pouvez ensuite utiliser pour exécuter le f du contenu de la tâche.

// Task Creation
const task = console.createTask(name);

// Task Execution
task.run(f);

La tâche constitue le lien entre le contexte dans lequel elle a été créée et le contexte de la fonction asynchrone en cours d'exécution.

Appliqué à la fonction makeScheduler ci-dessus, le code devient le suivant:

function makeScheduler() {
  const tasks = [];

  return {
    schedule(f) {
      const task = console.createTask(f.name);
      tasks.push({ task, f });
    },

    work() {
      while (tasks.length) {
        const { task, f } = tasks.shift();
        task.run(f); // instead of f();
      }
    },
  };
}

Grâce à cela, les outils pour les développeurs Chrome peuvent désormais afficher une meilleure trace de la pile.

Trace de la pile d&#39;un code asynchrone exécuté avec des informations sur la date de planification

Notez que businessLogic() est désormais inclus dans la trace de la pile. En outre, la tâche porte un nom familier someTask au lieu du nom générique requestAnimationFrame, comme précédemment.

Cadres d'appel conviviaux

Les frameworks génèrent souvent du code à partir de toutes sortes de langages de création de modèles lors de la création d'un projet, comme les modèles Angular ou JSX qui transforment du code HTML en JavaScript simple qui s'exécute finalement dans le navigateur. Parfois, ces types de fonctions générées reçoivent des noms peu conviviaux, qu'il s'agisse de noms à une seule lettre après leur réduction ou de noms obscurs ou inconnus, même s'ils ne le sont pas.

Dans l'exemple de projet, AppComponent_Template_app_button_handleClick_1_listener, que vous voyez dans la trace de la pile, est un exemple.

Capture d&#39;écran de la trace de la pile avec un nom de fonction généré automatiquement.

Pour résoudre ce problème, les outils pour les développeurs Chrome permettent désormais de renommer ces fonctions via des cartes sources. Si un mappage source comporte une entrée de nom pour le début d'un champ d'application de fonction, le cadre d'appel doit afficher ce nom dans la trace de la pile.

En tant qu'auteur, aucune action de votre part n'est requise pour activer ce nouveau comportement. Il appartient au cadre de mettre en œuvre ce changement.

Perspectives d'avenir

Grâce aux ajouts décrits dans cet article, les outils pour les développeurs Chrome peuvent vous offrir une meilleure expérience de débogage. Il y a d'autres domaines que l'équipe aimerait explorer. En particulier, comment améliorer l'expérience de profilage dans les outils de développement.

L'équipe des outils pour les développeurs Chrome encourage les auteurs de frameworks à adopter ces nouvelles fonctionnalités. L'article Étude de cas: Améliorer le débogage Angular avec les outils de développement fournit des conseils sur la façon de procéder.