AjaxMin.DLL

The Microsoft Ajax Minifier also provides a DLL that can be used in your own applications. Classes are defined in the Microsoft.Ajax.Utilities namespace. There are two main ways to access the functionality.

 

Minifier Class

Instantiate the Minifier class and call either the MinifyJavaScript or MinifyStyleSheet methods, passing in the source to be minified as a string value. The return value from both those functions is the minified code as a string value. If there were any errors or warnings minifying your code, they will be in the ErrorList property, which is an ICollection<ContextError>. This is the simplest way to minify your sources using the DLL.

using System;
using System.IO;
using Microsoft.Ajax.Utilities;
namespace AjaxMinSample
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 1)
            {
                string source;
                using (var inputFile = new StreamReader(args[0]))
                {
                    source = inputFile.ReadToEnd();
                }
                var minifier = new Minifier();
                Console.WriteLine(minifier.MinifyJavaScript(source));
                foreach (var error in minifier.ErrorList)
                {
                    Console.Error.WriteLine(error.ToString());
                }
            }
        }
    }
}

 

CssSettings

The MinifyStylesheet method can optionally take a CssSettings object to specify various CSS minification settings. There are two ways to generate one: manually, by creating a default CssSettings object and then setting all properties you wish to change from the default settings, or by creating an instance of the SwitchParser object, parsing a command-line switch by calling the Parse method on that object, and then passing the generated CssSettings property as the second parameter to the MinifyStylesheet method.

var switchParser = new SwitchParser();
switchParser.Parse("-css:decls -colors:hex");
var minifier = new Minifier();
var minifiedStyle = minifier.MinifyStyleSheet(styleAttrValue, switchParser.CssSettings);

 

CodeSettings

The MinifyJavaScript method can optionally take a CodeSettings object to specify various JavaScript minification settings.  The JSParser object’s Parse method must be passed a CodeSettings object. There are two ways to generate one: manually, by creating a default CodeSettings object and then setting all properties you wish to change from the default settings, or by creating an instance of the  SwitchParser object, parsing a command-line switch by calling the Parse method on the object, and then passing the generated JSSettings property as the second parameter to the MinifyJavaScript method, or as the only parameter to the Parse method on the JSParser object.

 

JSParser Classes

If you wish to take advantage of the JavaScript parser and examine and/or manipulate the resulting abstract syntax tree (AST), you can instantiate an object of the type JSParser, and utilize its methods and properties directly. The main advantage here is that the parser returns an object of type Block that represents the top-level set of statements for the input script. It is then possible to traverse the tree, delete nodes, add nodes, move them around, rename variables – anything is possible once you have the AST. And once you are done, simply call the ToCode method on the Block object returned from the parser to get the resulting JavaScript code.

Up to and including Version 4.x of AjaxMin, the JSParse object is created passing in the source code to parse. The Parse method takes the CodeSettings object:

using System;
using System.IO;
using Microsoft.Ajax.Utilities;
namespace AjaxMinSample
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 1)
            {
                string source;
                using (var inputFile = new StreamReader(args[0]))
                {
                    source = inputFile.ReadToEnd();
                }
                JSParser parser = new JSParser(source);
                parser.CompilerError += ErrorHandler;
                CodeSettings settings = new CodeSettings();
                Block block = parser.Parse(settings);
                Console.WriteLine(block.ToCode());
            }
        }
        static void ErrorHandler(object source, JScriptExceptionEventArgs ea)
        {
            Console.Error.WriteLine(ea.Error.ToString());
        }
    }
}

Versions 5.x going forward, the JSParse constructor takes no parameters (line 15). The Parse method takes the source to parse and an optional CodeSettings object (line 35). This is to allow for multiple parse operations on multiple pieces of source code to work with the same global namespace. Also, the ToCode method is no longer supported on AstNodes directly. Please use the OutputVisitor to generate valid JavaScript code from a node. You can either call it with a TextWriter stream (shown below, line 38), or don’t pass a stream and it will instead return a string object representing the generated code.

   1:  using System;
   2:  using System.IO;
   3:   
   4:  using Microsoft.Ajax.Utilities;
   5:   
   6:  namespace AjaxMinSample
   7:  {
   8:      class Program
   9:      {
  10:          static void Main(string[] args)
  11:          {
  12:              if (args.Length > 0)
  13:              {
  14:                  // set up a single JSParser object with a simple error handler.
  15:                  var parser = new JSParser();
  16:                  parser.CompilerError += (sender, ea) =>
  17:                      {
  18:                          Console.Error.WriteLine(ea.Error.ToString());
  19:                      };
  20:   
  21:                  // default settings.
  22:                  var codeSettings = new CodeSettings();
  23:   
  24:                  // each argument should be a path to a JS input file.
  25:                  foreach (var path in args)
  26:                  {
  27:                      // read the input file.
  28:                      string source;
  29:                      using (var inputFile = new StreamReader(path))
  30:                      {
  31:                          source = inputFile.ReadToEnd();
  32:                      }
  33:   
  34:                      // parse the source code to an AST tree
  35:                      var block = parser.Parse(source, codeSettings);
  36:   
  37:                      // output the tree to the Console Out stream
  38:                      OutputVisitor.Apply(Console.Out, block, codeSettings);
  39:                  }
  40:              }
  41:          }
  42:      }
  43:  }

AST Traversal

If you would like to traverse the entire tree from root to leaf, you could start with the Block object and simply iterate over all the nodes in the Children collection recursively:

        static void IterateChildren(AstNode node)
        {
            foreach (var child in node.Children)
            {
                IterateChildren(child);
            }
        }

Or you can use a Visitor pattern. Define a new class derived from the Microsoft.Ajax.Utilities.TreeVisitor class. There are a number of virtual methods on TreeVisitor – one for each concrete AST node type – that can be overridden. The base TreeVisitor class methods simply iterates over the node’s children nodes. For example, if the desire it to iterate over all the nodes in the tree and print out the name of all variables defined in var statements, a visitor can be define like this:

    class MyVisitor : TreeVisitor
    {
        public MyVisitor() { }
        public override void Visit(VariableDeclaration node)
        {
            base.Visit(node);
            Console.WriteLine(node.Identifier);
        }
    }

To execute the visitor, instantiate an object and pass the Block node to the Visit method:

        var myVisitor = new MyVisitor();
        myVisitor.Visit(block);

Nodes in the AST tree can be created, inserted, replaced, deleted, and modified. Internally Ajax Minifier uses a number of visitor classes to modify the tree for maximum minification.

Unfortunately, currently only JavaScript is parsed into an AST that can be traversed. The CSS syntax tree is not available at this time.

Last edited Sep 16, 2013 at 4:57 PM by ronlo, version 18

Comments

No comments yet.