ASP.NET MVC - Bundle Config order

I'm trying to use a specific locale (es-CL) in my ASP.NET MVC 5 application. I've the following:

  1. Changed web.config uiculture and culture to "es-CL"
  2. Installed the Globalize and jQuery.Validation.Globalize packages
  3. Changed the default language in my views: <html lang="es-cl">
  4. Created a new Bundle and included in the appropriate views.

In BundleConfig.cs:

bundles.Add(new ScriptBundle("~/bundles/jqueryval")
    .Include("~/Scripts/jquery.validate.js")
    .Include("~/Scripts/jquery.validate.unobtrusive.js"));

bundles.Add(new ScriptBundle("~/bundles/globalization")
    .Include("~/Scripts/globalize/globalize.js")
    .Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
    .Include("~/Scripts/jquery.validate.globalize.js"));

In the appropriate views:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/globalization")
}

However, the generated source code is the following:

<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>

<script src="/Scripts/jquery.validate.globalize.js"></script>
<script src="/Scripts/globalize/globalize.js"></script>
<script src="/Scripts/globalize/cultures/globalize.culture.es-CL.js"></script>

Please note that the jquery.validate.globalize.js script is being loaded before globalize.js, which is not what I want.

Why is this happening? Is it possible to rely in the include order in a single bundle, or am I forced to put this single script in a different bundle and specify it in my view?

By default, bundling order is alphabetical for names with wildcards (as pointed out in the comments). However, it also orders based on what it thinks your dependency tree is, and jQuery scripts seem to get slotted to the top. You need to create an object that implement IBundleOrder:

class NonOrderingBundleOrderer : IBundleOrderer
{
    public IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
    {
        return files;
    }
}

This prevents the default ordering. Now to use it:

var bundle = new ScriptBundle("~/bundles/globalization")
    .Include("~/Scripts/globalize/globalize.js")
    .Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
    .Include("~/Scripts/jquery.validate.globalize.js");

bundle.Orderer = new NonOrderingBundleOrderer();

bundles.Add(bundle);

ref: http://stevescodingblog.co.uk/changing-the-ordering-for-single-bundles-in-asp-net-4/

For further reading, an answer to MikeSmithDev's question provides further insight into the default ordering for popular script libraries:

Ordering of Files within a bundle - What are the known libraries?

ASP.NET MVC - Bundle Config order. Ask Question Asked 6 years, 1 month ago. Active 8 months ago. Viewed 43k times 78. 22. I'm trying to use a specific locale (es-CL

In the last version of MVC 5 (at october 27 of 2014), yo should use this class instead:

class AsIsBundleOrderer : IBundleOrderer
{
    public IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
    {
        return files;
    }
}

And create the bundle like the other response:

var bundle = new ScriptBundle("~/bundles/globalization")
.Include("~/Scripts/globalize/globalize.js")
.Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
.Include("~/Scripts/jquery.validate.globalize.js");

bundle.Orderer = new AsIsBundleOrderer();

bundles.Add(bundle);

For ASP.NET MVC 4, this means with a debug configuration, the file jquery-1.7.1.js will be added to the bundle. In a release configuration, jquery-1.7.1.min.js will be added. The bundling framework follows several common conventions such as: Selecting ".min" file for release when FileX.min.js and FileX.js exist. Selecting the non ".min" version

To reduce the codes during creating bundles, I suggest you create an extension method.

Require infrastructure classes:

class NonOrderingBundleOrderer : IBundleOrderer
{
    public IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
    {
        return files;
    }
}


static class BundleExtentions
{
    public static Bundle NonOrdering(this Bundle bundle)
    {
        bundle.Orderer=new NonOrderingBundleOrderer();
        return bundle;
    }
}

Now simply use it like this:

All in one command 😎

bundles.Add(new ScriptBundle("~/bundles/jqueryval")
               .NonOrdering()
               .Include(
                    "~/Scripts/globalize/globalize.js",
                    "~/Scripts/globalize/cultures/globalize.culture.es-CL.js",
                    //...
                );

javascript asp.net asp.net-mvc 3 0 Leonardo Herrera 2020-06-10 12:04:49 +0000 UTC 3 Answers By default, bundling order is alphabetical for names with wildcards (as pointed out in the comments).

Bundling and minification has been available in ASP.NET MVC for a long time. This blog post focuses on problems people have had with bundling and provides working solutions for those who cannot use bundling in ASP.NET MVC for different reasons. Also some ideas about more effective bundling are presented here.

In ASP.NET Core 2.0 or earlier, the MVC and Razor Pages project templates provide a bundleconfig.json configuration file that defines the options for each bundle: In ASP.NET Core 2.1 or later, add a new JSON file, named bundleconfig.json , to the MVC or Razor Pages project root.

ASP.NET MVC - Bundle Config order. 15. Force ASP.Net MVC Bundle to render the javascript files in a certain order. 21. Make a script bundle include another script

Comments
  • Have a look at this question stackoverflow.com/questions/11979718/…
  • @PaulMcCowat yes, but I'm not using the minified versions yet. I'm using Microsoft.AspNet.Web.Optimizations 1.1.0.
  • @LeonardoHerrera I would think it is like Chris mentioned in his comments, that known files are moved around to an order specified by the bundler... but I can't be sure since I don't know what those files are, which led me to ask. I'll be interested to know if using the IBundleOrderer works for you since specifying the order didn't.
  • look at @Softlion answer in [this link][1] [1]: stackoverflow.com/questions/11979718/…
  • @section Scripts { @Scripts.Render("~/bundles/jqueryval") } appears to have resolved the issue of my scripts loading out of order....
  • Not to nitpick, but "by default, bundling order is alphabetical" is true when you use things like wild cards... when you specify the order, like he has, it should use his order. I can only assume the bundler is moving around known file types and is ignoring his order.
  • It looks like the bundler also orders using some logic about dependencies. It thinks that jquery.validate.globalize.js is required for the other two. From the ref: "[The bundler] will even put known framework javascript files first in the bundle automatically, such as jQuery or Prototype scripts, to make sure they run before your own code which uses their types gets executed"
  • The spesific order is: jquery.js jquery-min.js jquery-* jquery-ui* jquery.ui* jquery.unobtrusive* jquery.validate* modernizr-* dojo.* mootools-core* mootools-* prototype.js prototype-* scriptaculous-* ext.js ext-*
  • here is where programming is not fun. why VS make this complicated?
  • The fact that this exists blows my mind with how stupid it is. Really.. the bundler knows better how to order my dependencies better than I've typed them? Gulp.js (or even Grunt) FTW!
  • Where can I find this info? Can you provide a link please?
  • I just try to use the method of the current response for this question but I found my selkf with an error in ASP.NET MVC 5, so I check the IBundleOrderer interface and made the changes
  • There is no Orderer Property. I am using MVC 5.2.x
  • I just test it with MVC 5.2.3 and tehres is the Orderer Property.
  • Nice way of thinking!