From 5887c2ba3840be81ab6e89481e771a5d277101ae Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Tue, 15 Nov 2016 10:31:27 -0800 Subject: [PATCH] doc: improve description of module `exports` - 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: https://github.com/nodejs/node/pull/9622 Reviewed-By: Luigi Pinca Reviewed-By: Stephen Belanger Reviewed-By: James M Snell --- doc/api/modules.md | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/doc/api/modules.md b/doc/api/modules.md index ad98a0abcc20c4..1978c0aa3f521f 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -529,34 +529,51 @@ const x = require('./x'); console.log(x.a); ``` -#### exports alias +#### exports shortcut -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