I\'ve found the following contract in a Node.js module:
module.exports = exports = nano = function database_module(cfg) {...}
I wonder what
Both
module.exports
andexports
point to the samefunction database_module(cfg) {...}
.
1| var a, b;
2| a = b = function() { console.log("Old"); };
3| b = function() { console.log("New"); };
4|
5| a(); // "Old"
6| b(); // "New"
You can change b
on line 3 to a
, the output is reverse. The conclusion is:
a
andb
are independent.
So module.exports = exports = nano = function database_module(cfg) {...}
is equivalent to:
var f = function database_module(cfg) {...};
module.exports = f;
exports = f;
Assumed the above is module.js
, which is required by foo.js
. The benefits of module.exports = exports = nano = function database_module(cfg) {...}
is clear now:
In foo.js
, since module.exports
is require('./module.js')
:
var output = require('./modules.js')();
In moduls.js
: You can use exports
instead of module.exports
.
So, you will be happy if both exports
and module.exports
pointing to the same thing.
It's a subtle difference to do with the way objects are passed by reference in JavaScript.
exports
and module.exports
both point to the same object. exports
is a variable and module.exports
is an attribute of the module object.
Say I write something like this:
exports = {a:1};
module.exports = {b:12};
exports
and module.exports
now point to different objects. Modifying exports no longer modifies module.exports.
When the import function inspects module.exports
it gets {b:12}
I found this link useful to answer the above question.
http://timnew.me/blog/2012/04/20/exports-vs-module-exports-in-node-js/
To add to the other posts The module system in node does
var exports = module.exports
before executing your code. So when you want to exports = foo , you probably want to do module.exports = exports = foo but using exports.foo = foo should be fine
exports
and module.exports
are the same unless you reassign exports
within your module.
The easiest way to think about it, is to think that this line is implicitly at the top of every module.
var exports = module.exports = {};
If, within your module, you reassign exports
, then you reassign it within your module and it no longer equals module.exports
. This is why, if you want to export a function, you must do:
module.exports = function() { ... }
If you simply assigned your function() { ... }
to exports
, you would be reassigning exports
to no longer point to module.exports
.
If you don't want to refer to your function by module.exports
every time, you can do:
module.exports = exports = function() { ... }
Notice that module.exports
is the left most argument.
Attaching properties to exports
is not the same since you are not reassigning it. That is why this works
exports.foo = function() { ... }
"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." - http://nodejs.org/api/modules.html
This shows how require()
works in its simplest form, excerpted from Eloquent JavaScript
Problem
It is not possible for a module to directly export a value other than the exports object, such as a function. For example, a module might want to export only the constructor of the object type it defines. Right now, it cannot do that because require always uses the exports
object it creates as the exported value.
Solution
Provide modules with another variable, module
, which is an object that has a property exports
. This property initially points at the empty object created by require but can be overwritten with another value in order to export something else.
function require(name) {
if (name in require.cache)
return require.cache[name];
var code = new Function("exports, module", readFile(name));
var exports = {}, module = {exports: exports};
code(exports, module);
require.cache[name] = module.exports;
return module.exports;
}
require.cache = Object.create(null);