Let’s say you want to use following JS frameworks & libs in your ASP.NET MVC 4 project with enabled minification / bundling support:
jquery-1.7.1.min.js
json2.min.js
modernizr-2.5.3.js
underscore.min.js
backbone.min.js
chosen.jquery.min.js
bootstrap.min.js
...
my.min.js
I specially list names in particular order above, because IT IS important to load some libs in specific order in Web page, e.g.: Chosen jQuery plugin should be loaded AFTER jQuery framework, Backbone.JS framework should be loaded AFTER Underscore.JS (it have hard dependency on it) etc.
However, default order in ASP.NET MVC 4 for loading JS resources might be different from what you want: DefaultBundleOrderer by default load underscore.min.js AFTER backbone.min.js (just because of alphabet ordering) and so on. More so (and it’s a bit separate issue), in the current bootstrap builder exists well know issue with “final semicolons in JS files” (see for example https://github.com/twitter/bootstrap/issues/1758 and https://github.com/twitter/bootstrap/issues/1795 etc.) and so if you use it to get bootstrap.min.js and load something AFTER (in my list above it’s my.min.js file) you will get cool JS exception in browser: “Uncaught TypeError: undefined is not a function”
etc.
And so you may want to load files in following order before bootstrap team fix issue (or sure you can fix it easy yourself), i.e. with bootstrap.min.js going LAST in the sequence:
jquery-1.7.1.min.js
json2.min.js
modernizr-2.5.3.js
underscore.min.js
backbone.min.js
chosen.jquery.min.js
...
my.min.js
...
bootstrap.min.js
So how is it possible to change Bundler order? It turns out that it’s easy enough: just use own Orderer, which do basically nothing:
public class AsIsBundleOrderer : IBundleOrderer
{
public virtual IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
{
if (context == null)
throw new ArgumentNullException("context");
if (files == null)
throw new ArgumentNullException("files");
return files;
}
}
and make sure your Bundle use it instead of DefaultBundleOrderer like this:
protected void Application_Start()
{
...
var bundle = new Bundle("~/Scripts/js", new JsMinify());
bundle.Orderer = new AsIsBundleOrderer();
bundle.AddFile("~/Scripts/jquery-1.7.1.min.js");
bundle.AddFile("~/Scripts/jquery.validate.min.js");
bundle.AddFile("~/Scripts/json2.min.js");
bundle.AddFile("~/Scripts/modernizr-2.5.3.js");
bundle.AddFile("~/Scripts/underscore.min.js");
bundle.AddFile("~/Scripts/backbone.min.js");
bundle.AddFile("~/Scripts/chosen.jquery.min.js");
bundle.AddFile("~/Scripts/my.min.js");
bundle.AddFile("~/Scripts/bootstrap.min.js");
BundleTable.Bundles.Add(bundle);
...
}
Happy end