Que sont les cartes sources ?

Améliorez l'expérience de débogage Web avec les mappages sources.

Aujourd'hui, nous parlons des cartes sources, un outil essentiel au développement Web moderne qui simplifie considérablement le débogage. Dans cet article, nous allons découvrir les principes de base des mappages sources, comment ils sont générés et comment ils améliorent l'expérience de débogage.

Le besoin de cartes sources

Autrefois, nous concevions des applications Web en HTML, CSS et JavaScript pur, et nous déployions les mêmes fichiers sur le Web.

Cependant, étant donné que nous créons des applications Web plus complexes de nos jours, votre workflow de développement peut nécessiter l'utilisation de divers outils. Exemple :

Brève présentation des différents outils.

Ces outils nécessitent un processus de compilation pour transpiler votre code en code HTML, JavaScript et CSS standard compréhensible par les navigateurs. En outre, pour optimiser les performances, il est courant de compresser ces fichiers (par exemple, à l'aide de Terser pour minimiser et brouiller JavaScript), puis de combiner ces fichiers afin de réduire leur taille et de les rendre plus efficaces pour le Web.

Par exemple, à l'aide des outils de compilation, nous pouvons transpiler et compresser le fichier TypeScript suivant en une seule ligne de code JavaScript. Vous pouvez essayer la démonstration disponible dans mon dépôt GitHub.

/* A TypeScript demo: example.ts */

document.querySelector('button')?.addEventListener('click', () => {
  const num: number = Math.floor(Math.random() * 101);
  const greet: string = 'Hello';
  (document.querySelector('p') as HTMLParagraphElement).innerText = `${greet}, you are no. ${num}!`;
  console.log(num);
});

Une version compressée serait:

/* A compressed JavaScript version of the TypeScript demo: example.min.js  */

document.querySelector("button")?.addEventListener("click",(()=>{const e=Math.floor(101*Math.random());document.querySelector("p").innerText=`Hello, you are no. ${e}!`,console.log(e)}));

Cependant, cette optimisation peut compliquer le débogage. Un code compressé avec tout sur une seule ligne et des noms de variables plus courts peut compliquer l'identification de la source d'un problème. C'est là qu'interviennent les mappages sources : ils mappent votre code compilé au code d'origine.

Générer des cartes sources

Les cartes sources sont des fichiers dont le nom se termine par .map (par exemple, example.min.js.map et styles.css.map). Ils peuvent être générés par la plupart des outils de compilation, tels que Vite, webpack, Rollup, Parcel, esbuild, etc.

Certains outils incluent des cartes sources par défaut, tandis que d'autres peuvent nécessiter une configuration supplémentaire pour les générer.

/* Example configuration: vite.config.js */
/* https://vitejs.dev/config/ */

export default defineConfig({
  build: {
    sourcemap: true, // enable production source maps
  },
  css: {
    devSourcemap: true // enable CSS source maps during development
  }
})

Comprendre la carte source

Ces fichiers de mappage source contiennent des informations essentielles sur la façon dont le code compilé est mappé au code d'origine, ce qui permet aux développeurs d'effectuer facilement le débogage. Voici un exemple de carte source.

{
  "mappings": "AAAAA,SAASC,cAAc,WAAWC, ...",
  "sources": ["src/script.ts"],
  "sourcesContent": ["document.querySelector('button')..."],
  "names": ["document","querySelector", ...],
  "version": 3,
  "file": "example.min.js.map"
}

Pour comprendre chacun de ces champs, vous pouvez lire les spécifications de la carte source ou cet article classique sur l'anatomie d'une carte source.

L'aspect le plus critique d'une carte source est le champ mappings. Il utilise une chaîne encodée en base 64 VLQ pour faire correspondre les lignes et les emplacements du fichier compilé avec le fichier d'origine correspondant. Ce mappage peut être visualisé à l'aide d'un visualiseur de carte source tel que source-map-visualization et Source Map Visualization.

Visualisation de la carte source.
L'image illustre la visualisation de l'exemple de code précédent, généré par un visualiseur.

La colonne généré à gauche affiche le contenu compressé et la colonne original affiche la source d'origine.

Le visualiseur attribue un code couleur à chaque ligne de la colonne original et le code correspondant dans la colonne generated.

La section Mappages affiche les mappages décodés du code. Par exemple, l'entrée 65-> 2:2 signifie:

  • Code généré: le mot const commence à la position 65 dans le contenu compressé.
  • Code d'origine: le mot const commence à la ligne 2 et à la colonne 2 du contenu d'origine.

Entrée de mappage.

De cette façon, les développeurs peuvent rapidement identifier la relation entre le code réduit et le code d'origine, ce qui fluidifie le processus de débogage.

Les outils pour les développeurs du navigateur appliquent ces mappages sources pour vous aider à identifier plus rapidement les problèmes de débogage, directement dans les navigateurs.

Les outils pour les développeurs appliquent un mappage source.

L'image montre comment les outils pour les développeurs pour navigateur appliquent les cartes sources et indiquent les mappages entre les fichiers.

Extensions de carte source

Les cartes sources prennent en charge les extensions. Les extensions sont des champs personnalisés qui commencent par la convention d'attribution de noms x_. C'est par exemple le cas du champ d'extension x_google_ignoreList proposé par les outils pour les développeurs Chrome. Consultez x_google_ignoreList pour en savoir plus sur la manière dont ces extensions vous aident à vous concentrer sur votre code.

Ce n'est pas parfait

Dans notre exemple, la variable greet a été optimisée lors du processus de compilation. La valeur a été intégrée directement dans la sortie de chaîne finale.

Le message d'accueil variable n'est pas une carte.

Dans ce cas, lorsque vous déboguez le code, il se peut que les outils pour les développeurs ne puissent pas déduire ni afficher la valeur réelle. Les outils pour les développeurs de navigateurs ne sont pas les seuls défis à relever. Cela complique également la surveillance et l'analyse du code.

Le message d'accueil variable n'est pas défini.

Il s'agit bien entendu d'un problème à résoudre. L'une des méthodes consiste à inclure les informations de portée dans les cartes sources, comme le font d'autres langages de programmation avec leurs informations de débogage.

Cependant, cela nécessite que l'ensemble de l'écosystème collabore pour améliorer les spécifications et l'implémentation des cartes sources. Une discussion active est en cours sur l'amélioration du débogage avec les mappages sources.

Nous sommes impatients d'améliorer les mappages de sources et de simplifier encore plus le débogage.