DEV Community

Uday Janardhan Singh
Uday Janardhan Singh

Posted on • Edited on

Node.js Export Dilemma: Decoding module.exports vs exports for Developers

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;
Enter fullscreen mode Exit fullscreen mode

Or we can use this below syntax by reassigning.

module.exports = {
  send,
  REQUEST_TIMEOUT
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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:

Module.exports object refrence

  • Initially,module.exports=exports , and the require function returns the object module.exports refers 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 as REQUEST_TIMEOUT with a value of 500.

  • 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 function from other module will not return the newly created send function as the export. Instead, the original object referenced by module.exports is 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 = {};
Enter fullscreen mode Exit fullscreen mode

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)