Getting started with JavaScript Source Maps
Posted Feb 28, 2014 | 6 min. (1072 words)It’s standard practice to minify your JavaScript for production deployments to improve performance for end users but this has the unfortunate side effect of making debugging production issues quite difficult and line 1 quickly becomes a very popular number. Thankfully in more recent times we can leverage a JavaScript source map file to map between a minified version of our JavaScript and the un-minified source.
Source Maps are a JSON based mapping format which can be used by any processed file to create a mapping relationship between source and processed output. We can use source maps for our minified JavaScript, our CoffeeScript output, our Less output and our Sass output! If you are interested in the technical details on how the mapping works and what the source map file contains you can read up on the revision 3 proposal document. For handling translation of our minified JavaScript we want to produce a JavaScript source map.
Generating JavaScript Source Maps
To get started you will need a tool which can help produce a source map as part of producing a minified version of your JavaScript. We personally use UglifyJS and find it to be a most excellent tool. To install it you will need Node.js installed (even if you’re not a Node dev, this is pretty easy), you can then run:
npm install uglify-js -g
This will install Uglify so that its globally available which is what you will typically want.
As an example lets assume we have a file called source.js, we want to install this as part of our web application. Using Uglify we can minify the file and produce a source map at the same time by executing:
uglifyjs source.js -o source.min.js --source-map source.min.js.map
There are some other options which you may want to use, Ill describe the effect of these shortly.
- –source-map-root – This applies a root path to the source files described in your map file
- –source-map-url – The path to the source map on your server which can either be absolute or relative to the deployed file
If you open up source.min.js after it has been produced by Uglify you will notice there is a comment at the end of the file which looks like this:
//# sourceMappingURL=source.js.map
This comment is a convention to indicate we have a map file available and is used to indicate where the map file is downloaded from. If you used the –source-map-url option with Uglify earlier than the URL would be adjusted with the path you specified there.
It’s standard for this comment to be produced by tooling like Uglify however there is another approach available for indicating where the source map might be which is to include a X-SourceMap HTTP header in your response when serving the minified file. This relies on your web server being configured accordingly so generally having the comment is going to be a much simpler and more achievable approach to use.
If you open up the map file it will look something like:
{"version":3,"file":"source.min.js","sources":["source.js"],"names":["the","quick","brown","fox","jumped","over","the","lazy","orcs","trolls","dwarves","elves","and","peons"],"mappings":"AAAA,QAASA,QACPC,OAAOC,OAGT,QAASC,QACPC,QAAQC,IAAI,qBACZL,QAGF,QAASM,QACR,GAAIC,EAEJA,GAAI,CACJJ,MAAKI,GAGN,QAASC,WACR,GAAIC,KAAKC,GACT,IAAIC,IACJF,KAAM,MACNH,MAAKG,KAGNR,OAAOW,KAAK,4BAA4BC,QAExCL"}
You can see the file contains the name of the file it should be related to (source.min.js), the source files which it maps to (source.js) and set of names and mappings which describe the relationships between file and sources. File can be an absolute or relative URI describing how to reach the file and likewise the filenames in the sources array can be absolute or relative paths. If you used the –source-map-root option with Uglify earlier the sources would be adjusted based on the path specified with that option.
In practice the names and mappings sections are likely to be quite substantial. Its not uncommon for your map file to rival the size of your original source files. Also bear in mind with tools like Uglify you may be combining multiple source files into a single minified output and so the sources section can contain multiple entries.
Now that we have our minified output and the mapping file we can deploy source.min.js and source.min.js.map as part of our web application. You will still refer to the minified file as you would want to and ordinarily this will be the only file that is downloaded. Interested parties (e.g. Developer consoles in Chrome and Firefox) however will now be able to use the map file to present you with information based on the original source file rather than the minified version which is actually being used. If you open up your developer console and watch an error occur you will notice that the stack information will appear based on your original source file – exactly what we want!
Behind the scenes there is a bit of a dance occurring to get all this information, here is a quick overview of whats happening:
- Your browser loads the initial page and downloads source.min.js as it is referenced
- An error occurs in the JavaScript contained within source.min.js, typically this will be handled by window.onError
- The developer console goes to render our this error and the associated stack trace. On inspection of source.min.js it notices there is an end of file comment which conforms to the format to indicate a source map file is present
- Your browser now downloads source.min.js.map, if this file exists the map file will be processed and we will start attempting to decode the stack based on the mappings contained in this file. If there is a successful mapping the updated reference will point to a line number, column number and symbol in source.js rather than source.min.js
JavaScript Source Maps with Raygun
We have taken a keen interest in source maps as many of our users are debugging production errors using Raygun and we have recently added in support for processing any available source maps to decode the stack traces in errors we receive so that the stack is translated back against the original source file which radically assists in understanding what has occurred. This allows us to translate this:
Into this (current design, likely to change):
If you are using minified JavaScript and debugging production issues you should integrate JavaScript source maps into your deployments.
Next steps
To start using SourceMaps with Raygun update your copy of raygun.js to 1.7 or later, make sure you have deployed your source map and optionally your source files if you want the snippets to be shown along with the stack trace. You can find more information in our documentation about how to set this up.