javascript tutorial - [Solved-5 Solutions] Module.exports vs exports in node.js - javascript - java script - javascript array
Problem:
I've found the following contract in a Node.js module:
- We wonder whats the different between module.exports and exports and why both are used here
Solution 1:
The following won't work.
The following will work if module.exports is set.
console
- Basically node.js doesn't export the object that exports currently references, but exports the properties of what exports originally references. Although Node.js does export the object module.exports references, allowing we to call it like a function.
- 2nd least important reason
- They set both module.exports and exports to ensure exports isn't referencing the prior exported object. By setting both we use exports as a shorthand and avoid potential bugs later on down the road.
- Using exports.prop = true instead of module.exports.prop = true saves characters and avoids confusion.
Solution 2:
Basically the answer lies in what really happens when a module is required via require
statement. Assuming this is the first time the module is being required.
For example:
contents of file1.js:
When the above statement is executed, a Module
object is created. Its constructor function is:
- As we see each module object has a property with name
exports
. This is what is eventually returned as part ofrequire
. - Next step of require is to wrap the contents of file1.js into an anonymous function like below:
And this anonymous function is invoked the following way, module here refers to the ModuleObject created earlier.
- As we can see inside the function, exports formal argument refers to module.exports. In essence it's a convenience provided to the module programmer.
- However this convenience need to be exercised with care. In any case if trying to assign a new object to exports ensure we do it this way.
If we do it following way wrong way, module.exports
will still be pointing to the object created as part of module instance.
As as result adding anything to the above exports object will have no effect to module.exports object and nothing will be exported or returned as part of require.
Solution 3:
- Initially,
module.exports=exports
, and therequire
function returns the object module.exportsrefers 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, we 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.
Solution 4:
JavaScript passes by reference.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 we write something like this:
exports = {a:1}; module.exports = {b:12};
Solution 5:
- Here is a good description written about node modules in node.js in action book from Manningpublication.
- What ultimately gets exported in our 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 we 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 we want to maintain that link, we can make module.exports reference exports again as follows: