Quellzuordnungen sind ein wichtiges Tool in der modernen Webentwicklung, das die Fehlerbehebung erheblich erleichtert. Auf dieser Seite werden die Grundlagen von Source Maps erläutert, wie sie generiert und wie sie die Fehlerbehebung verbessern.
Die Notwendigkeit von Source Maps
Die ersten Webanwendungen wurden mit geringer Komplexität erstellt. Entwickler stellten HTML-, CSS- und JavaScript-Dateien direkt im Web bereit.
Moderne und komplexe Webanwendungen erfordern unter Umständen eine Vielzahl von Tools in ihrem Entwicklungsworkflow. Beispiel:
- Vorlagensprachen und HTML-Präprozessoren: Pug, Nunjucks, Markdown.
- CSS-Präprozessoren: SCSS, LESS, PostCSS
- JavaScript-Frameworks: Angular, React, Vue, Svelte
- JavaScript-Meta-Frameworks: Next.js, Nuxt und Astro.
- Übergeordnete Programmiersprachen: TypeScript, Dart, CoffeeScript.
![Ein kurzer Überblick über verschiedene Tools.](https://web.dev/static/articles/source-maps/image/a-brief-overview-various-769879995ff7c.png?authuser=6&hl=de)
Diese Tools erfordern einen Build-Prozess, um den Code in standardmäßigen HTML-, JavaScript- und CSS-Code zu transpilieren, den Browser verstehen können. Außerdem wird die Leistung häufig durch Reduzieren und Kombinieren dieser Dateien mit einem Tool wie Terser optimiert.
Mit Build-Tools können wir beispielsweise die folgende TypeScript-Datei transpilieren und in eine einzige JavaScript-Zeile komprimieren. In dieser Demo auf GitHub kannst du es selbst ausprobieren.
/* 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);
});
Eine komprimierte Version wäre:
/* 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)}));
Das Komprimieren des Codes kann das Debugging jedoch erschweren. Quellzuordnungen können dieses Problem beseitigen: Indem Sie den kompilierten Code dem ursprünglichen Code zuordnen, können Sie die Fehlerquelle schnell finden.
Quellzuordnungen generieren
Quellzuordnungen sind Dateien, deren Namen auf .map
enden, z. B. example.min.js.map
und styles.css.map
. Sie können von den meisten Build-Tools wie Vite, Webpack, Rollup, Parcel und esbuild generiert werden.
Einige Tools enthalten standardmäßig Quellzuordnungen. Andere erfordern möglicherweise eine zusätzliche Konfiguration, um sie zu erstellen:
/* 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
}
})
Source Map
Diese Source Map-Dateien enthalten wichtige Informationen dazu, wie der kompilierte Code dem ursprünglichen Code zugeordnet wird, um die Fehlerbehebung zu erleichtern. Hier ist ein Beispiel für eine Source Map:
{
"mappings": "AAAAA,SAASC,cAAc,WAAWC, ...",
"sources": ["src/script.ts"],
"sourcesContent": ["document.querySelector('button')..."],
"names": ["document","querySelector", ...],
"version": 3,
"file": "example.min.js.map"
}
Informationen zu den einzelnen Feldern finden Sie in der Source Map-Spezifikation oder unter Anatomie einer Source Map.
Der wichtigste Teil einer Source Map ist das Feld mappings
. Dabei wird ein VLQ-Base 64-codierter String verwendet, um Linien und Orte in der kompilierten Datei der entsprechenden Originaldatei zuzuordnen. Sie können sich diese Zuordnung mithilfe eines Visualizers wie source-map-visualization oder Source Map Visualization ansehen.
![Eine Source Map-Visualisierung.](https://web.dev/static/articles/source-maps/image/a-source-map-visualizatio-4866bc351df59.png?authuser=6&hl=de)
Die Spalte Generiert auf der linken Seite zeigt den komprimierten Inhalt und die Spalte Original die Originalquelle.
Der Visualizer kennzeichnet jede Zeile in der Spalte original mit dem entsprechenden Code in der Spalte Generated farblich.
Der Abschnitt mappings enthält decodierte Zuordnungen des Codes. Der Eintrag 65 -> 2:2
bedeutet beispielsweise:
- Generierter Code: Das Wort
const
beginnt im komprimierten Inhalt an Position 65. - Originalcode: Das Wort
const
beginnt in Zeile 2 und Spalte 2 des Originalinhalts.
![Zuordnungseintrag.](https://web.dev/static/articles/source-maps/image/mapping-entry-dc9df15808405.png?authuser=6&hl=de)
65 -> 2:2
So können Entwickler schnell die Beziehung zwischen dem minimierten Code und dem ursprünglichen Code erkennen, was die Fehlerbehebung vereinfacht.
Die Entwicklertools des Browsers wenden diese Quellzuordnungen an, damit Sie Fehler bei der Fehlerbehebung schnell im Browser lokalisieren können.
![Entwicklertools, die eine Source Map anwenden.](https://web.dev/static/articles/source-maps/image/developer-tools-applies-ea66f57e838eb.png?authuser=6&hl=de)
Quellzuordnungserweiterungen
Quellzuordnungen unterstützen benutzerdefinierte Erweiterungsfelder, die mit dem Präfix x_
beginnen. Ein Beispiel hierfür ist das von den Chrome-Entwicklertools vorgeschlagene Erweiterungsfeld x_google_ignoreList
. Unter x_google_ignoreList finden Sie weitere Informationen dazu, wie Sie sich mithilfe dieser Erweiterungen auf Ihren Code konzentrieren können.
Nachteile der Source Map
Leider sind Quellzuordnungen nicht immer so vollständig, wie Sie sie benötigen.
In unserem ersten Beispiel wurde die Variable greet
während des Build-Prozesses optimiert, obwohl ihr Wert direkt in die endgültige Stringausgabe eingebettet ist.
![Variable „Begrüßung“ ist nicht zugeordnet.](https://web.dev/static/articles/source-maps/image/variaqble-greet-is-map-a93a440f3c171.png?authuser=6&hl=de)
greet
im ursprünglichen Code fehlt in der Zuordnung.In diesem Fall können die Entwicklertools bei der Fehlersuche im Code möglicherweise den tatsächlichen Wert nicht ableiten und anzeigen. Diese Art von Fehler kann das Monitoring und die Analyse Ihres Codes erschweren.
![Die Variable „begrüß“ ist nicht definiert.](https://web.dev/static/articles/source-maps/image/variable-greet-is-undefin-19fcbf9a06a26.png?authuser=6&hl=de)
greet
gefunden.Dies ist ein Problem, das innerhalb des Designs von Source Maps gelöst werden muss. Eine mögliche Lösung besteht darin, Informationen zum Umfang in die Source Maps auf die gleiche Weise wie in anderen Programmiersprachen mit ihren Fehlerbehebungsinformationen aufzunehmen.
Dies erfordert jedoch, dass das gesamte System zusammenarbeiten, um die Spezifikation und Implementierung der Source Map zu verbessern. Informationen zur Verbesserung der Debugging-Fähigkeit mit Quellzuordnungen finden Sie im Vorschlag für Source Maps Version 4 auf GitHub.