There are many pages about source maps online (e.g. this one), but almost none of them go into detail on how to decode VLQs (the smoosh of characters at the bottom of the source map where all the important data is stored), so lots of thanks to Peter van der Zee who wrote it up in enough detail that someone who hadn't heard of VLQs before (me) could write a decoder.
Anyway, one of circumstances in which you might want to use source maps is to provide nice debugging of code that is generated and transpiled to javascript at run time. Most of the common descriptions of source maps assume that you're going to be serving the compiled code, the source map and the original source from some server, but this isn't always what you want.
Fortunately, there are a few notes in the spec that show that the authors understood this. To make source maps work dynamically, you need a combination of two things: the ability to attach actual source into the source map which is provided by the optional sourcesContent field of the sourcemap and also the ability to attach a source map directly to some code rather than have to have it exist as a file somewhere. This is provided by a little note:
Note: <url> maybe a data URI. Using a data URI along with “sourcesContent” allow for a completely self-contained source-map.
I've used the coffeescript compiler here as an example because it can straightforwardly generate the source map for me. Then I modify the provided source map to include the sourcesContent field, encode the whole thing up as a base64 data uri (I use btoa so don't expect this to work in IE), and add the //@ sourceURL= directive pointing at the data URI to the end of the generated code.
Then all that remains is to eval the code.
This works fine in Chrome 29.0.1508.3 canary if you have source maps turned on, but it doesn't work in Firefox 24.0a1 nightly. It might take a little while to make it into all the common browsers.
And here's the code that does it:
If you found this interesting or useful, leave a comment.
comments powered by Disqus