pmuellr is Patrick Mueller

other pmuellr thangs: home page, twitter, flickr, github

Wednesday, November 16, 2011

debugging concatenated JavaScript files

In James Burke's blog post "Why not AMD?", the subject of debugging briefly came up. In response to the claim that AMD is "Inefficient by default", James responds: (bold emphasis applied by me)

I assume this means that it allows separate modules to be loaded async. FWIW, the current state of ES harmony modules will allow separate file loading for each module. This works better for debugging.

For AMD, you can get the "one script file at the bottom of the page" loading with the 750 byte almond AMD shim and runtime http loading.

I cannot see a better solution to this issue. If you have ideas I would like to hear them.

I'd like to point out some futures/options for making concatenated scripts easier to debug. None of solutions deal with mangled names, they're just ways of letting the debugger show a concatenated script as the set of individual scripts that make up the concatenated script. Baby steps!

Source Map support in the web debuggers

Werner Schuster's blog post "Mozilla, WebKit To Support Debugging Minified JS As Well As CoffeeScript and other JS Languages" covers most of the ground for the Source Map work that's ongoing. Chris Heilmann's recent presentation from Velocity "Firefox Performance" mentions some work going on at Mozilla.

Of course, we need both ends working here; minizer's are going to have to be able to spit out Source Maps, as well as language translators like CoffeeScript. The CoffeeScript bug for Source Map work is here (I think).

cheating with eval() and //@ sourceurl

Back in the day, a feature in Firebug that I copied into Web Inspector was "sourceURL" support, described in "Give your eval a name with //@ sourceURL". I recently made use of this in my "unminified" version of the injected target weinre script. weinre ships with two versions of the code that gets injected into the target: target-script.js and target-script-min.js. The "min" version is what you should be using for typical weinre debugging, the non-"min" version is what I use when debugging the debugger.

The file target-script-min.js contains gently minized JS files, just concatenated together. The target-script.js file is a bit different. For every JS file, it adds a "//@ sourceurl" comment to the bottom of the file, converts the script content to a string with JSON.stringify(), and then writes an eval([that string here]) to the concatenated file.

The difference between debugging these in a browser which supports sourceurl is night and day. Try it: after visiting these pages, open your web debugger and look at the scripts which are loaded. Note, this works on Google Chrome 16.0.912.36 beta on a Mac (and likely other versions).