Skip to content

Bundling jQuery 2.x and jQuery 1.x in ASP .Net MVC and staying NuGet fresh

Fork in the road
If you use Nuget to install jQuery into your application, you’ll need to take some extra steps to support multiple versions of jQuery.  By default, NuGet will uninstall previous versions of a package.  The way around this is to create another folder inside the scripts folder and put the older jQuery-1.. files in it. I got the idea for doing this from a post on StackOverflow

Right click on the Scripts folder and select Add->New Folder.  Give the folder a name that has some meaning to you, I used “compatibility”.  Select the jquery-1.* files and move them to the new folder.  You can copy them or move them, it doesn’t really matter.

Then install the latest version of jQuery using NuGet.  From the Tools menu, select Library Package Manager->Package Manager Console.  From the package manager window run the following:
Install-Package jQuery

You should see something like this:

Package Manager Console
Package Manager Console

It installed jQuery 2.1 and then it removed the jQuery 1.10 package.  It complained that it couldn’t find the intellisense file for the previous version. That’s because I had moved it to the new folder.

Now it’s time to update the bundles. When you create a new web project, ASP .Net will create some bundles for you. A bundle is a collection of scripts and stylesheets and does a neat little trick where at debug time you get the individual files as if you had specified each one in the web page. At runtime, the files are minified and consolidated into a single file. This compresses the payload and saves on loading time as the browser only needs to make a single request to get the files in the bundle. Any hoo, if you create a ASP .Net project in the current version of VS, you will get this bundle definition in BundleConfig.cs:

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

This call to bundles.Add creates a new bundle named “~/bundles/jquery” and uses the {version} regex placeholder, (\d+(?:.\d+){1,3}), to match the jQuery file without having to specify the version. You don’t have to worry about your code breaking due to an invalid reference to jQuery when NuGet updates jQuery.

What we do now is add a second bundle that will use the older version of jQuery. Since we copied those files to a new folder, NuGet is blissfully unaware of their continued existence and will not remove them. We just create a ScriptBundle with a new name and have it specify the folder that we put the old version of jQuery in.

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

        bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
            "~/Scripts/jquery-{version}.js"));
        // Other code removed...
    }
}

The final step is to update the shared layout view that MVC puts the jQuery script reference in.

With a new project, you will edit the Views\Shared_Layout.cshtml file. The default jquery reference will look like something this:

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

What we need to do is the replace the @Scripts.Render line with a conditional block of code that checks for older versions of Internet Explorer.

    <!--[if lt IE 9]>
    @Scripts.Render("~/bundles/jqueryold")
    <![endif]-->
    <!--[if gte IE 9]><!-->
    @Scripts.Render("~/bundles/jquery")
    <!--<![endif]-->
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

We use IE’s Conditional Comments to detect previous versions of IE. This a feature specific to IE versions 5 through 9. All other browsers will treat the Conditional Comments as regular HTML comments.

<!--[if lt IE 9]>

With this line, IE 5-9 (and 10 in compatibility view) will treat this as the start of a block of code. All other browsers will treat this as the start of a comment block. The block is closed when it hits “–>”.

    <!--[if gte IE 9]><!-->
    @Scripts.Render("~/bundles/jquery")
    <!--<![endif]-->

With this block, we are saying if IE is greater than or equal to version 9, to use this block. The “<!–>” on that line tells IE 10 and the other browsers to close out this comment block which makes that block of code available to the browser. This will allow you to stay current by letting NuGet updating jQuery, while still keeping some level of compatibility with older versions. This is one of the times where IE extending HTML in a proprietary way is useful.

The fork in the road image was modified from an creative commons licensed image posted by Eric Hamiter to his Flickr collection.