Monday, January 3, 2011

Using the AJAX minifier as an MSBuild task to compress JavaScript

It is possible to us the AJAX Minifier to generate compact Ecmascript (JavaScript) and CSS files.

Add the following to your .csproj file within the Project tag. This page gives more detail.

<Target Name="AfterBuild">
    <JS Include="**\*.original.js" />
    <CSS Include="**\*.original.css" />
  <AjaxMin JsSourceFiles="@(JS)" JsSourceExtensionPattern="\.original.js$" JsTargetExtension=".js" 
            CssSourceFiles="@(CSS)" CssSourceExtensionPattern="\.original.css$" CssTargetExtension=".css"
            JsOutputMode="MultipleLines" JsCombineDuplicateLiterals="true"/>

The documentation is good except that it does not detail all the options for the MSBuild task. I list them for version 4.0 below, with descriptions copied from various places including the source code and documentation:

JsCollapseToLiteralCollapse new Array() to [] and new Object() to {}.true
JsCombineDuplicateLiteralsCombine duplicate literals within function scopes to local variables.false
JsEnsureFinalSemicolonAppends a semi-colon to the end of the minified JavaScript.true
JsEvalTreatmentNormally an eval statement can contain anything, including references to local variables and functions. If it is expected to do so, when the tool encounters an eval statement, that scope and all parent scopes cannot take advantage of local variable and function renaming because things could break when the eval is evaluated and the references are looked up. To reduce the amount of resulting minification but make sure that all possible references in evaluated code will hold true, use the MakeAllSafe value. However, sometimes the developer knows that he’s not referencing local variables in his eval (like when only evaluating JSON objects), and this switch can be set to Ignore to make sure you get the maximum reduction in resulting code size. Or alternatively, if the developer knows the code being evaluated will only access local variables and functions in the current scope and nowhere else, the MakeImmediateSafe value can be specified and all parent scopes will still rename their locals. Very dangerous setting; should only be used when you are certain of all possible behavior of evaluated code. Ignore
JsIndentSizeFor the multi-line output feature, how many spaces to use when indenting a block (see OutputMode).4
JsInlineSafeStringsBreak up string literals containing </script> so inline code won't break.true
JsLocalRenamingRenaming of locals. There are a couple settings: KeepAll is the default and doesn’t rename variables or functions at all. CrunchAll renames everything it can. In between there is KeepLocalizationVars, which renames everything it can except for variables starting with L_. Those are left as-is so localization efforts can continue on the minified code.CrunchAll
JsMacSafariQuirksThere are two quirks that Safari on the Mac (not the PC) needed: throw statements always seem to require a terminating semicolon; and if statements that only contains a single function declaration need to surround that function declaration with curly-braces. Basically, if you want your code to always work in Safari, set this to true. If you don’t care about Safari (for instance, in a corporate environment where the browser your users can use is highly restricted), setting this value to false might save a few bytes.true
JsOutputModeSingleLine minifies everything to a single line. MultipleLines breaks the minified code into multiple lines for easier reading (won’t drive you insane trying to debug a single line). The only difference between the two outputs is whitespace. (see also: IndentSize).SingleLine
JsRemoveUnneededCodeShould be set to true for maximum minification. Removes unreferenced local functions (not global functions, though), unreferenced function parameters, quotes around object literal field names that won’t be confused with reserved words, and it does some interesting things with switch statements. For instance, if the default case is empty (just a break), it removes it altogether. If there is no default case, it also removes other empty case statements. It also removes break statements after return statements (unreachable code). true
JsStripDebugStatementsremoves “debugger” statements, any calls into certain namespaces like $Debug, Debug, Web.Debug or Msn.Debug. also strips calls to the WAssert function.true

1 comment:

  1. The documentation is hardly good... Thank you for this.