Skip to content

Commit

Permalink
doc: improve description of module exports
Browse files Browse the repository at this point in the history
- Do not use word alias, it isn't well defined
- Fix return value of require() example, which confusingly was not the
  exported API as it should have been.
- Fix the require() example, which claimed that the module exported `0`,
  when it exports `some_func`.
- Describe best practice in keeping exports and module.exports bound
  together.
- Describe why exports exists
- Remove reference to magic, which is also not well defined

PR-URL: #9622
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
sam-github authored and addaleax committed Dec 5, 2016
1 parent 70633f9 commit 2e22fa0
Showing 1 changed file with 31 additions and 14 deletions.
45 changes: 31 additions & 14 deletions doc/api/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -529,34 +529,51 @@ const x = require('./x');
console.log(x.a);
```

#### exports alias
#### exports shortcut
<!-- YAML
added: v0.1.16
-->

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.
The `exports` variable is available within a module's file-level scope, and is
assigned the value of `module.exports` before the module is evaluated.

It allows a shortcut, so that `module.exports.f = ...` can be written more
succinctly as `exports.f = ...`. However, be aware that like any variable, if a
new value is assigned to `exports`, it is no longer bound to `module.exports`:

```js
module.exports.hello = true; // Exported from require of module
exports = { hello: false }; // Not exported, only available in the module
```

When the `module.exports` property is being completely replaced by a new
object, it is common to also reassign `exports`, for example:

```js
module.exports = exports = function Constructor() {
// ... etc.
```
To illustrate the behavior, imagine this hypothetical implementation of
`require()`:
`require()`, which is quite similar to what is actually done by `require()`:
```js
function require(...) {
// ...
var module = { exports: {} };
((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
// Your module code here. In this example, define a function.
function some_func() {};
exports = some_func;
// At this point, exports is no longer a shortcut to module.exports, and
// this module will still export an empty default object.
module.exports = some_func;
// At this point, the module will now export some_func, instead of the
// default object.
})(module, module.exports);
return module;
return module.exports;
}
```
As a guideline, if the relationship between `exports` and `module.exports`
seems like magic to you, ignore `exports` and only use `module.exports`.

### module.filename
<!-- YAML
added: v0.1.16
Expand Down

0 comments on commit 2e22fa0

Please sign in to comment.