I'm using the latest version of RequireJS and trying to get it to work with jQuery and jQuery plugins.
I can get it to load jQuery fine, but I can't get it to work with jQuery plugins. This is my code:
var dependencies = ["order!jquery"];
dependencies = dependencies.concat([
"order!plugins/underscore-1.3.1",
"order!plugins/backbone-0.9.1",
"order!plugins/jquery.typewatch"]);
require.config({
waitSeconds: 30,
paths: {
"jquery": 'http://code.jquery.com/jquery-1.9.1'
}
});
require(dependencies, function($) {
...
jQuery is loading OK, but I then get
Uncaught ReferenceError: jQuery is not defined jquery.typewatch.js:92
Uncaught TypeError: undefined is not a function backbone-0.9.1.js:1064
The first error is complaining about jQuery not being defined, and the second about $ not being defined.
Why isn't this working? Everything seems to be loading in the right order, the order plugin works OK for underscore and backbone, and I can use $ in the code for normal jQuery functions.
Related
I am facing loading of JQuery dependency scripts with Require Js
I am having Jquery Plugins, jQuery Library and 2 module js
assets > js > vendor > jQuery Library,
assets > js > apps.js, pageTop.js, categoryJS.js
My apps.js:
require.config({
'baseUrl':'assets/js',
'paths':{
'jQuery':'vendor/jquery-1.11.2.min',
'viewportSize':'viewportSize-min',
'isoTopFilter':'isotope.pkgd.min',
'categoryJS' :'categoryJS'
},
shim:{
'jQuery': {
'exports':'$'
},
'viewportSize' :{
deps:['jQuery']
},
'isoTopFilter':{
deps:['jQuery']
},
'pageTop':{
deps:['jQuery']
},
'categoryJS':{
deps:['jQuery']
}
}
});//require.config
define(['jQuery','viewportSize','isoTopFilter','pageTop','categoryJS'], function($, pageTop, categoryJS) {
$(function() {
pageTop.alertProduct();
categoryJS.categorySlider();
});
});
and my pageTop.js
define([],function( ){
return {
alertProduct: function(){
alert('I am module2');
return true;
}
}
});
My categoryJs.js
define([],function( ){
return {
categorySlider: function(){
alert('I am module2');
return true;
}
}
});
The script is not loading, getting error
Uncaught TypeError: Cannot read property 'alertProduct' of undefined
Can some one please help me, I have tried by all means
You have:
define(['jQuery','viewportSize','isoTopFilter','pageTop','categoryJS'],
function($, pageTop, categoryJS)
Look at the list of dependencies and the list of arguments. pageTop is the 2nd argument so it will get the value of the viewportSize module. There's no magic here: each module listed in the dependencies is passed to the callback and it is passed in the same order as it appears in the dependencies. Assuming you do not need the values of viewportSize and isoTopFilter you could do this:
define(['jquery','pageTop','categoryJS','viewportSize','isoTopFilter'],
function($, pageTop, categoryJS)
Also,
jQuery calls define so you cannot set a shim for it. (It most likely will be ignored.) You should remove the shim you set for it.
Same with your own modules. If you call define and want to set a list of dependencies, pass the dependencies to define, do not set shim for these modules. shim is only for code that does not call define.
jQuery hardcodes its module name as jquery so you have to refer to it as jquery all lowercase. (More details here.) Change your paths so that you have jquery there instead of jQuery.
Maybe somebody was able to fix such issue?
Questions :
Case # 1 - why IE loads jQuery UI before jQuery even though shim
dependencies in Require JS forbid this?
This question looks similar to mine - Angular UI slider with Require JS fires before jQuery UI
Case # 2 - if i load jQuery, jQuery UI and Require JS modules
separately and specific module is dependent on jQuery UI why this
module does not know that jQuery UI was already loaded before Require
JS?
Here goes long description of the issue.
Case # 1 - everything is a module of Require JS.
In HTML i have :
<script
src="/scripts/libs/require.min.js"
data-main="/scripts/application.js">
</script>
In application.js i have :
require.config({
paths: {
libsJQ: 'libs/jquery.min',
libsUI: 'libs/jquery.ui.min',
libsMouse: 'libs/jquery.mousewheel.min',
modulesVideo: 'modules/video'
},
shim: {
libsUI: { deps: ['libsJQ'] },
libsMouse: { deps: ['libsUI'] },
modulesVideo: { deps: ['libsUI'] }
});
In modules/video.js i have :
define(function(require) {
return {
setup: function() {
var s = this;
s.link = $('.content-link');
s.popup = $('.video');
s.popup.dialog({
autoOpen: false,
show: { effect: 'fade', duration: 500 },
hide: { effect: 'fade', duration: 500 }
});
s.link.bind('click', function() {
s.popup.dialog('open');
});
}
});
1) I am having Require JS that includes jQuery, jQuery UI and several modules dependent on them.
2) Some modules depend exactly on jQuery UI e.g. module that displays video in popup
3) If i try to load everything as modules of Require JS then in all browsers everything seems to be working fine, dependencies working but from time to time in IE i get such errors
SCRIPT438: Object doesn't support property or method 'dialog'
SCRIPT438: Object doesn't support property or method 'easeOutQuad'
Which means that independently of shim dependencies sometimes in IE jQuery UI loads faster then jQuery
Case # 2 - jQuery and jQuery UI need to be included before Require JS.
In HTML i have :
<script type="text/javascript" src="/themes/sonifi/scripts/libs/jquery.min.js"></script>
<script type="text/javascript" src="/themes/sonifi/scripts/libs/jquery.ui.min.js"></script>
<script
src="<?php print sonifi_assets() ?>/scripts/libs/require.min.js"
data-main="<?php print sonifi_assets() ?>/scripts/application.js">
</script>
In application.js i have :
require.config({
paths: {
libsMouse: 'libs/jquery.mousewheel.min',
modulesVideo: 'modules/video'
});
Now i get this error in all browsers :
NetworkError: 404 Not Found - http://sonifi.web/themes/sonifi/scripts/jquery.js
Error: Script error for: jquery http://requirejs.org/docs/errors.html#scripterror
Error: Load timeout for modules: modulesVideo
Which seems that Require JS wants to include jQuery as its module otherwise if it does not have config for jQuery but it has modules that depend on jQuery it tries to find it in absolutely wrong directory and of course cannot find it there.
Seems that in my case i simply needed to increase timeout to give script a chance to load itself and only after this proceed to loading of its dependencies. If timeout is short enough Require JS simply stops loading of this script and goes to the next one.
http://requirejs.org/docs/api.html#config-waitSeconds
I am using the requirejs domReady plugin within my code like this:
1.Config for module:
requirejs.config({
baseUrl:'scripts',
paths:{
async:'lib/plugins/async',
domReady:'lib/plugins/domReady'
}
});
2.Actual module
require(['domReady!','./gmaps','./gmaps_controls'],function(gmaps,controls){
//get mapdiv here by id
//create controls from controls module here...
});
I get the error:
GET http://localhost:8180/lib/plugins/domReady.js 404 (Not Found) require.js:34
Uncaught Error: Script error for: domReady
http://requirejs.org/docs/errors.html#scripterror require.js:8
This is my file strcuture within the scripts folder:
./lib:
plugins require.js
./lib/plugins:
async.js domReady.js
UPDATE2:
I load requirejs like this:
<script type="text/javascript" data-main="scripts/gmaps_displayScenario" src="scripts/lib/require.js"></script>
This is working for me:
requirejs.config({
baseUrl:'scripts',
paths:{
async:'lib/plugins/async',
domReady:'lib/plugins/domReady'
}
});
require(['domReady!','./gmaps','./gmaps_geoJSON'],function(domReady,gmaps,geoJSON){
//code goes on
I did this because I use jQuery only for the $(document).ready() function and for making ajaxcalls...I did not want to load the whole library for this. However this is not working as specified here.
The line $("body").slimScroll(); throws error, because slimScroll is not defined. That is because require.js probably doesn't load automatically shim keys, if you are requiring any module, that is specified as dependency in shim (i think if i have shim jquery.slimscroll and its dependency is jquery, then when i require jquery, it automatically loads jquery.slimscroll - this behavior doesn't happen).
So the right way is call define(['jquery', 'jquery.slimscroll') function ($) ..., so require knows i need jquery.slimscroll and because it is in shim, it will be loaded a bit different, because it is not AMD compatible.
Problem is that if i have lot of jquery plugins, i need always pass all plugins that i need in define call. Is there any way, how to solve this type of annoying behavior and write just define(['jquery'], function ($) ..?
require.config({
baseUrl: 'js/bower',
paths: {
react: 'react/react-with-addons',
jquery: 'jquery/dist/jquery',
'jquery-private': '../jquery-private',
'jquery.slimscroll': 'jquery-slimscroll/jquery.slimscroll.min'
},
map: {
'*': {
jquery: 'jquery-private',
},
'jquery-private': {
jquery: 'jquery'
}
},
shim: {
'jquery.slimscroll': ['jquery']
}
});
require(['jquery'], function ($) {
$("body").slimScroll();
});
You could just add the jquery plugins to the dependencies of your jquery-private module.
define(['jquery', 'jquery.slimscroll', ...], function (jQuery) {
return jQuery.noConflict(true);
});
This way, when any module requires jquery, the plugins are also loaded at the same time.
I'm assuming that jquery-private is meant to load jQuery so that it does not conflict with other version of jQuery. That's what my example reflects above but it does not generally matter what the module actually does.
With this method you still need to have a shim configuration for each plugin that is not an AMD module. Moreover, your plugins will have to get a map setting just like for jquery-private to get the real jquery module. Otherwise, there will be a circular dependency.
I'm upgrading from jQuery 1.8 to 1.9 and since jQuery.browser() is removed, I will use jQuery Browser Plugin.
My requirejs config file (loaded using data-main="") looks somewhat like this:
(EDITED - added more code snippets)
main-comp.js
require.config({
paths: {
jquery: 'libs/jquery/jquery1.9.1.min',
utils: 'modules/utils',
myController: "controllers/myController",
browserPlugin: 'libs/jquery/jquery.browser.min'
},
shim: {
browserPlugin: {
deps: ['jquery']
}
}
});
require(['myController', 'jquery'], function (controller, $) {
$(controller.start);
}
);
moduls/utils.js
define(['browserPlugin'], function () {
return {
browser: $.browser
};
});
myController.js
define(['utils'], function (utils) {
function start() {
console.log(utils.browser.msie)
}
return {
start: start
};
});
Everything seemed to work properly, but then I saw that sometimes in IE only I get a 'jQuery' is undefined (it's a capital Q there) or '$' is undefined errors from the jquery.browser.min.js file.
I thought the deps means that jquery will load before the jquery.browser file but apparently this isn't always the case. I tried following this answer and add exports: "$.fn.browser" but with no success.
When running an optimized version (minify+uglify using r.js) I haven't encountered it.
What am I doing wrong?
You need to ensure you reference $ as a parameter in the require callback. Like so:
require(['myController', 'jquery'], function (controller, $) {
$(controller.start);
}
);
This ensures that jQuery is available to use. It is a bit of an odd one as it will expose itself globally anyway so it will sometimes work regardless, but the correct way is to explicitly require it and use it inside the callback as a parameter.
It looks like you are missing jquery dependency in moduls/utils.js, please try:
define(['jquery', 'browserPlugin'], function ($) {
return {
browser: $.browser
};
});
and also, just to be on the safe side, add jquery to your shim :
jquery: {
exports: "$"
},
By the way, why don't you use $.browser in your code and just load the jquery plugin using the shim configuration?
I had the same problem, the script in data-main is loading asynchronously, that means that it may load after the scripts it defines.
The solution is to load another script with the require.config right after the require.js script.
data-main Entry Point Documentation.