Modules/Wrappings-Explicit-Dependencies

From CommonJS Spec Wiki
Jump to: navigation, search

STATUS: PROPOSAL

Implementations
[[Implementations/FlyScript|]]

This specification addresses how modules may be formatted for use in contexts where the module loader may be unable to provide an implicit module scope when the module text is executed.

Background

A browser-based module loader may fetch modules in one of two ways: by using the XMLHttpRequest API or by inserting dynamically generated script tags into the document. Using XMLHttpRequest allows the loader to manipulate the module text before execution, but is subject to same-origin request policies and typically provides an inferior debugging experience. A module loader that uses script tags has the opposite problem: it sacrifices the ability to dynamically construct a module scope before the module text is executed. A server component may be used to transform the module into format that is usable by the loader, but a solution which obviates the need for such a component is preferred.

Goals

  • A wrapped module must be a valid module.
  • New free variables within the module scope should not be introduced.

Contract

  1. In a module, the free variable "module" must have a property "declare" which is a function.
  2. The "declare" method accepts a either one or two arguments.
    1. When called with one argument, that argument is the "module factory".
    2. When called with two arguments:
      1. The first argument is a "dependency array" which is an Array of relative or top-level module identifiers.
      2. The second argument is the "module factory".
  3. If specified, the environment may use the contents of the "dependency array" to ensure that the module's dependencies are avaiable prior to executing the "module factory".
  4. The environment may choose to ignore the "dependency array" and resolve dependencies in any manner appropriate for the environment.
  5. The "module factory" must be either a function or an object.
  6. If the "module factory" is a function, then:
    1. The first three formal parameters of the function, if specified, must be "require", "exports", and "module".
    2. The function, when called, must initialize the module's exports.
    3. If a value other than undefined is returned from the function, then the module's exports are set to that value.
  7. If the "module factory" is an object, then the module's exports are set to that object.

Sample Code

A basic wrapped module

module.declare(function(require, exports, module)
{
    exports.foo = "bar"; 
});

A wrapped module returning a value

module.declare(function()
{
	return { foo: "bar" };
});

A wrapped module with an object factory

module.declare(
{
	foo: "bar"
});

A wrapped module using an explicit dependency array

module.declare(["./a"], function(require, exports, module)
{
	exports.fooA = require("./a").foo;
});