Node.js: exports vs module.exports
What is the difference between exports and module.exports in Node.js?#
Let's first take a look at what the module
object is all about. Create a file named run.js
with the following content.
console.log(module);
Then execute the file using node
. You should see an output which looks something like this:
$ node run.js
Module {
id: '.',
exports: {},
parent: null,
filename: '/Users/yaapa/projects/hacksparrow.com/run.js',
loaded: false,
children: [],
paths:
[ '/Users/yaapa/projects/hacksparrow.com/node_modules',
'/Users/yaapa/projects/node_modules',
'/Users/yaapa/node_modules',
'/Users/node_modules',
'/node_modules' ] }
So it looks like module
is a contextual reference to the file you just executed.
Did you notice it has an exports
property? Which is an empty object. That's where you define the 'importable' objects of your module.
Now edit run.js
and run it again:
exports.a = 'A';
exports.b = 'B';
$ node run.js
Module {
id: '.',
exports: { a: 'A', b: 'B' },
...
You can see that assigning properties to the exports
object has added those properties to modules.exports
.
That is because exports
is a reference to modules.exports
.
You can confirm it with the following code:
exports.a = 'A';
console.log(exports === module.exports);
console.log(module.exports);
$ node run.js
true
{ a: 'A' }
So, assing properties to the exports
object is a neat shortcut if you want to export an object from your module:
Using module.exports
:
module.exports = {
greet: function (name) {
console.log(`Hi ${name}!`);
},
farewell: function() {
console.log('Bye!');
}
}
Using exports
:
exports.greet = function (name) {
console.log(`Hi ${name}!`);
}
exports.farewell = function() {
console.log('Bye!');
}
Defining the properties on exports
certainly looks better than defining them on an object assigned to module.exports
.
Do you like surprises?
You have no choice - exports
is not a reference to modules.exports
all the time!
If you assign anything to module.exports
, exports
is not no longer a reference to it, and exports
loses all its power.
module.exports = {a: 'A'};
exports.b = 'B';
console.log(exports === module.exports);
console.log(module)
$ node run.js
false
Module {
id: '.',
exports: { a: 'A' },
...
So, now you know, exports
is shortcut for referencing module.exports
, if your module is to export an object. It is a pretty much usless object if your module exports any other data type or you have assigned anything to module.exports
.
References#
- Node.js - module object
- Node.js - module.exports