CSS Bundling the jQuery UI Theme

Its common in the projects I work on to have an images folder separate from the less/css folder.  When jQuery UI is used its usually got its own folder as well.  Here’s a sample with a number of things removed for clarity.

JQueryUI Solution Explorer Sample

In development while Bundling is turned off accessing an image in the menu.less file might look something like this. 

#contentContainer {
background: #FFFFFF url(‘../../images/masterPages/menu/contentContainerBackground.jpg’) no-repeat top center;
}

For context here is a sample bundle from our BundleConfig.cs

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles) {

        bundles.Add(new StyleBundle("~/cssBundles/masterPages/root").Include(
                    "~/css/masterPages/reset.css",
                    "~/jQueryUITheme/jquery-ui-theme.css",
                    "~/css/masterPages/root.css"
                    ));
    }
}

So its a happy accident this just works.  It turns out from the bundle path /cssBundles/masterPages if you go back two directories then you hit the root of the site and find the images directory.  The CSS works bundled and in development.  However, throw a jQuery UI theme in the middle of this and things aren’t so pretty.  jQuery by default keeps all its images in a subfolder next to the theme.  There really is no way to move the images around without editing the theme.css and since that file is generated I think its best to leave it alone.  So this left us in a odd spot because we wanted our theme to be bundled in with the rest of our css to keep down on the number of network requests, but we also didn’t want to try to move everything in the project around just to make bundling work.  So here’s our answer, URL Rewrite. As usual extra information removed for clarity.

<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Rewrite jQueryUI Images for Bundling">
                    <match url="cssBundles/masterPages/images/(.*)" />
                    <action type="Rewrite" url="jQueryUITheme/images/{R:1}" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

This catch all rule looks for images the jQuery UI theme thinks should be on the end of our bundle url and redirects them to where we want to keep them in the project.  It’s a little black magic, but its configure once and forget about it.  Now all our bundling works in dev and prod.