Sunday, January 22, 2012

AMD support for Underscore and Backbone

As mentioned previously, at the moment there is no support for AMD in Underscore, a decision that also affects Backbone.

However, there have been enough developers interested in using Underscore and Backbone with AMD that forks were set up under the amdjs organization that have optional define() calls in them:

https://github.com/amdjs/underscore

https://github.com/amdjs/backbone

Ryan Florence suggested the AMD community maintain these forks, and if you would like to see AMD support as part of the main repos, click on the links above and click the Watch button. But only do it if you actually use the libraries above in an AMD context.

Hopefully this will give the DocumentCloud folks some indication of how many people might benefit from having support directly in the main repos, and maybe over time AMD support can be added to the main repos.

Both forks optionally register as AMD modules but also export global objects. This is to address the difficulty Underscore saw when only doing the AMD call, which led to the AMD removal from Underscore.

If you want an easy way to fetch these AMD versions from the command line, or to have a tool to make it easy to AMD-wrap older releases of those libraries, use volo. The README's Usage section has specific instructions on how to fetch these libraries.

If you would like to try an AMD+Backbone option that does to not modify the source files, check out Tim Branyen's explorations.


9 comments:

Darcy Parker said...

Thanks for creating these forks. I was using a previous version of underscore with AMD support. And I was using jburk's fork of backbone with AMD support so I could use it in my project. I really like the AMD approach when developing and don't really grok why I should run a build each time I want to make a quick edit. I prefer to build when I am ready to deploy and feel I work more efficiently with the AMD approach during development. I just swapped out my previous versions of underscore/backbone and replaced them with these forks. Works nicely. (I am now watching the github repos for these forks.)

Alex Lawrence said...

I don´t about how it was but why is it that underscore is registering itself as named AMD module? The other day I just read multiple times that anonymous modules are far more portable (maybe even on your website?).

James Burke said...

Alex Lawrence: this section has some info on why jQuery and Underscore register as named modules.

Leo C said...

Hi there, I was looking at the AMD fork of Backbone and noticed that the define lists 'exports' as a dependency. What is 'exports' referring to? I can't think of another hard dependency that Backbone has other than underscore and jQuery and i don't want the module to fail to load because I didn't declare something.

Hope that makes sense.

James Burke said...

Leo C: 'exports' is a special dependency that maps to the Node/CommonJS idea of 'exports'. More information here.

Vic said...

Hi, quick question. I've been dabbling with Backbone and Underscore lately and I'm now trying to use RequireJS for dependency management, etc. Can you explain really quick what this fork of Backbone and Underscore allows that we can't already do with RequireJS plus the originals? If you've already explained the problem somewhere, I'd appreciate the link. Thanks :)

James Burke said...

Vic: the amdjs branches register the right object as a module export, and in the Backbone case, specifies 'underscore' and 'jquery' as dependencies via a define() wrapper, so that the code that defines Backbone does not execute until those dependencies are available.

You can use AMD loader plugins like order or even better use to get a similar behavior without having to modify the file source to add the AMD define call.

I personally prefer to have the define() calls in the file so that it reduces the amount of special case loader plugins and config. For this reason, volo has an "amdify" command that can be used to wrap traditional scripts in a define() wrapper.

But ideally the library in question would do the optional define() call in its source directly, it normally results in better, cleaner code.

Unknown said...

I'm this must have been discussed somewhere else, but doea nybody have an idea why backbone and underscore devs dropped amd support? Are there any plans to provide it in the near future?

James Burke said...

opensas opensas: discussed a little bit in the first link from this post:

http://tagneto.blogspot.ca/2012/01/simplicity-and-javascript-modules.html

near the end of it. End result, the author of those libraries does not need it for projects, and does not want any support burden by introducing it, instead preferring to wait for modules to get into the language.