I am using requirejs + jquery + jqueryui. I have read TONS of examples of how to do this. I think I understand the various approaches and it seems to me that my setup should be working correctly. However, I occasionally get a $.widget is not defined error in my custom modules that depend on jquery-ui. It is a pain because it is inconsistent and hard to reproduce so it is hard for me to test alternative approaches.
I am not shimming all of my jquery plugins because there are a lot. Instead, I am loading jquery with a separate requirejs call. Then, in the callback for that I load the rest of my stuff. This way I don't have to maintain a list of shims for all my jquery plugins.
For jquery-ui, I use a shim to make it depend on jquery. Then all my custom modules that use the widget factory have 'jquery-ui' in their dependency list.
In my templates...
requirejs.config({
baseUrl: ATHLETE.siteConfig.jsBaseUrl,
paths: {
'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min',
'jquery-ui': '//ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min'
},
shim: {
"jquery-ui": ['jquery']
},
waitSeconds: 15
});
requirejs(['jquery'], function($) {
requirejs(['site'], function() {
requirejs(['mypage']);
});
});
Note that I am loading site.js before mypage.js. They have some shared dependencies. In my build config, I exclude site.js from mypage.js, therefore the shared dependencies are compiled into site.js and not mypage.js. Therefore, I need to completely load site.js before loading mypage.js or else require might try to load those shared dependencies separately.
Here's a sample custom module of mine that depends on jquery-ui.
define([
'jquery',
'jquery-ui'
],function($) {
$.widget('ui.viewAllSponsorsWidget', $.ui.dialog, {
options: {
autoOpen: false,
dialogClass: 'view-all-sponsor-dialog-wrap',
draggable: false,
modal: true,
resizable: false,
width: 370,
height: 400
}
});
});
The error $.widget is not defined is caused by the 5th line of this and similar custom modules of mine. Again, it is really inconsistent and hard to reproduce. More often than not, I do NOT get the error, even when I clear my cache. Can anyone think of a way that line 5 could possibly be getting executed before jquery-ui is fully loaded?
UPDATE Aug 16, 2013
I have been able to track this down a bit more. I created a simple module that depends on jquery and jquery-ui.
define([
'jquery',
'jquery-ui'
],function($) {
console.log('$.widget is defined? ' + Boolean($.widget));
console.log('jQuery.widget is defined? ' + Boolean(jQuery.widget));
});
The output of this is as follows:
LOG: $.widget is defined? false
LOG: jQuery.widget is defined? true
So somehow the global jQuery object has widget defined, but the copy provided to me by requirejs does not.
Change your shim to this:
shim: {
'jquery-ui': ['jquery']
}
Here is an example of a bunch of Require.js configurations for popular libraries.