NodeJS - module.exports vs exports
I read an article on the difference between module.exports
and exports
in NodeJS and thought I could contribute to the discussion.
The key difference between the two is that module.exports
is what matters, and exports
just happens to point to the same thing.
It might help clarify things to show how the two variables are initialized. Essentially before your code runs, there is code that runs like this:
var module = {…}; // other module stuff
var exports = module.exports = {};
So both variables initially point to the same empty Object, but of course can be reassigned to any other value instead. If you reassign the exports
variable, it doesn’t affect module.exports
. Similarly, if you reassign module.exports
, it no longer affects exports
. They will be pointing at different values.
It's important to note the distinction between variables and values. module.exports
and exports
are just variables that start out pointing to the same value. If you modify the value they both point to, for example if that value is an object and you set properties on it, then both of those variables are both affected. But if you point one of those variables at a different value, then modifying the value of one will no longer change the other.
What makes module.exports
the “real deal” is that when someone require()
s your module, require
executes something like this:
function require(moduleName) {
var module = getModule(moduleName);
return module.exports;
}
require
grabs the module and finds the exports property of it. So the values that matter are first whatever value module
points to, and then whatever value the exports
property on it points to.
It might also help to say that module
is the real deal, not that module.exports
is. Take this code for example:
var truth = module;
var notExports = module.exports;
truth.exports = { genre: "Rock" };
notExports.genre = "Blues";
Rock
will be exported. Since truth
is pointing to module
, it can make lasting changes to the exports that notExports
can’t. As soon as truth
changes the value of module
's exports
property, the old value that notExports
still points to is moot.