Dependency Management Got Awesome CommonJS and AMD Compliant dependency loader for modern web apps

How Modules are Resolved

0.4.x

OLD: This is an old version of documentation. You probably want the most recent version of this document, from the sidebar on the right.

Module resolution in Inject follows the AMD and CommonJS specification. There are three governing rules:

  1. module identifers are relative when their path begins with ./ or ../. If their path does not begin with either of these, the module identifier is considered non-relative
  2. non-relative module identifiers are left alone
  3. relative module identifiers are relative to the module that made the request

Consider the following code structure:

|-modules
  |-sub
    |-a.js
    |-program.js
  |-a.js

The module root is set to modules above. You then run the program.js module, which looks like so:

var one = require('a.js');
var two = require('../a.js');
var three = require('./a.js');

module.exports.one = one.text;
module.exports.two = two.text;
module.exports.three = three.text;

modules/sub/a.js is:

module.exports.text = 'modules/sub/a.js';

and modules/a.js is:

module.exports.text = 'modules/a.js';

The exports from program.js will contain one, two, and three. Even if you adjust the URL in Inject using a function like Inject.addRule, the module’s IDs will continue to map as expected.

{
  one: 'modules/a.js',      // non-relative (a.js)
  two: 'modules/a.js',      // relative (../a.js)
  three: 'modules/sub/a.js' // relative (./a.js)
}

Why is This So?

There’s very little documentation as to the “why” behind this, so we’d like to take the time as part of the Inject framework to explain the rationale behind module IDs versus URLs. To find a real use case, the npm provides a perfect example. Each node ‘module’ can have its own internal dependencies. It doesn’t know (or care) what the rest of the system is doing. Instead, by running npm install, you mount an entire module and its sub modules to a predefined location.

Bring this back now to the web. It would be great if you could request a “carousel” module, have it depend on jQuery, and have it use its own version of jQuery internally. Then, even as you upgrade jQuery elsewhere, you don’t have to worry about your carousel unexpectectly breaking. There’s a small price to pay in potentially having multiple copies of a submodule floating around, but the dependency management (and lack of regressions) is worth its weight in gold on large scale sites.

comments powered by Disqus