Using the ASP.NET Web Optimization Framework
, I am attempting to load some javascript files up. It works fine, except I am running into a peculiar situation with either the loading order, the loading speed, or its execution. I cannot figure out which.
Basically, I am using ace
code editor for javascript, and I also want to include its autocompletion package. This requires two files.
/ace.js
/ext-language_tools.js
This isn't an issue, if I load both of these files the normal way (with <script>
tags) it works fine. But when I try to use the web optimization bundles, it seems as if something goes wrong.
Trying this out...
bundles.Add(new ScriptBundle("~/bundles/js") {
.Include("~/js/ace.js")
.Include("~/js/ext-language_tools.js")
});
and then in the view ..
@Scripts.Render("~/bundles/js")
I get the error
ace is not defined
This means that the ace.js
file hasn't run, or hasn't loaded. Because if I break it apart into two bundles, it starts working.
bundles.Add(new ScriptBundle("~/bundles/js") {
.Include("~/js/ace.js")
});
bundles.Add(new ScriptBundle("~/bundles/js/language_tools") {
.Include("~/js/ext-language_tools.js")
});
Can anyone explain why this would behave in this fashion?
This is well explained in MSDN Magazine: Programming CSS: Bundling and Minification (scroll to More Advanced Bundling Features section).
An excerpt (I bolded some text):
In particular, the BundleCollection class has a couple of features that are worth mentioning even though they’re mostly useful when script files—rather than CSS files—are bundled.
The first feature is ordering. The BundleCollection class has a property named Orderer of type IBundleOrderer. As obvious as it may seem, an orderer is a component responsible for determining the actual order in which you want files to be bundled for download. The default orderer is the DefaultBundleOrderer class. This class bundles files in the order that results from the settings set via FileSetOrderList—a property of BundleCollection. The FileSetOrderList is designed to be a collection of BundleFileSetOrdering classes. Each of these classes defines a pattern for files (for example, jquery-*), and the order in which BundleFileSetOrdering classes are added to FileSetOrderList determines the actual order of files. For example, given the default configuration, all jQuery files are always bundled before Modernizr files.
The source for DefaultBundleOrderer class is here.
However, of particular interest is the BundleCollection class' AddDefaultFileOrderings function (screenshot below).
Now, going back to your question, in your bundle you have ace.js
and ext-language_tools.js
. The latter file matches ext-*
and as a result will always be included at the top of the file list in your bundle before ace.js
.
SOLUTION:
This is already answered HERE.
The same solution is also given in the MSDN Magazine (link at the top).
Another method described there is to "reset all orderings using the following code":
bundles.ResetAll();
"In this case, the effect of using the default orderer or the poor man’s orderer shown earlier is the same. Note, though, that ResetAll also resets script orderings."