This specification addresses how modules should be written in order to be interoperable in browser-based environment. By implication, this specification defines the minimum features that a module system must provide in order to support interoperable modules.
- Modules are singletons.
- New free variables within the module scope should not be introduced.
- Execution must be lazy.
A module is defined with define
keyword, which is a function.
define(factory);
- The
define
function accepts a single argument, the module factory. - The
factory
may be a function or other valid values. - If
factory
is a function, the first three parameters of the function, if specified, must be "require", "exports", and "module", in that order. - If
factory
is not a function, then the module's exports are set to that object.
In a module, there are three free variables: require
, exports
and module
.
define(function(require, exports, module) {
// The module code goes here
});
-
require
is a functionrequire
accepts a module identifier.require
returns the exported API of the foreign module.- If requested module cannot be returned,
require
should return null.
-
require.async
is a functionrequire.async
accepts a list of module identifiers and a optional callback function.- The callback function receives module exports as function arguments, listed in the same order as the order in the first argument.
- If requested module cannot be returned, the callback should receive null correspondingly.
In a module, there is a free variable called "exports", that is an object that the module may add its API to as it executes.
-
module.uri
The full resolved uri to the module.
-
module.dependencies
A list of module identifiers that required by the module.
-
module.exports
The exported API of the module. It is the same as
exports
object.
- A module identifier is and must be a literal string.
- Module identifiers may not have a filename extensions like
.js
. - Module identifiers should be dash-joined string, such as
foo-bar
. - Module identifiers can be a relative path, like
./foo
and../bar
.
A typical sample
math.js
define(function(require, exports, module) {
exports.add = function() {
var sum = 0, i = 0, args = arguments, l = args.length;
while (i < l) {
sum += args[i++];
}
return sum;
};
});
increment.js
define(function(require, exports, module) {
var add = require('math').add;
exports.increment = function(val) {
return add(val, 1);
};
});
program.js
define(function(require, exports, module) {
var inc = require('increment').increment;
var a = 1;
inc(a); // 2
module.id == "program";
});
Wrapped modules with non-function factory
object-data.js
define({
foo: "bar"
});
array-data.js
define([
'foo',
'bar'
]);
string-data.js
define('foo bar');