Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why we use exports in nodejs?

Tags:

node.js

I am newbie of Nodejs. As per me module.exports and exports both are empty object. module.exports can expose function while exports can not to this. Everything can achieve from module.exports.

So, why we use exports even we have module.exports? what are the advantages of exports over module.exports?

like image 811
user7104874 Avatar asked Dec 22 '16 10:12

user7104874


2 Answers

TL;DR

You can use:

exports.x = 1;
exports.y = 2;
exports.z = 3;

as a shorter way of writing:

module.exports.x = 1;
module.exports.y = 2;
module.exports.z = 3;

The only advantage is less typing.

But you have to write:

module.exports = {
    x: 1,
    y: 2,
    z: 3
};

as this will not work:

exports = {
    x: 1,
    y: 2,
    z: 3
};

because it wouldn't change the module.exports and it's module.exports that actually gets exported.

Explanation

Your module gets wrapped in an implicit closure that gets some variables passed as parameters. One of those variables is called exports that is an empty object and another one is called module and it includes exports as one of its properties:

module.exports === exports

When you write:

exports.x = 10;

then you change the property of the provided object (the object is still the same object, but it is mutated) and everything is fine. The value x is available as both exports.x and module.exports.x.

But if you write:

exports = {x: 10};

then you assign a new object to exports while the module.exports is still pointing to the original (empty) object. That way you have exports.x set correctly but you don't have module.exports.x set as well, because now:

module.exports !== exports

If you want to make a new object instead of using the empty one that you got in exports then you have to assign it to module.exports:

module.exports = {x: 10};

Now module.exports and exports are different as well:

module.exports !== exports

But it's module.exports that's actually exported so everything is fine.

After assigning a new object to module.exports you could assign it to exports as well:

module.exports = {x: 10};
exports = module.exports;

or do it the other way around:

exports = {x: 10};
module.exports = exports;

so you could still use the shortcut of assigning new properties with:

exports.y = 20;

but I haven't seen that in practice.

Real examples

Exporting some functions (public) but not others (private). Let's say you have those functions:

function private1() {
    // ...
}
function private2() {
    // ...
}
function public1() {
    // ...
}
function public2() {
    // ...
}

You have few options to export two public functions:

This works

module.exports.public1 = public1;
module.exports.public2 = public2;

or:

exports.public1 = public1;
exports.public2 = public2;

or:

module.exports = {
    public1: public1,
    public2: public2
};

or:

module.exports = {
    public1,
    public2
};

This doesn't work

exports = {
    public1: public1,
    public2: public2
};

or:

exports = {
    public1,
    public2
};

Summary

In other words, exports is just for convenience so that you don't have to write module.exports every time, but it doesn't work for cases when you want to export a different object than the one provided to you originally. In that case you need to set the module.exports to that new object.

See also

See also this answer:

  • What is the difference between module.export and export
like image 161
rsp Avatar answered Sep 30 '22 16:09

rsp


module is a plain JavaScript object with an exports property. exports is a plain JavaScript variable that happens to be set to module.exports. At the end of your file, node.js will basically 'return' module.exports to the require function. A simplified way to view a JS file in Node could be this:

// your code
var module = { exports: {} };
var exports = module.exports;

return module.exports;

If you set a property on exports, like exports.a = 9;, that will set module.exports.a as well because objects are passed around as references in JavaScript, which means that if you set multiple variables to the same object, they are all the same object; so then exports and module.exports are the same object. But if you set exports to something new, it will no longer be set to module.exports, so exports and module.exports are no longer the same object.

like image 44
Darshan Jadiye Avatar answered Sep 30 '22 18:09

Darshan Jadiye