Anyone who has tried to debug minified code knows how mind-bogglingly painful it is. Variables are one- or two-letters long, everything is on one line or a series of compacted lines, and stack-traces are down-right useless. This is where source maps can
help. A source map is an external file created during the build process that maps the generated code back into the original sources. Tools can take the minified code, read in the source map, and take you from the minified gobbledygook right to the original
point in your well-formatted and [hopefully] commented sources.
Creating a source map with AjaxMin is easy: specify the
–map:MTYPE MFILE switch on the
command-line, with the MTYPE value either
V3 or XML. The source map will be created at the file path pointed to by
MFILE. Be sure you have write access to that path. Currently only two formats have been implemented: the Script# XML source map format (“XML”), and the Google JSON V3 Source Map format (“V3”).
[Note: if the MTYPE value is left off the switch,
XML will be assumed for backwards-compatibility.]
JSON V3 Source Map Format, –map:v3
The V3 source map format generates a JSON object that can be consumed by applications such as Chrome. This format is quickly becoming an Internet standard; other browsers will or will soon have support for this format as well. A quick
Bing search can deliver a wealth of information on how to set up the various browsers or tools to read these source map files. The format itself is well-documented on the Google website:
Source Map Revision 3 Proposal. The gist is that the output is a UTF-8-encoded JSON object literal with a few specific properties defined upon it. The mappings are encoded in relative VLQ Base-64 sequences to provide for more compacted output than previous
formats. A typical example may look like:
In this example, two source files (SourceFile1.js and SourceFile2.js) have been minified to the file minifiedCode.js. This source map maps the code in minifiedCode.js to the original code in the two source files.
XML Script# Source Map Format, –map:xml
Many thanks to Microsoft contributor Rafael Correa for implementing the XML Script# format feature. His description from the check-in notes:
Given a particular position in the output script file, these symbols will be able to tell us its corresponding position on the source file. That would allow us to translate Chrome callstacks back to their original (pre-AjaxMin) format. In fact, for deeply
minified scripts output to single line, Chrome would be the only browser that can leverage this map for callstack translation as it outputs both line and column number for each frame on the stack.
The Script# source map format is XML-based. A typical source map file may look like:
<!—more removed for brevity -->
<checksum value="93-80-C3-F2-41-DE-04-E4-1D-8E-5C-B0-16-7F-50-FD" />
<sourceFile id="1" path="Test.js" />
Each <s> element is a symbol in the minified file and contains a comma-separated list of values indicating the destination (minified) location, the source location, an index into the list of source files used to generate
the output file, the symbol type, and an optional parent function indicator.
AjaxMin MSBuild Task
Source map generation is also supported in the
AjaxMin MSBuild Task via the SourceMapType attribute (type String). To generate a V3 source map, set the property to “V3”; to create an XML Script# source map, set it to “XML”. The source map will be created in the same file as the output file(s), and the
file name will be outputfile.js.map (the exact same name as the output file, but with “.map” appended to the end). Unfortunately, the build task does not allow for the name of the generated source map file to be specified.
If your build requires that kind of control over the output, it is recommended to use the AjaxMin Manifest build task instead.
To generate a Source Map while using the AjaxMin.dll library, a little more work is needed than just setting a couple switches. A source map implementation must be instantiated and assigned to the SymbolsMap property of the CodeSettings object used to minify
the source code. The implementations provided by AjaxMin implement the ISymbolsMap interface, and take a TextWriter as the sole parameter to their constructors. That means your code will be responsible for creating the TextWriter to which the source map will
be written. Be aware that the text encoding should be UTF-8 with no Byte-Order Mark (BOM) written at the beginning. V3 source map files that include a BOM will not be read by Chrome. You an either instantiate one of the two implementation classes
directly (V3SourceMap or ScriptSharpSourceMap), or you can use the Create method on the static SourceMapFactory class. The ISourceMap.StartPackage and ISourceMap.EndPackage methods should be called before and after the minification call.
of the implementation object.