SourceMap¶
The need for SourceMap¶
In the past, we built Web applications using only HTML, CSS, and JavaScript and deployed the same files to the web.
Now that we are building more complex Web applications, your development workflow may involve using various tools. For example:
-
Template languages and HTML preprocessors: Pug, Nunjucks, Markdown.
-
JavaScript frameworks: Angular, React, Vue, Svelte.
-
Advanced programming languages: TypeScript, Dart, CoffeeScript.
-
And so on.
These tools require a build process to translate your code into standard HTML, JavaScript, and CSS that the browser can understand. Also, to optimize performance, it's common to minify (for example, using Terser to shrink and mangle JavaScript) and combine these files to reduce their size and improve page efficiency.
For instance, using build tools, we can translate and compress the following TypeScript file into a single line of JavaScript.
/* 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
console.log(num);
});
The compressed version is as follows:
/* A compressed JavaScript version of the TypeScript demo: example.min.js */
document.querySelector("button")?.addEventListener("click",(()=>{const e=Math.floor
However, this optimization makes debugging more difficult. If the minified code puts everything on one line and the variable names are short, it's hard to pinpoint the source of the problem. This is where source maps come in - source maps map your compiled code back to the original code.
Generate SourceMap¶
Source maps are files ending with .map (such as example.min.js.map and styles.css.map). Most build tools can generate source maps, such as Vite, webpack, Rollup, Parcel, esbuild. Some tools include source maps by default, while others may require additional configuration for generation.
/* 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
}
})
Understand SourceMap¶
These source map files contain crucial information about how the compiled code maps to the original code, allowing developers to debug easily. Here is an example of a source code map:
{
"mappings": "AAAAA,SAASC,cAAc,WAAWC, ...",
"sources": ["src/script.ts"],
"sourcesContent": ["document.querySelector('button')..."],
"names": ["document","querySelector", ...],
"version": 3,
"file": "example.min.js.map"
}
The most critical element of a source map is the mappings
field. It uses a VLQ base 64 encoded string to map the lines and positions in the compiled file to the corresponding original file. You can use source map visualization tools like source-map-visualization and source map visualization to present this mapping intuitively and verify the file's usability.
For example: a visualization chart of the code sample generated by the visualization tool source-map-visualization.
The generated column on the left shows the compressed content, and the original column shows the original source.
Visualization tools color-code each line in the original column and the corresponding code in the generated column. The mappings section displays the decoded code mapping. For instance, entry 65-> 2:2 means:
- Generated code: The word const starts at position 65 in the compressed content.
- Original code: The word const starts from the 2nd line and 2nd column in the original content.
This way, developers can quickly determine the relationship between the minified code and the original code, making the debugging process smoother.
Browser developer tools will apply these source code maps to help you debug issues directly in the browser faster.