static void

ASP Bundles

Bundling and minification can reduce the number of http connections (the normal simultaneous limit is 6) and the KBs downloaded (still a problem on mobile, of course). Internally it creates a BundleModule and watches for bundle requests. It includes automatic caching (1 year) with a v querystring based on a hash of the contents.
You can also use it with webforms. Webforms allows bundles to be configured in a bundle.config xml file.

It doesn't really fit with require.js/AMD, which has it's own optimizer (usually Node).


Package is Microsoft.AspNet.Web.Optimization, dll is System.Web.Optimization.
It depends on Microsoft.Web.Infrastructure and WebGrease (WebGrease depends on Antlr)

Creating bundles

In application start (Global.asax):

protected void Application_Start()

In App_Start add a BundleConfig.cs:

//add specific files
    new ScriptBundle("~/bundles/jquery")
        .Include("~/Scripts/jquery-{version}.js" //can be a params list of files
//or entire directory
bundles.Add(new ScriptBundle("~/bundles/scripts")

Look-out for conflicts between the virtual path with physical files (~/Scripts/jQuery.js). The standard is to use ~/bundles/

IncludeDirectory is dangerous. Css files may be import each other, and files are added in alphabetic order. Adding individual files is more explicit and safe.

//if css includes relative paths, fix them up
bundles.Add(new StyleBundle("~/bundle/sitecss")
    .Include("~/Content/nested/site.css", new CssRewriteUrlTransform()));

Pattern rules and advanced use

//when in debug, use the log form. In release/optimized use the non-log form.
bundles.FileExtensionReplacementList.Add("log", OptimizationMode.WhenDisabled);

Ordering is controlled by the BundleCollection.FileSetOrderList

//mu.js will be moved to the front of the list
var ordering = new BundleFileSetOrdering("mu");
BundleTable.Bundles.FileSetOrderList.Insert(0, ordering);
//the default orderlist has jquery first (and moo, prototype, ext)
//for css reset.css then normalize.css are first

You can ignore files. There is an empty BundleCollection.IgnoreList and, for use with IncludeDirectory only, a BundleCollection.DirectoryFilter which deals with *-min.js etc. NB: FileExtensionReplacementList does the standard min/debug switching.

//ignore unit test files
//IncludeDirectory - ignore logging only in release, but include it in DEBUG
BundleTable.Bundles.DirectoryFilter.Ignore("*logging.js", OptimizationMode.WhenEnabled);
//default ignores in debug and release: *.intellisense, *.vsdoc
//default ignores when debug or optimized: *.min, *.map, *.debug


In debug mode (system.web/compilation[@debug=true] ) it is OFF. The files in a bundle are sent individually, un-minimized.
Override it with BundleTable.EnableOptimizations = true.

Razor views

Use @Scripts.Render or @Styles.Render, or @Scripts.Url



For public websites, you'll probably want a jquery CDN:

BundleTable.EnableOptimizations = true; //rqd for cdn
bundles.UseCdn = true; //must set this!!!
var bundle = new ScriptBundle("~/bundles/jquery",
    //this is the debug file (not the backup!)
//is this global variable truthy?
bundle.CdnFallbackExpression = "window.jQuery";

In the html, the Scripts.Render adds this:

<script>(window.jQuery)||document.write('<script src="/bundles/jquery"><\/script>');</script>


There are 3rd party nuget packages for Less, Sass and CoffeeScript (eg BundleTransformers.*). Alternatively just use the Visual Studio Web Essentials extension.

You could use bundles to output server localized resources to javascript. IBundleTransform and implement Process (BundleResponse.Content is the concatenated file content). If you create a new Bundle (instead of ScriptBundle), a ctor overload allows you to add transforms, so you can add JsMinify() Transform (i.e. minimization) as well as a custom transform.