Modules/Wrappings

From CommonJS Spec Wiki
Jump to: navigation, search

STATUS: PROPOSAL

Implementations
[[Implementations/FlyScript|]], [[Implementations/SeaJS|]]

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 single argument, the module factory.
  3. The module factory must be either a function or an object.
  4. 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", in that order.
    2. The function, when called, should initialize the module's exports.
    3. If a value is returned from the function such that the abstract operation ToBoolean(value) equals true, then the module's exports are set to that value.
  5. 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(require)
{
	return { foo: "bar" };
});

A wrapped module with an object factory

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