Update: It appears as of Underscore 1.3 (just after this post was written), AMD support was removed, sadly. See this commit for the details.
If, like myself, you’re new to RequireJS and you’re trying to use it to roll your Backbone projects, you may be running into a few issues. Alas, it’s not quite plug n’ play (yet!).
There are a variety of places to find solutions to this problem. The only catch is that the libraries are in a bit of a state of flux. But for now, the fix is very easy.
The Prolem
Just for a quick refresher, one of the major goals of AMD is to keep modules completely self contained with access being allowed through the API you design. Even then, this is scoped to the specific module that requires it. However, jQuery, Backbone, and Underscore (Backbone hard dependency) all occupy the global space.
But we still need our tried and tested libraries! Thanks to the community, a number of solutions can be found that boot strap these into modules.
Here’s the catch. Since AMD as really catching on, the libraries are starting to integrate built in solutions.
The State of the Libraries Address
James Burke from Mozilla has been working hard to get things moving for compatibility. As you know, the Backbone stack requires jQuery (you could be using something else, but you’re likely using this), Underscore, and Backbone. The current versions are jQuery 1.7.1, Underscore 1.2.4, and Backbone 0.5.3
jQuery – As of 1.7, James had this commit accepted. However, if you look at his comments, he opted to leave the default behavior of jQuery and expose it to the global scope, leaving it up the developer to call noConflict to seal thing. It’s likely to remain like this for a while.
Underscore – As of 1.2.1, this commit was drawn into underscore. You’ll notice the first user comment says “This particular commit breaks a work around commonly used for Backbone & AMD.” Which is true. But the ultimate goal is to not have to hack at things.
Backbone – As of 0.5.3, there is no integrated support for define. James has a pending pull request to this effect. However, as noted in Underscore above, Backbone integration with RequireJS and the latest version of Underscore is currently broken. Until this is fixed, you’ll have to use the proposed branch. DOWNLOAD HERE
Getting it All to Play Nicely Together
Ok, now you’ve got your latest versions of jQuery and underscore. You’ve downloaded the AMD-ready branch of Backbone. Now, there’s only one more step.
In the branch of Backbone, it depends on the location of jQuery and Underscore being aliased specifically to ‘jquery’ and ‘underscore’ respectively (this is one of the parts that breaks existing boot strapping methods).
require.config({
paths : {
jquery : 'path/to/jquery',
underscore : 'path/to/underscore',
backbone : 'path/to/backbone'
}
});
Now, in your your modules, simply require Backbone
define([
'backbone'
],
function(Backbone) {
return Backbone.Model.extend({
initialize : function() {
}
});
}
);
Since you defined the location of jquery and underscore, in good AMD fashion, it draws in it’s own dependencies.
Unless you plan on using them in your module, there’s no need to load them.
Also, as mentioned before, jQuery will infect the global space. You’ll want to be sure to call jQuery.noConflict(true) in order to remove it.