The power of the Asynchronous Module Definition

[2011-10-14] dev, javascript, jsmodules, jslang
(Ad, please don’t block)
Update 2011-11-19: Bridging the module gap between Node.js and browsers

This post explains Asynchronous Module Definition (AMD), a standard for defining modules in JavaScript and contrasts it with the currently very popular CommonJS synchronous modules.

Currently, CommonJS-style synchronous modules are very popular. For example, they are used in Node.js. Such a module looks as follows.

    // Import new modules anywhere
    var otherModule = require("libs/otherModule");
    
    // Export your functions, classes, objects etc.
    exports.myFunction = function () {
        otherModule.otherExportedFunction() + 1;
    };
However, Asynchronous Module Definitions (AMDs) are slowly getting traction. Example:
    // Import all modules in a single location
    define([ "libs/otherModule" ],
        function (otherModule) {
            // Export your module as an object
            return {
                myFunction: function () {
                    otherModule.otherExportedFunction() + 1;
                }
            };
        }
    );
The main advantages are:
  • Asynchronous: AMDs have been designed to support asynchronicity and most AMD-compatible script loaders take advantage of it. Thus, AMD modules can be loaded in parallel. Once the last imported module has finished loading, the importing module can be evaluated. It is ironic that the Node.js module system is synchronous.
  • Work in browsers: Browser modules have to be asynchronous and AMDs are.
  • No globals: AMDs avoid global variables from being created, because there is always a wrapping function. Note, though, that CommonJS-compliant module loaders usually also (invisibly) wrap modules they load in a function.
  • No more namespacing: AMDs obviate the need for namespacing such as foo.bar.myModule, via a global variable and nested objects. The namespacing is in the path to the file, a local variable is short and convenient handle.
Two popular script loaders that support AMDs (source: [1]): Related reading:
  1. AMD is better for the web than CommonJS modules” by Miller Medeiros. [The post goes into greater detail regarding AMD features such as loading non-script resources.]
  2. Modules and namespaces in JavaScript [explains several module patterns and gives an in-depth perspective on modularity in JavaScript]
  3. A first look at the upcoming JavaScript modules [thankfully, these will make all current module systems obsolete, in the long run]