Introduction:
The debate between module.exports and exports in Node.js often confuses many developers, and this is something which made me confuse when i started learning NodeJS. Both are used to export modules in Node.js, but there are differences in how they function.
Let's look one by one with example.
Default Export Object: module.exports is the actual object that is returned when a module is required. It starts as an empty object and anything assigned to module.exports will be returned as the result of the require function.
Example:
const REQUEST_TIMEOUT = 500;
function send(url, data) {
console.log(`Sending ${data} to server`);
}
module.exports.send = send;
module.exports.REQUEST_TIMEOUT = REQUEST_TIMEOUT;
Or we can use this below syntax by reassigning.
module.exports = {
send,
REQUEST_TIMEOUT
}
Alias to module.exports: exports is essentially a shortcut or an alias for module.exports. It allows you to add properties and methods to the module that will be available when the module is required. Provided you have not reassigned the module.exports or exports. It allows a shortcut, so that module.exports.send = send can be written more succinctly as exports.send = send.
Example:
exports.send = send;
exports.REQUEST_TIMEOUT = REQUEST_TIMEOUT;
We have seen the both the examples and their usage let's dive deep to get better understanding how these two works internally.
Difference in Reassignment:
Initially,
module.exports=exports, and therequirefunction returns the objectmodule.exportsrefers to.When properties or methods are added to this shared object through exports, like
exports.REQUEST_TIMEOUT = 500, both module.exports and exports maintain reference to the same object. Thus, upon requiring this module and assigning it to a variable, that variable will have access to the added property, such asREQUEST_TIMEOUTwith a value of500.However, when one of them is overridden or reassigned. For instance, if exports is reassigned explicitly, like
exports = function send {...}, a crucial change occurs: exports now refers to a new empty object, while module.exports retains its reference to the original object. Consequently, requiring this
send functionfrom other module will not return the newly createdsend functionas the export. Instead, the original object referenced bymodule.exportsis retrieved.
Always remember module.exports is Boss.
Conclusion.
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 = {};
In essence, exports and module.exports are essentially the same, up until you reassign exports within your module. This action causes a separation between the two, where exports points to a new object and module.exports maintains reference to the original one.

Top comments (0)