AMD – CommonsJS Modules for the Browser

The Asynchronous Module Definition API (AMD) brings modular JavaScript to the browser similar to the CommonsJS Modules API. The difference with CommonsJS modules is that AMD enables modules to be loaded asynchronously on demand, reducing browser footprint. As with CommonsJS modules, AMD modules do not add variables to the global namespace, helping to avoid clashes between libraries. But do the benefits of AMD justify the extra effort and learning curve for using it in browser JavaScript projects?

The API itself is straightforward to use. To load a module, the require function is used:

// Require a defined module
require(['alpha'], function (Alpha) {
// Module loaded
var myAlpha = new Alpha();
});

To declare a module, the define method is used. Note that dependencies on further modules can be declared, allowing the AMD script loader to load them as well.

// Module alpha depends on beta
define(‘alpha’, [‘beta’], function (Beta) {
var Alpha = function () {};
return Alpha;
});

There are several implementations of AMD. RequireJS (written by James Burke) is popular and offers additional benefits in the form of the r.js optimizer that can “uglify”, minify and concatenate AMD modules as part of an automated build.

One obstacle to AMD adoption is that although AMD versions of libraries like JQuery, JQueryUI, Backbone and Underscore exist there aremany libraries that do not (yet) use AMD. RequireJS does provide a shim to load non-AMD libraries, but the load order can be critical between dependent modules which could introduce hard to catch errors. And while it’s possible to write AMD wrappers around non-AMD libraries (and James Burke’s volo tool can automate this with the amdify goal), it does creates extra work. And AMD can still have naming collisions (read this debate on the topic) – although unlike global variables, an engineer can control this by configuring AMD correctly.

Despite this drawback, AMD offers real benefits with a low cost in complexity. Over time, hopefully more libraries will follow JQuery in adopting AMD (even if James Burke has to do all the work), which will make it even easier for engineers to enjoy the benefits of asynchronous modularity in their web projects.