Bundling and Minification with Sitecore

There’s various ways to add bundling and minification to a site, but one of the easiest is to use Microsoft’s support from the Microsoft.AspNet.Web.Optimization package. This implementation has some great features including:

  • Automatically create the bundles and minify them as files are changed
  • Create unique urls to each version of a bundle to force browser refreshing of the file
  • Debug mode which outputs links to the raw files rather than the bundled minified version

The functionality is also fully compatible with Sitecore. To use it in your Sitecore solution follow these steps:

1. Add Microsoft.AspNet.Web.Optimization to your project from NuGet. This is the package from Microsoft that contains the functionality to do bundling and minification

MicrosoftAspNetWebOptimization-NuGet

2. Create your CSS and Javascript bundles. Where you put the logic for this is up to you but it will need to run when the application starts. Outside of Sitecore my main development is on bespoke ASP.NET MVC and Web API projects so I like to organise startup scripts into an App_Start folder and reference it from the Application_Start event in the global ascx file.

If you are running a Sitecore instance with multiple sites or if you do not have direct access to the production config files, it may be better to keep the logic separate and use a pipeline to create the bundles.

My bundle definitions would look something like this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Optimization;

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new ScriptBundle("~/bundles/scripts").Include(
                    "~/Scripts/jquery-{version}.js",
                    "~/Scripts/bootstrap.js"));

        bundles.Add(new StyleBundle("~/bundles/css").Include(
            "~/Content/bootstrap.css",
            "~/css/site.css"));
    }
}

And in my Global.asax.cs file I would have some logic like this to call the other function

protected void Application_Start(object sender, EventArgs e)
{
    BundleConfig.RegisterBundles(System.Web.Optimization.BundleTable.Bundles);
}

3. Replace your Javascript/CSS references in your layout or rendering files with a call to render the bundle

Webforms

    <%: System.Web.Optimization.Scripts.Render("~/bundles/scripts") %>
    <%: System.Web.Optimization.Styles.Render("~/bundles/css") %>

MVC

@Scripts.Render("~/bundles/scripts")
@Styles.Render("~/bundles/css")

4. In your web.config file there are a couple of changes needed to get things to work.

First you need to set an ignore url prefix to stop Sitecore trying to resolve the URL to the bundle. In this example mine is called bundles (note: you should add the prefix the what is already in your config file. e.g. |/bundles)

<!--  IGNORE URLS
      Set IgnoreUrlPrefixes to a '|' separated list of url prefixes that should not be
      regarded and processed as friendly urls (ie. forms etc.)
-->
<setting name="IgnoreUrlPrefixes" value="/sitecore/default.aspx|/trace.axd|/webresource.axd|/sitecore/shell/Controls/Rich Text Editor/Telerik.Web.UI.DialogHandler.aspx|/sitecore/shell/applications/content manager/telerik.web.ui.dialoghandler.aspx|/sitecore/shell/Controls/Rich Text Editor/Telerik.Web.UI.SpellCheckHandler.axd|/Telerik.Web.UI.WebResource.axd|/sitecore/admin/upgrade/|/layouts/testing|/bundles" />

Next a dependant assembly binding needs to be set up for Web Grease. Without it you will see an error about the Web Grease version number

<dependentAssembly>
  <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
  <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>

If you have done this and are still getting a version number error check the assembly binding tag. Older versions of Sitecore have the applies to property set which may be only applying the bindings to .Net 2 and you may be using .Net 4.

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" appliesTo="v2.0.50727">

5. If you are using IIS7 you will also need to make a change in your web.config file

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
    </modules>
</system.webServer>

6. Publish your changes into your Sitecore site. Depending if you have compilation mode set to debug or not you will now either have a bundle reference for all your JavaScript and CSS or the individual file references.

Advertisements