4

I am observing a very peculiar behaviour when minifying files with System.Web.Optimization, I am already using IBundleOrderer that works fine in preserving file order when I am not minifying the files

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

public static void RegisterTestingBundle(BundleCollection bundles)
    {
        var bundle = new ScriptBundle("~/OnTheMoveWebFiles/bundles/Testing");
        bundle.Orderer = new RespectGivenBundleOrder();
        bundle.Include(
            string.Format("{0}jquery-{{version}}.js", baseJSFolder),
            string.Format("{0}ua-parser.js", baseJSFolder),
            string.Format("{0}OnTheMove_Core.js", baseJSFolder),
            string.Format("{0}OnTheMove_TheApplication.js", baseJSFolder),
            string.Format("{0}OnTheMove_JQMQueryString.js", baseJSFolder),
            string.Format("{0}OnTheMove_OfflineAuditing.js", baseJSFolder),
            string.Format("{0}OnTheMove_DatabaseManager.js", baseJSFolder),
            string.Format("{0}OnTheMove.js", baseJSFolder),
            string.Format("{0}OnTheMove_Offline.js", baseJSFolder),
            string.Format("{0}OnTheMove_DatabaseLoader.js", baseJSFolder),
            string.Format("{0}OnTheMove_DatabaseTestHelper.js", baseJSFolder),
            string.Format("{0}OnTheMove_SmartScriptPlayer.js", baseJSFolder),
            string.Format("{0}jasmine.js", baseJSFolder),
            string.Format("{0}jasmine-html.js", baseJSFolder),
            string.Format("{0}jasmine-jquery-{{version}}.js", baseJSFolder),
            string.Format("{0}jasmine-OnTheMove-GenericMocksAndHelpers.js", baseJSFolder),
            string.Format("{0}jasmine-OnTheMove-DatabaseManager-SiebelToSQL-Tests.js", baseJSFolder),
            string.Format("{0}jasmine-OnTheMove-TreeValidator-Tests.js", baseJSFolder),
            string.Format("{0}jasmine-OnTheMove-GlobalFunction-Tests.js", baseJSFolder),
            string.Format("{0}jasmine-OnTheMove-OnTheMove_BusinessComponent-Tests.js", baseJSFolder),
            string.Format("{0}jasmine-OnTheMove_DatabaseTestHelper-Tests.js", baseJSFolder),
            string.Format("{0}jasmine-OnTheMove_OfflineAuditing-Tests.js", baseJSFolder),
            string.Format("{0}jasmine-OnTheMove-JQueryExtension-Tests.js", baseJSFolder));
        bundles.Add(bundle);
    }

but when I do turn the minification on I am getting javascript errors and by inspecting the beginning of minified file in chrome developer tools I can immediately see that order is messed up.

In immediate window when I execute var cont = new BundleResolver(BundleTable.Bundles ).GetBundleContents("~/OnTheMoveWebFiles/bundles/Testing") I get

Count = 23
    [0]: "~/OnTheMoveWebFiles/js/jquery-1.7.1.js"
    [1]: "~/OnTheMoveWebFiles/js/ua-parser.js"
    [2]: "~/OnTheMoveWebFiles/js/OnTheMove_Core.js"
    [3]: "~/OnTheMoveWebFiles/js/OnTheMove_TheApplication.js"
    [4]: "~/OnTheMoveWebFiles/js/OnTheMove_JQMQueryString.js"
    [5]: "~/OnTheMoveWebFiles/js/OnTheMove_OfflineAuditing.js"
    [6]: "~/OnTheMoveWebFiles/js/OnTheMove_DatabaseManager.js"
    [7]: "~/OnTheMoveWebFiles/js/OnTheMove.js"
    [8]: "~/OnTheMoveWebFiles/js/OnTheMove_Offline.js"
    [9]: "~/OnTheMoveWebFiles/js/OnTheMove_DatabaseLoader.js"
    [10]: "~/OnTheMoveWebFiles/js/OnTheMove_DatabaseTestHelper.js"
    [11]: "~/OnTheMoveWebFiles/js/OnTheMove_SmartScriptPlayer.js"
    [12]: "~/OnTheMoveWebFiles/js/jasmine.js"
    [13]: "~/OnTheMoveWebFiles/js/jasmine-html.js"
    [14]: "~/OnTheMoveWebFiles/js/jasmine-jquery-1.7.0.js"
    [15]: "~/OnTheMoveWebFiles/js/jasmine-OnTheMove-GenericMocksAndHelpers.js"
    [16]: "~/OnTheMoveWebFiles/js/jasmine-OnTheMove-DatabaseManager-SiebelToSQL-Tests.js"
    [17]: "~/OnTheMoveWebFiles/js/jasmine-OnTheMove-TreeValidator-Tests.js"
    [18]: "~/OnTheMoveWebFiles/js/jasmine-OnTheMove-GlobalFunction-Tests.js"
    [19]: "~/OnTheMoveWebFiles/js/jasmine-OnTheMove-OnTheMove_BusinessComponent-Tests.js"
    [20]: "~/OnTheMoveWebFiles/js/jasmine-OnTheMove_DatabaseTestHelper-Tests.js"
    [21]: "~/OnTheMoveWebFiles/js/jasmine-OnTheMove_OfflineAuditing-Tests.js"
    [22]: "~/OnTheMoveWebFiles/js/jasmine-OnTheMove-JQueryExtension-Tests.js"

which shows that order is being preserved, however when I minify it on the fly (var contents =BundleManager.GetBundleContents("~/OnTheMoveWebFiles/bundles/Testing");) I get

"function TheApplication(){return window.onTheMove.theApplication}function decodeQueryString(n,t,i,r){var f,u={},s,h,e,o;if(i||(i=function(){return}),...

Which is beginning of OnTheMove_TheApplication.js and not jquery-1.7.1.js that I am expecting. One solution I see is to split it apart into more bundles and try to handle it that way.
Why minifier is not preserving order? Is my expectation wrong?

11
  • Just for fun, try an experiment by changing your orderer to return the files alphabetically? Let us know what that does. Commented Aug 21, 2014 at 14:47
  • @Haney when changing the orderer to files.OrderBy(o => o.IncludedVirtualPath); minification result comes out as "function decodeQueryString(n,t,i,r){var f,u={},s,h,e,o;if(i||(i=function(){return}),r&&(u=r),t.length>1&&t[t... which is line 17 of OnTheMove.js and new BundleResolver(BundleTable.Bundles ).GetBundleContents ("~/OnTheMoveWebFiles/bundles/Testing"); starts with [0]: "~/OnTheMoveWebFiles/js/jasmine.js" [1]: "~/OnTheMoveWebFiles/js/jasmine-html.js" and [12]: "~/OnTheMoveWebFiles/js/OnTheMove.js" is 13th item in the list. Commented Aug 21, 2014 at 14:52
  • So it clearly is not respecting your order. How strange. Commented Aug 21, 2014 at 14:56
  • This is odd, but try moving the set of the orderer to AFTER including the scripts? Commented Aug 21, 2014 at 14:57
  • Also try a single Include of basefolder/*.js and see what that does Commented Aug 21, 2014 at 15:00

1 Answer 1

1

I managed solving this issue by creating an extension :

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

internal static class BundleExtensions
{
    public static Bundle ForceOrdered(this Bundle sb)
    {
        sb.Orderer = new AsIsBundleOrderer();
        return sb;
    }
}

Then, you can register your bundle

bundles.Add(new ScriptBundle("~/bundles/home")
            .Include("~/Scripts/leaflet-0.6.4.js")
            .Include("~/Scripts/oms.js")
            .Include("~/Scripts/home.js").ForceOrdered()

        );
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.