As we discussed briefly in Authoring AMD Modules, some modules require other modules to do their work. The module author specifies these other modules by listing each module's id in the dependency list or in a "local require".

Module ids

AMD and CommonJS both specify module ids that look very much like file paths or urls: ids consist of terms separated by slashes. The definition of "terms" is fairly loose. The CommonJS spec further restricts "terms" to be camelCase Javascript identifiers, but in practice, other popular file name characters, such as - are acceptable. The proposed ES6 modules spec is much more flexible, but, realistically, ids should be compatible with file systems and urls.

AMD reserves the ! character to indicate that a Loader Plugin should be used to load the module or other type of resource.

Some examples of acceptable module ids:

"wire/lib/functional"
"poly/es5-strict"
"app/billing/billTo/Customer"
"jquery"

As with file systems and urls, the slashes delineate organizational hierarchies. Typically, these hierarchies are mirrored by identical directory structures in the underlying file system, but this mirroring is not guaranteed. For example, curl.js exposes some extensibility API modules. These modules have ids of the form "curl/", but they don't actually exist as files.

Be careful to capitalize correctly. Because most modules typically map to files, spell and capitalize the module name exactly the same as the file name. For example, "jQuery" is almost always not the correct module id (capital "Q")! Here's how you would require jQuery in a module:

define(function (require) {

    var $ = require('jquery');
    $('body').text('Hello world!');

});

Reserved ids

Most AMD environments reserve a few special module ids to refer to built-in modules and utilities. For example, most AMD environments reserve the "require", "exports", and "module" ids to gain access to pseudo-modules that simulate the free variables of CommonJS. AMD environments may reserve a few other ids, as well. For example, a proposed feature of curl.js 0.8 is a global pseudo-module to help devs create code that works on the server and the browser.

define(function (require) {

    // inspect the CommonJS "module" var
    var module = require('module');
    console.log(module.uri, module.id);

});

Check your AMD environment's documentation for more information about reserved module ids.

Relative Ids

AMD and CommonJS also support the notion of relative module identifiers. Modules that reside in the same hierarchical level can be referenced by using ./ at the beginning of the id. Modules that reside one level up from the current level can be referenced using ../.

At run time or build time, the AMD environment must translate relative ids to absolute ids. Absolute ids are rooted at the top level of the module hierarchy and contain no .. or .. The process of removing the leading .. or . is called "normalization". For example, assuming app/billing/billTo/Customer is the id of the current module, the environment normalizes required ids as follows:

// module app/billing/billTo/Customer
define(function (require) {

    // normalizes to "app/billing/billTo/store"
    var store = require("./store");

    // normalizes to "app/billing/payee/Payee"
    var Payee = require("../payee/Payee");

});

AMD and CommonJS also recognize bare . and .. as module identifiers. . normalizes to the module whose name is the same as the current level. .. normalizes to the module whose name is the same as the level that is one level up from the current level. Yes, that is confusing! Perhaps that's why you don't see these used often. Hopefully, some examples might help. For example, given that the current module is "app/billing/billTo/Customer", the environment normalizes these ids as follows:

// module app/billing/billTo/Customer
define(function (require) {

    // normalizes to "app/billing/billTo" (a module, not a folder!)
    var billTo = require(".");

    // normalizes to "app/billing" (a module, not a folder!)
    var billing = require("..");

});

Hint: Never use relative module ids to reference unrelated modules! Relative modules are meant to be used within a "package" (defined later). Also, more than one set of ../ may be a code smell that you need to organize your modules better. The relative id may also be interpreted as a url, rather than an id by an AMD environment.

// module app/billing/billTo/Customer
define(function (require) {

    // OK: normalizes to "app/common/payee/Payee"
    // food for thought: should common and billing be separate packages?
    var Payee = require("../../common/payee/Payee");

    // BAD: normalizes to "../util/date" -- a URL, not an ID!
    var Date = require("../../../util/Date");

    // GOOD: use an absolute id to reference a different package
    var Date = require("util/Date"); // "Date" module in the "util" package

});

So, how does the AMD environment know where to find modules if I specify ids and not urls?

That's the topic of Consuming modules: locating modules in AMD.