Pseudorandom Knowledge

Organizing JavaScript with AMD

Asynchronous Module Definition is a standard for modularizing JavaScript code. RequireJS is one implementation of AMD.

/Scripts/app/constants.js
define({
    pi: 3.14159,
    e: 2.71828
});

A module in AMD consists of a a value and an identifier. The identifier is the name of the file that contains the module minus the base URL and the file ending.

/Scripts/app/circle.js
define(['app/constants'], function (constants) {
    return function (radius) {
        return {
            radius: radius,
            diameter: 2 * radius,
            circumference: 2 * constants.pi * radius,
            area: constants.pi * radius * radius
        };
    };
});

When a module is defined with a function that function will be called and the result will be used as the value. That value can still be a function which is useful because it can be used as a constructor.

This also shows how one module can depend other modules. AMD will take care of loading the other modules and pass their values to the function. Hence a function is required in this case.

/Scripts/app/main.js
require.config({
    baseUrl: '/Scripts',
    paths: {
        'jquery': 'http://code.jquery.com/jquery-2.1.0.min'
    }
});
 
require(['jquery', 'app/circle'], function ($, circle) {
    $('body').html(circle(5.3).area);
})

In the main JavaScript file RequireJS is configured and the application is started. Since this does not define a module it uses require instead of define.

<script src="/Scripts/lib/require.js" data-main="/Scripts/app/main"></script>

The only file that has to be included in the traditional way is the one for RequireJS. It then needs to know which file to start the application with.

The drawback of AMD is that there can only be one module per file. While this is good for organizing code during development it means a lot of files to download to the browser. AMD does load files asynchronously when needed. However, when used in production some way of combining JavaScript files is almost necessary.