I\'ve found the following contract in a Node.js module:
module.exports = exports = nano = function database_module(cfg) {...}
I wonder what
Here is the result of
console.log("module:");
console.log(module);
console.log("exports:");
console.log(exports);
console.log("module.exports:");
console.log(module.exports);
Also:
if(module.exports === exports){
console.log("YES");
}else{
console.log("NO");
}
//YES
Note: The CommonJS specification only allows the use of the exports variable to expose public members. Therefore, the named exports pattern is the only one that is really compatible with the CommonJS specification. The use of module.exports is an extension provided by Node.js to support a broader range of module definition patterns.
1.exports -> use as singleton utility
2. module-exports -> use as logical objects such as service , model etc
Here is a good description written about node modules in node.js in action book from Manning publication.
What ultimately gets exported in your application is module.exports.
exports is set
up simply as a global reference to module.exports , which initially is defined as an
empty object that you can add properties to. So exports.myFunc is just shorthand
for module.exports.myFunc.
As a result, if exports is set to anything else, it breaks the reference between
module.exports and exports . Because module.exports is what really gets
exported, exports will no longer work as expected—it doesn’t reference module
.exports anymore. If you want to maintain that link, you can make module.exports
reference exports again as follows:
module.exports = exports = db;
Initially,module.exports=exports
, and the require
function returns the object module.exports
refers to.
if we add property to the object, say exports.a=1
, then module.exports and exports still refer to the same object. So if we call require and assign the module to a variable, then the variable has a property a and its value is 1;
But if we override one of them, for example, exports=function(){}
, then they are different now: exports refers to a new object and module.exports refer to the original object. And if we require the file, it will not return the new object, since module.exports is not refer to the new object.
For me, i will keep adding new property, or override both of them to a new object. Just override one is not right. And keep in mind that module.exports
is the real boss.
var a = {},md={};
//Firstly,the exports and module.exports point the same empty Object
exp = a;//exports =a;
md.exp = a;//module.exports = a;
exp.attr = "change";
console.log(md.exp);//{attr:"change"}
//If you point exp to other object instead of point it's property to other object. The md.exp will be empty Object {}
var a ={},md={};
exp =a;
md.exp =a;
exp = function(){ console.log('Do nothing...'); };
console.log(md.exp); //{}
To understand the differences, you have to first understand what Node.js does to every module during runtime. Node.js creates a wrapper function for every module:
(function(exports, require, module, __filename, __dirname) {
})()
Notice the first param exports
is an empty object, and the third param module
is an object with many properties, and one of the properties is named exports
. This is what exports
comes from and what module.exports
comes from. The former one is a variable object, and the latter one is a property of module
object.
Within the module, Node.js automatically does this thing at the beginning: module.exports = exports
, and ultimately returns module.exports
.
So you can see that if you reassign some value to exports
, it won't have any effect to module.exports
. (Simply because exports
points to another new object, but module.exports
still holds the old exports
)
let exports = {};
const module = {};
module.exports = exports;
exports = { a: 1 }
console.log(module.exports) // {}
But if you updates properties of exports
, it will surely have effect on module.exports
. Because they both point to the same object.
let exports = {};
const module = {};
module.exports = exports;
exports.a = 1;
module.exports.b = 2;
console.log(module.exports) // { a: 1, b: 2 }
Also notice that if you reassign another value to module.exports
, then it seems meaningless for exports
updates. Every updates on exports
is ignored because module.exports
points to another object.
let exports = {};
const module = {};
module.exports = exports;
exports.a = 1;
module.exports = {
hello: () => console.log('hello')
}
console.log(module.exports) // { hello: () => console.log('hello')}