Browse Source

doc: improve module documentation

Expands on when to use module.exports vs. exports. This is a recurring
question on mailing list and continues to confuse new devs.
v0.10.22-release
Ryan Graham 11 years ago
committed by Ben Noordhuis
parent
commit
5ac6f4de13
  1. 8
      doc/api/globals.markdown
  2. 74
      doc/api/modules.markdown

8
doc/api/globals.markdown

@ -124,7 +124,9 @@ Example: running `node example.js` from `/Users/mjr`
* {Object}
A reference to the current module. In particular
`module.exports` is the same as the `exports` object.
`module.exports` is used for defining what a module exports and makes
available through `require()`.
`module` isn't actually a global but rather local to each module.
See the [module system documentation][] for more information.
@ -133,10 +135,10 @@ See the [module system documentation][] for more information.
<!-- type=var -->
A reference to the `module.exports` object which is shared between all
instances of the current module and made accessible through `require()`.
A reference to the `module.exports` that is shorter to type.
See [module system documentation][] for details on when to use `exports` and
when to use `module.exports`.
`exports` isn't actually a global but rather local to each module.
See the [module system documentation][] for more information.

74
doc/api/modules.markdown

@ -27,26 +27,33 @@ The contents of `circle.js`:
};
The module `circle.js` has exported the functions `area()` and
`circumference()`. To export an object, add to the special `exports`
object.
`circumference()`. To add functions and objects to the root of your module,
you can add them to the special `exports` object.
Note that `exports` is a reference to `module.exports` making it suitable
for augmentation only. If you are exporting a single item such as a
constructor you will want to use `module.exports` directly instead.
Variables local to the module will be private, as though the module was wrapped
in a function. In this example the variable `PI` is private to `circle.js`.
function MyConstructor (opts) {
//...
}
If you want the root of your module's export to be a function (such as a
constructor) or if you want to export a complete object in one assignment
instead of building it one property at a time, assign it to `module.exports`
instead of `exports`.
// BROKEN: Does not modify exports
exports = MyConstructor;
Below, `bar.js` makes use of the `square` module, which exports a constructor:
// exports the constructor properly
module.exports = MyConstructor;
var square = require('./square.js');
var mySquare = square(2);
console.log('The area of my square is ' + mySquare.area());
Variables
local to the module will be private. In this example the variable `PI` is
private to `circle.js`.
The `square` module is defined in `square.js`:
// assigning to exports will not modify module, must use module.exports
module.exports = function(width) {
return {
area: function() {
return width * width;
}
};
}
The module system is implemented in the `require("module")` module.
@ -232,18 +239,21 @@ would resolve to different files.
* {Object}
In each module, the `module` free variable is a reference to the object
representing the current module. In particular
`module.exports` is accessible via the `exports` module-global.
`module` isn't actually a global but rather local to each module.
representing the current module. For convenience, `module.exports` is
also accessible via the `exports` module-global. `module` isn't actually
a global but rather local to each module.
### module.exports
* {Object}
The `module.exports` object is created by the Module system. Sometimes this is not
acceptable, many want their module to be an instance of some class. To do this
assign the desired export object to `module.exports`. For example suppose we
were making a module called `a.js`
acceptable; many want their module to be an instance of some class. To do this
assign the desired export object to `module.exports`. Note that assigning the
desired object to `exports` will simply rebind the local `exports` variable,
which is probably not what you want to do.
For example suppose we were making a module called `a.js`
var EventEmitter = require('events').EventEmitter;
@ -277,6 +287,28 @@ y.js:
var x = require('./x');
console.log(x.a);
#### exports alias
The `exports` variable that is available within a module starts as a reference
to `module.exports`. As with any variable, if you assign a new value to it, it
is no longer bound to the previous value.
To illustrate the behaviour, imagine this hypothetical implementation of
`require()`:
function require(...) {
// ...
function (module, exports) {
// Your module code here
exports = some_func; // re-assigns exports, exports is no longer
// a shortcut, and nothing is exported.
module.exports = some_func; // makes your module export 0
} (module, module.exports);
return module;
}
As a guideline, if the relationship between `exports` and `module.exports`
seems like magic to you, ignore `exports` and only use `module.exports`.
### module.require(id)

Loading…
Cancel
Save