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

2 thoughts on “Bundling and Minification with Sitecore

  1. Srinivas says:

    Thanks for the Info, bundling works like a charm. I have a question over here am not able to get the Sitecore Context in the Bundling. I need to get the Language and other things from sitecore in the RegisterBundle method. However the sitecore.context.item is null over there. What is the alternate way?

    • timgriff84 says:

      Sitecore.context.item will be null because the code is being executed directly from IIS rather than going through Sitecore. It’s also only called on site startup rather than on a request so there would be no context item.

      I’d question you reason for wanting to access the context item when creating a bundle though. The idea of a bundle is that it only changes when the files within it change and until that happens your sites visitors will be loading a cached version of the bundle rather than re-downloading from the server.

      It sounds like if you want different file contents for different languages you should be creating multiple bundles and then referencing the correct one in your page based on language.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s