AMD/RequireJS

The Asynchronous Module Definition (AMD) provides a framework for predictable loading of JavaScript modules and dependencies. AMD is an extension of (and possible transport for) the CommonJS specification.

The RequireJS library implements AMD with loading, bundling and other functionality. It brings sensible imports (with define and require) to frontend JavaScript, instead of the usual array of script includes into the global namespace. Interestingly, as Node.js implements CommonJS-style require’s, there are also support modules to bring Node.js code under AMD.

Take both of things together and we have the real potential for shared JavaScript code across the browser and server. As we use this exact approach at work for our new Backbone.js frontend / Express Node.js backend web application, I created a short talk that I presented at the November 11, 2012 Node.DC meetup, entitled “Shared Code with AMD/RequireJS”.

![AMD/RequireJS Talk][img_talk] [img_talk]: http://loose-bits.com/media/img/2012/11/15/nodedc-requirejs.png

Source Code and Demo

The source for the presentation is available on GitHub. The repository further includes all of the demonstration code I used to create a shared JavaScript library and then expose it via the frontend (as straight JavaScript) and the backend (as a REST service).

The talk and the source give a good overview and run-through of how to implement simple shared code, but to give a better sense of the final result, here is a RequireJS-compliant code module (for shuffling elements in a string) that has an underscore dependency, and works in both the browser and as a standard module in Node.js:

// Node.js hook boilerplate.
// This adds the `define` function to Node.
if (typeof define !== 'function') {
  var define = require('amdefine')(module);
}

// Define wrapper gives us `require`
define(function(require) {
  // Looks like a normal `require` for Node.js.
  // Note: Both browser and Node.js should use
  // the **same** version of libraries.
  var _ = require('underscore');

  // Slice a string into a list of items
  // and return the shuffled values.
  var shuffle = function (val) {
    val = val || "";
    return _.shuffle(val.split(/[\s,]+/));
  };

  // Export our shuffle function by returning.
  return shuffle;
});

We add some boilerplate at the top of the library for Node.js, then use the define function to make a require import function available to both the browser and Node.js, and we’re off and code sharing!

AMD, RequireJS, and shared code are topics that have a lot more depth, features, and challenges. Hopefully this provides the start to a journey into better JavaScript dependency management and more extensible full stack web application development.