Getting started with JavaScript Source Maps

Jeremy BoydProduct Updates, Provider Updates, Web Development4 Comments

maps

Source Maps

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:

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:

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:

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:

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:

Minified stack trace

Into this (current design, likely to change):

Decoded Stack Trace

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.

Next level software intelligence across your entire stack.

4 Comments on “Getting started with JavaScript Source Maps”

  1. Paul

    Interesting blog post. I’m still a bit confuses about what needs to be deployed to the site? Using web essentials with visual studio i have 3 JavaScript files which I have have minified. This has given me files.js, files.min.js and files.min.js.map. Looking at the map file, the source points to my original 3 JavaScript files before minifying. So what do I deploy to the server? Your blog states you make the page load files.min.js file only. But if my map file points to the original 3 files, surely they need to be on the server too?

    1. Jeremy Boyd

      It depends on what level of information you want and how sensitive you are to deploying the original source files. We only need the minified file and the map file to be present to translate the minified stack into its decoded form. If you want the source code snippets to be also present in your error reports within Raygun then you will need the source files deployed which we then used to grab the snippets from.

      tldr; Deploy the .min.js and .min.js.map files to get stack translation, additionally deploy the source .js files to get snippets

      Jeremy

  2. midhun

    Hi, I have a backbone.js application and I am using r.js optimizer. I have a number of modules which combines multiple files to single file. I have enabled generateSourceMap:true in r.js config and I use uglify2 for minification. I could see the source files and .map files generated. But when I look at the chrome dev tools it doesn’t show me the .src.js files instead of minified files. The minified files has the comment as the last line to do the source mapping. Can you help me to find out what am I doing wrong. Is there some difference when we combine files?

  3. Pingback: JavaScript debugging made easy with source maps

Leave a Reply

Your email address will not be published. Required fields are marked *