Reputation: 53
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
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
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
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
module.exports.hello = true;
exports.hello = true;
module.exports.hello = true;
exports = { hello: true };
exports property is completely replaced by new object.
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
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