Que sont les cartes sources ?

Les cartes sources constituent un outil crucial dans le développement Web moderne, car elles facilitent considérablement le débogage. Cette page explore les principes de base des cartes sources, comment elles sont générées et comment elles améliorent l'expérience de débogage.

Le besoin de cartes sources

Les premières applications Web ont été conçues avec peu de complexité. Les développeurs ont déployé des fichiers HTML, CSS et JavaScript directement sur le Web.

Les applications Web plus modernes et complexes peuvent nécessiter une variété d'outils dans leur workflow de développement. Exemple :

Brève présentation des différents outils.
Certains des outils de développement d'applications Web courants.

Ces outils nécessitent un processus de compilation pour transpiler votre code en code HTML, JavaScript et CSS standard compréhensible par les navigateurs. Il est également courant d'optimiser les performances en minimisant et en combinant ces fichiers à l'aide d'un outil comme Terser.

Par exemple, à l'aide des outils de compilation, nous pouvons transpiler et compresser le fichier TypeScript suivant en une seule ligne de JavaScript. Vous pouvez l'essayer vous-même dans cette démonstration sur 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, la compression de votre code peut compliquer le débogage. Les cartes sources permettent de résoudre ce problème: en mappant le code compilé au code d'origine, elles peuvent vous aider à trouver rapidement la source d'une erreur.

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, y compris Vite, webpack, Rollup, Parcel et esbuild.

Certains outils incluent des cartes sources par défaut. 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

Pour faciliter le débogage, ces fichiers de mappage source contiennent des informations essentielles sur la façon dont le code compilé est mappé au code d'origine. 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 la spécification de la carte source ou la anatomie d'une carte source.

La partie la plus importante d'une carte source est le champ mappings. Elle utilise une chaîne encodée en base 64 VLQ pour mapper les lignes et les emplacements du fichier compilé avec le fichier d'origine correspondant. Vous pouvez afficher ce mappage à l'aide d'un visualiseur de carte source tel que source-map-visualization ou Source Map Visualization.

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

La colonne generated à gauche montre le contenu compressé et la colonne original affiche la source d'origine.

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

La section mappings 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.
Visualisation cartographique, axée sur l'entrée 65 -> 2:2

Cela permet aux développeurs d'identifier rapidement 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 de navigateurs appliquent ces mappages sources pour vous aider à identifier rapidement les problèmes de débogage dans le navigateur.

Outils pour les développeurs appliquant une carte source.
Exemple de la façon dont les outils pour les développeurs pour navigateur appliquent les cartes sources et affichent les mappages entre les fichiers.

Extensions de carte source

Les mappages sources sont compatibles avec les champs d'extension personnalisés commençant par le préfixe x_. Prenons l'exemple 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 façon dont ces extensions vous aident à vous concentrer sur votre code.

Inconvénients des cartes sources

Malheureusement, les mappages de sources ne sont pas toujours aussi complets que vous le souhaitez. Dans notre premier exemple, la variable greet a été optimisée lors du processus de compilation, même si sa valeur est directement intégrée dans la sortie de chaîne finale.

Le message d'accueil variable n'est pas mappé.
La variable greet dans le code d'origine ne figure pas dans le mappage.

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. Ce type d'erreur peut compliquer la surveillance et l'analyse de votre code.

Le message d'accueil variable n'est pas défini.
L'outil pour les développeurs n'a trouvé aucune valeur pour greet.

C'est un problème qui doit être résolu dans la conception des cartes sources. Une solution potentielle consiste à inclure des informations de champ d'application dans les mappages sources de la même manière que 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 la spécification et l'implémentation de la carte source. Pour découvrir comment améliorer le débogage avec les mappages sources, consultez la proposition de cartes sources v4 sur GitHub.