Bundle is loaded in the wrong order - javascript

In my _Layout view I'm including the following scriptbundle:
bundles.Add(new ScriptBundle("~/bundles/js").Include(
"~/Scripts/jquery.min.js",
"~/Scripts/jquery-ui.min.js",
"~/Scripts/bootstrap.min.js",
"~/Scripts/jquery.flot.categories.js",
"~/Scripts/jquery.flot.js",
"~/Scripts/jquery.flot.min.js",
"~/Scripts/jquery.flot.orderBars.js",
"~/Scripts/jquery.flot.pie.js",
"~/Scripts/jquery.flot.resize.js",
"~/Scripts/graphtable.js",
"~/Scripts/fullcalendar.min.js",
"~/Scripts/chosen.jquery.min.js",
"~/Scripts/autoresize.jquery.min.js",
"~/Scripts/jquery.autotab.js",
"~/Scripts/jquery.jgrowl_minimized.js",
"~/Scripts/jquery.dataTables.min.js",
"~/Scripts/jquery.stepy.min.js",
"~/Scripts/jquery.validate.min.js",
"~/Scripts/jquery.cookie.js",
"~/Scripts/raphael.2.1.0.min.js",
"~/Scripts/justgage.1.0.1.min.js",
"~/Scripts/glisse.js",
"~/Scripts/styleswitcher.js",
"~/Scripts/moderniz.js",
"~/Scripts/jquery.sparkline.min.js",
"~/Scripts/slidernav-min.js",
"~/Scripts/jquery.fancybox.js",
"~/Scripts/main.js",
"~/Scripts/application.js",
"~/Scripts/excanvas.min.js",
"~/Scripts/float.settings.infobox.js"
));
The thing is; when I load the page and look at the network traffic I see that jquery-ui.min.js is loaded first (before jquery.min.js)!
Here is the order in which they load in:
I thought the scripts would load in the order I specified them in. Am I wrong? And if so, how should I load them in the proper order?
EDIT:
I tried adding a custom sort as described here:
http://stevescodingblog.co.uk/changing-the-ordering-for-single-bundles-in-asp-net-4/
However I get the following error when building the project:
Error 1 'Namespace.AsIsBundleOrderer' does not implement interface member 'System.Web.Optimization.IBundleOrderer.OrderFiles(System.Web.Optimization.BundleContext, System.Collections.Generic.IEnumerable)'

Some things that can cause this problem:
Buggy version of ASP.NET Web Optimization Framework. Update to 1.1.3 or later.
Explicit names are always processed before symbolic names.
Explicitly named dependent of symbolically named libraries
Knockout-jqueryui.js doesn't have a version in its name. It depends on jQuery and jQuery UI. Both of these have versions in their names. If you use symbolic names like jQuery-{version} to refer to these libraries, because knockout-jqueryui is named explicitly, it will be loaded in the first pass - before its dependencies.
Either name the versions explicitly or fudge a version number into the dependent library name and make them all symbolic.

Related

How to reduce JavaScript Files in Magento?

I am new to Magento but work in webdev for several years now.
My goal is to optimise an existing Magento installation in terms of speed.
Looking at all the JS and CSS files used within this installation the first thing I aim for is to combine those file or better reduce the number of modules used. I am aware of the "combine files" function within the config menu, but that does lead to conflicts between jQuery and prototype which is why I am trying to first get an understanding of what types of frameworks/modules etc are used.
This is a list of all JS-files required by the homepage of this installation:
jquery-1.12.3.min.js
prototype.js
ccard.js
validation.js
builder.js
effects.js
dragdrop.js
controls.js
slider.js
js.js
form.js
script.js
menu.js
translate.js
cookies.js
func.js
jquery.easing.1.3.min.js
efects.js
jquery-1.11.0.min.js
jquery-migrate-1.2.1.min.js
jquery.noconflict.js
swiper.min.js
jquery.easing.js
jquery.scrollTo.min.js
jquery.global.js
remodal.min.js
jquery.themepunch.tools.min.js
jquery.themepunch.revolution.min.js
easyzoom.js
ios-orientationchange-fix.js
jquery.swipebox.min.js
jquery.themepunch.plugins.min.js
jquery.themepunch.revolution.js
jquery.slider.js
jquery.selectbox.js
jquery.bxslider.min.js
jquery.tweet.js
cookieconsent.min.js
gtm.js?id=GTM-5W7V6F
analytics.js
ec.js
What would be the best approach to clean up this list in order to keep functionality while reducing request and load?
For starters i see that you load 2 versions of jQuery
jquery-1.12.3.min.js and jquery.easing.1.3.min.js
What i did was combine the javascript files with the config settings like you said and use the jQuery.noConflict() https://api.jquery.com/jquery.noconflict/. Don't use the $ (dollar) sign to use jQuery but write it fully because prototype also uses it and it creates problems sometimes. There will be some problems which you should try to fix. Sometimes it's just adding a ; to the end of the file or function.
I then tried to figure out what code was needed and what wasn't so i could remove some of it.
Magento Inbuilt provide this things
Login admin panel
goto System->configuration->Advanced->Developer->JavaScript Settings and set Merge JavaScript Files to yes
You can do same for css and you will see very few request in your web page

Managing resources in a sitelet

I'm beginning my trek in learning WebSharper, and I'm finding managing resources (e.g. css and javascript files) a bit confusing.
The documentation on this gives an example resource declaration
type MyResource() =
inherit Resources.BaseResource("http://my.cdn.net",
"file1.js", "file2.js", "file3.css")
and you can place a [<Require>] attribute on the assembly to make the resource appear on every page on the site:
[<assembly: Require(typeof<MyResource>)>]
do ()
The documentation goes on to say that the attribute can be placed on modules, types and (module level) let bindings and WebSharper will build a dependency graph to figure out if a given page (Action) needs the dependency or not. I've tried a few things (using a Twitter Bootstrap resource declaration), but the only way I've gotten to make this work is the assembly attribute.
Can someone give an example (or provide a link) of how to do properly use the [<Require>] attribute so that it gets added on one Action, but not another?
For reference, here's by Twitter Bootstrap resource declaration:
[<Require(typeof<JQuery.Resources.JQuery>)>]
[<Sealed>]
type BootstrapResource() =
inherit Resources.BaseResource("https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/",
"css/bootstrap.min.css", "js/bootstrap.min.js")
(I get that the [<Require]> attribute here here makes it a dependency of the Bootstrap resource, although I think WebSharper includes JQuery anyways, which would make it redundant.)
Having [<Require(typeof<JQuery.Resources.JQuery>)>] is not redundant as it tells WebSharper to always include JQuery before the currently defined resource.
Require attribute on assembly level in a referenced dll will not automatically add the resource to the page returned for a specific Action, only if the assembly referenced from one of the Web.Control types used for the page. It works the same for a smaller scope: [<Require(typeof<MyResource>)>] on a module, function, or type.

How do you use a page's existing jQuery + Twitter Bootstrap/plugins with StealJS?

I have a project that uses Twitter Bootstrap 3, however, I am supplementing the existing javascript situation with a CanJS app. For CanJS dependency management I chose their package StealJS. However, it appears that no matter what I do, StealJS insists on loading jQuery again, overwriting $.fn, of course.
In this question a core contributor answers that the solution is to "steal" a blank.js file. However, this breaks steal/build for production as can/util/jquery/jquery.js is passed 'jquery' as undefined (the results of blank.js).
I have tried variations on StealJS's stealconfig.js settings including map, paths, and completed but nothing seems to work.
Here is an example of doing this in RequireJS. Is the solution simply not to use StealJS and to use RequireJS instead?
You can try a solution that is similar to the RequieJS solution you linked to. That is, create a dummy file that looks like this:
steal(function(){
return window.jQuery;
});
And in stealconfig.js map jquery to wherever you put this file.

How to use javascript in Silverstripe CMS?

I'm using SilverStripe 3.0 CMS, and I need to include a Google Map into the CMS.
I'm following this steps, and besides it's a little bit old, the official documentation uses the same methods in the current version of SilverStripe (At least it seems to be the current version documentation).
The issue is in this part of the code:
Behaviour.register({
"#Form_EditForm" : {
initialize : function() {
this.observeMethod("PageLoaded", this.adminPageHandler);
this.adminPageHandler();
},
adminPageHandler : function() {
initialize();
}
}
});
First of all, Behaviour was not defined. I needed to include manually the behaviour.js file that comes within the framework. But now, I get a Type Error:
this.observeMethod is not a function
Can someone give me a hint of what can I do in order to call a javascript function when a page editor is opened in the SilverStripe CMS?
the 'Behaviour.register' call you mention is definitly deprecated and no longer available in the core code, so the docs need an update here.
unfortunately, i couldn't find a documented way to replace this behaviour, but for now the following should work for you, based on the approach in the forum post you mentioned first hand:
find the 'initGoogleMaps.js' script added here:
function getCMSFields() {
Requirements::javascript('mysite/javascript/initGoogleMaps.js');
...
inside this script, remove the Behaviour.register... block, and move the initialize function outside document.ready (or simply remove the document.ready part), so initialize is globally available (you might consider renaming it).
then, add the following inside getCMSFields:
$fields->addFieldToTab('Root.Content', new LiteralField('js', '<script>initialize();</script>'));
this will ensure the initialize function is called every time a page's 'edit view' is rendered inside the cms.
hth
As mentioned by ben,
LeftAndMain::require_javascript('mysite/javascript/initGoogleMaps.js')
is more reliable than 'include-it when needed'. Why?
Because Silverstripe uses Ajax, it is better to load any javascript or css on the first load, so that they are ready when you go to different model admin areas within the CMS in ajax-powered environment. Not loading at the start causes inconsistency and your js, css files will not be loaded when you don't hard-load that admin area.
From documentation: http://doc.silverstripe.org/framework/en/reference/requirements and http://api.silverstripe.org/3.0/class-LeftAndMain.html
The whole "include it when you need it" thing shows some weaknesses in
areas such as the CMS, where Ajax is used to load in large pieces of
the application, which potentially require more CSS and JavaScript to
be included. At this stage, the only workaround is to ensure that
everything you might need is included on the first page-load.
One idea is to mention the CSS and JavaScript which should be included
in the header of the Ajax response, so that the client can load up
those scripts and stylesheets upon completion of the Ajax request.
This could be coded quite cleanly, but for best results we'd want to
extend prototype.js with our own changes to their Ajax system, so that
every script had consistent support for this.
By the way, the ideal place for this line is _config.php in your custom module or in mysite, depending on your needs.
LeftAndMain::require_javascript('mysite/javascript/initGoogleMaps.js')
would work much better

Injecting JQuery Cross-Domain

Is it safe to inject JQuery's script using JsonP?
The installation of my web application is - adding a script to a customer's website (like google analytics). I was thinking of using JQuery on the customer's website, as part of my own injected script.
I was wondering, if there is some kind of risk?
The application needs to support any kind of website.
Thank you
Yaron
Its hard to tell what you are doing with your library, but it seems you are building some type of widget for use on multiple sites.
From here down has been updated after an enlightening comment from #K Prime caused me research exactly how you could include two copies of jQuery if needed:
It is generally bad to use jQuery if you are building a widget that will live on a site outside your control, and will be added to the site with a "copy this embed code and paste onto your site" type of functionality. (Of course jQuery widgets and plugins abound, but these are normally chosen and installed/implemented by developers not a generic "copy-n-paste" widget type implementation)
Probably the biggest reason (after realizing you can run two copies of jQuery on the same page) is the file size increase. Whether it is warranted will depend on your particular needs and function. Simple small widget = straight JS. Complex website front-end extension, then it probably is worth the file-size increase.
To include it properly (so you don't run into conflicts on their site) follow a workflow that looks something like this:
Dynamically add jQuery to their page using the Google APIs as mentioned on the other answers here.
Run var mywidget_jQuery = $.noConflict( true ); which will restore the original meaning of $ and restore the original meaning of window.jQuery.
Dynamically add your script file, but be sure to wrap the entire thing in a self executing anonymous function like this:
JS
(function($){
... Your code here ...
})(mywidget_jQuery);
Now, you can safely use $ inside your special function and all the jQuery features you want without issue.
Extra credit You could wrap steps 1 and 2 in an if statement that tests if window.jQuery is defined and if it, test if jQuery.fn.version is high enough to run your code. If either test fails, then run steps 1 and 2. If it passes, however, then just run var mywidget_jQuery = window.jQuery so the script you include in step 3 will still run.
You can add jQuery to a website by simply adding a <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.js" /> element.
However, make sure to call jQuery.noConflict() in case they use a different $ keyword.
If you're just after a reference to the library, why wouldn't you just link to the API hosted on Google Code?

Categories