I just tried upgrading to Backbone 1.1.2, and have been having issues with jQuery.
By default, Backbone expects to find the jQuery in the base directory as ./jquery.js
. When I add this into the RequireJS path and add it to the shim as a dependency for Backbone, then everything works inside of require
, but outside, nothing works. It's as if the local reference I am creating is stomping over the globally included jQuery?
In my html page, I have this:
<script src="js/lib/jquery/2.0.2/jquery.min.js"></script>
<script src="js/lib/jqueryui/{$jquery.ui.version}/jquery-ui.min.js"></script>
<script data-main="js/homepage" src="js/lib/require/2.1.11/require.min.js"></script>
homepage.js
(which currently works) looks like this:
require.config({
baseUrl: "./js",
paths: {
Underscore: 'lib/underscore/1.6.0/underscore-min',
Backbone: 'lib/backbone/1.0.0/backbone-min'
// ,jquery: 'lib/jquery/2.0.2/jquery.min'
// ,jqueryui: 'lib/jqueryui/1.10.3/jquery-ui.min'
},
shim: {
// 'jqueryui': {
// deps: ['jquery'],
// exports: "$"
// },
'Underscore': {
// deps: ['jquery'],
exports: "_"
},
'Backbone': {
deps: ['Underscore', /*'jquery'*/],
exports: 'Backbone'
}
}
});
require([ 'views/homepage/main' ], function(Main) {
});
In this situation, I am using the global jQuery and it works perfectly, both inside the app, and globally for my site navigation which uses jQuery. The js also minifies perfectly with r.js
.
But when I change my BB version to 1.1.2, it says that it can't find jquery.js
. When I uncomment all of the lines in homepage.js
to include jQuery dependencies, everything renders within the application, but now my navigation breaks, saying that the jQuery functions that i have created are undefined. I am also unable to minify my app in r.js
.
This leads me to believe that jQuery
and $
in the global namespace are being stomped on when RequireJS starts downloading its dependencies. Is this just a classic case of needing to use $.noConflict
? If so, how do I modify my code to do this?
Update for more recent versions
The answer was originally written for Backbone 1.1.2, and an older version of Underscore.
Recent versions are AMD-aware and do not need
shim
set for them. You should also use all lowercase names for the modules:backbone
andunderscore
because some of these names are hardcoded. (You can work around the hardcoding with amap
config but it is just simpler to use the standard, all lowercase names.)The solution
If you load jQuery with a
<script>
tag and then load it in RequireJS you have to take special precautions. However, I do not notice anything in your question that indicates that you need to have two jQueries loaded. So you could use the following trick to use the same instance of jQuery outside and inside AMD modules:This way when RequireJS "loads" the
jquery
module, it'll execute the code passed to thedefine
above. As I recall, jQuery UI just installs itself as a jQuery plugin so you don't need to do anything special about it. Also I recommend using Backbone 1.1.2, which does not need a shim. Underscore does not depend on jQuery so the shim for it does not need a dependency for it.