Multi-level Source maps

Source maps are awesome but one issue is that compiling from x-lang to JavaScript is a single level of mapping, if you want to go from x-lang > JavaScript > minified JavaScript you couldn’t as closure compiler, currently, only has a single level of mapping, until now. UglifyJS2 allows you to specify an input source map from the first stage of compilation, enabling multi-level mapping.

Check out the following demonstration showing multi-level source maps for TypeScript and Coffeescript. If you haven’t enabled source maps you can do so in Chrome and WebKit Nightly by opening the dev tools > clicking the cog in the lower right corner > general > enable source maps.

Enabling source maps in Chrome Dev Tools

In Firefox 23+ you can enable it in the build-in dev tools by going to Debugger > then clicking the cog in the top right corner > Show original sources.

Enabling source maps in Firefox Dev Tools

Multi-level what?

Now in code, let’s say CoffeeScript(CS), you can compile to JavaScript and generate a source map using the new redux compiler. You take that generated source map and at the minifying stage, with UglifyJS2, specify --in-source-map option to reference the first level source map, CS > JS, this will map the minified JavaScript directly back to the CS and not the compiled JavaScript output!

This sounds like a lot of work but if you have a build process involved it’s a matter of kicking of a simple cli command to do the work for you and it gives you the kick-arse ability of having the multi-level mappings.

Here are a few snippets on how you can get this going in CoffeeScript or TypeScript. For more info on source map generation check out the TypeScript and CoffeeScript blog posts.

CoffeeScript

$> coffee --js -i test.coffee
$> coffee --source-map -i test.coffee > test.js.map

The first line will compile your CoffeeScript to JS the second line will then generate the source map file.

$> uglifyjs2 test.js 
   -o test.min.js 
   --source-map test.min.js.map 
   --in-source-map test.js.map 
   -m -c

Uglify has a few more options the most important being the --in-source-map which will reference that source map when taking into account the file information and what it’ll output for the second stage source map.

TypeScript

$> tsc greeter.ts -sourcemap

The TypeScript compiler outputs greeter.js and greeter.js.map

$> uglifyjs2 greeter.js 
   -o greeter.min.js 
   --source-map greeter.min.js.map 
   --in-source-map greeter.js.map 
   -m -c

This command is exactly the same as the CoffeeScript example but with the file names changed.

This will work for any other language that compiles to JavaScript that can generate a source map. Check out the source maps wiki for more info.

Source maps works in Chrome, Safari 6.1+, WebKit Nightly, Firefox 23+.

[link href=”http://cssn.in/ja/045″]