Modules/Wrappings
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.
Contents
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
- In a module, the free variable "module" must have a property "declare" which is a function.
- The "declare" method accepts a single argument, the module factory.
- The module factory must be either a function or an object.
- If the module factory is a function, then:
- The first three formal parameters of the function, if specified, must be "require", "exports", and "module", in that order.
- The function, when called, should initialize the module's exports.
- 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.
- 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" });