ZHONGJIAFENG
ZHONGJIAFENG

Reputation: 53

What is the difference between module.export and export

What is the difference between module.export and export

What if there are some attributes in module.export object? Will export.xx be invalid then ?

Upvotes: 2

Views: 2897

Answers (4)

msahin
msahin

Reputation: 1770

This example will explain all:

//page2.js

 exports = () => { console.log("Foo") };
 module.exports = () => { console.log("Bar") };

//app.js

  const myFunc = require("./page2");
  myFunc();    //output : Bar

Upvotes: 0

Emad Dehnavi
Emad Dehnavi

Reputation: 3451

the module.exports is actually what the require function return, when you pass the path of your script to require function , your codes will wrap and run in a function expression which have a parameter named exports which is an empty object and then module.exports will pass to it. generally it's a shorthand to module.exports and in other words, it's two variables pointing at same object in memory, so it seems similar, right?

but actually there is a difference, exports act different in some patterns, lets give u an example about these kind of patterns, lets say we have a script named tada.js :

exports = function(){
    console.log('Tada');
}

console.log(exports);
console.log(module.exports);

if I require this script in my app.js :

var tada = require('./tada');

then what do you expect to see?

well, this is going to be the output:

console.log(exports); // [Function]
console.log(module.exports); // {}

it show exports as a function and module.exports as an empty object. but, as I told you, these two are just two variables pointing at same object in memory, passed by reference, so are they not suppose to have same value? well, maybe in any other language, it will act like that, but in JavaScript things are a little different.

In JavaScript if we use = to assign a value, it actually make a new object in memory, so in other words, in our example, that reference between exports and module.exports will broken, that mean exports and module.exports originally point to same object in memory, but when we did this :

exports = function(){
    console.log('Tada');
}

that reference broken and now exports is point to a new object in memory.

also remember that require function only return module.exports, not exports so that's why we got empty object for module.exports in our example and since reference broken, module.exports , exports are no longer pointing to same object.

To fix this, u need to mutate instead of overwrite. so if we change our example to this, then both exports and module.exports will have same value :

exports.tada = function(){
    console.log('Tada');
}

console.log(exports);
console.log(module.exports);

Upvotes: 0

karthick
karthick

Reputation: 6178

Module is object and exports is a property(variable) of module object.

const module = { 
   //property
   exports: {} 
}; 

exports is shortcut for module.exports until it is assigned with new object

  1. exports === module.exports

    module.exports.hello = true;
    exports.hello = true; 
    
  2. exports !== module.exports

    module.exports.hello = true;
    exports = { hello: true };
    

    exports property is completely replaced by new object.

Reference

function require(/* ... */) {
   const module = { exports: {} };
   ((module, exports) => {
      // Your module code here. In this example, define a function.
      function someFunc() {}
      exports = someFunc;
      // At this point, exports is no longer a shortcut to 
      // module.exports, and
      // this module will still export an empty default object.
      module.exports = someFunc;
      // At this point, the module will now export someFunc, instead of 
      //the default object.
    })(module, module.exports);
   return module.exports;
 }

Upvotes: 3

rsp
rsp

Reputation: 111506

First of all it's exports and module.exports and not export and module.export (there is also an export keyword in JavaScript but it is not supported in Node yet).

Every Node module is wrapped with this function:

(function (exports, require, module, __filename, __dirname) {
  // Your module code actually lives in here
});

See: https://nodejs.org/api/modules.html#modules_the_module_wrapper

Your module doesn't return the exported object from that functions as some people think. It can only pass data to the caller by adding properties to the arguments provided.

module.exports and exports are initially the same object - but it is module.exports that is actually exported if they end up to be not the same object.

It means that this will work the same:

module.exports.x = 1;
# or:
exports.x = 1;

because it changes the property of the same object.

But this will not be the same:

module.exports = {x: 1};

as this:

exports = {x: 1};

The last one will not export the x because it will substitute the object in exports (that was originally the same object as module.exports) while leaving the default empty object in module.exports to be actually exported.

The module.exports = {x: 1}; also substitutes a new object but it puts it where it needs to be to actually get exported. Note that this instruction changes the property of the module object, which can be seen by the caller after the implicit function that your module is wrapped in returns.

Now this would work:

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

because it substitutes the object in exports with a new one but it also puts it into module.exports.

Remember that it is always module.exports that matters at the end if you didn't substitute one of them with a new object then you can use them interchangeably when setting their attributes:

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

For more info see this answer:

Upvotes: 7

Related Questions