OdeToCode IC Logo

Yet Another Bundling Approach for MVC 4

Wednesday, March 21, 2012

ASP.NET MVC 4 allows you to bundle multiple JavaScript or CSS files into a single "bundled" download, and optionally minify the bundle to reduce the download size. John Petersen has a good introduction to the feature.

I've been experimenting with an approach that lets me use the following code during application startup.

BundleTable.Bundles.Add(new RGraphBundle());

The RGraphBundle class lists all the JavaScript files needed for a certain feature, and sets the virtual path to reach the bundle.

public class RGraphBundle : JsBundle
{
    public RGraphBundle() : base("~/Rgraph")
    {
        AddFiles(
            "~/Scripts/Rgraph/RGraph.common.core.js",
            "~/Scripts/Rgraph/RGraph.common.context.js",
            "~/Scripts/Rgraph/RGraph.common.zoom.js",
            "~/Scripts/Rgraph/RGraph.common.effects.js",
            "~/Scripts/Rgraph/RGraph.line.js"
        );
    }
}

Everything else is taken care of by base classes.

public class CustomBundle : Bundle
{
    public CustomBundle(string virtualPath) 
        : base(virtualPath)
    {
        
    }

    public void AddFiles(params string[] files)
    {
        foreach (var file in files)
        {
            AddFile(file);
        }            
    }

    public void SetTransform<T>() where T: IBundleTransform
    {
        if(HttpContext.Current.IsDebuggingEnabled)
        {
            Transform = new NoTransform();
        }
        else
        {
            Transform = Activator.CreateInstance<T>();
        }
    }        
}    

public class JsBundle : CustomBundle
{
    public JsBundle(string virtualPath) : base(virtualPath)
    {                        
        SetTransform<JsMinify>();
    }        
}

public class CssBundle : CustomBundle
{
    public CssBundle(string virtualPath) : base(virtualPath)
    {            
        SetTransform<CssMinify>();
    }
}

Checking the IsDebuggingEnabled flag lets me turn minification on and off by toggling the debug setting in web.config, just like the ScriptManager would do in that other ASP.NET web framework.