Node.js Module – exports vs module.exports
What is the difference between exports and module.exports in Node.js?
You must be familiar with the exports
object in Node.js modules, using which you create functions in your modules like this (assume in a file named rocker.js):
exports.name = function() {
console.log('My name is Lemmy Kilmister');
};
which you call from another file thus:
var rocker = require('./rocker.js');
rocker.name(); // 'My name is Lemmy Kilmister'
But what the heck is module.exports
? Is it even legal?
Here is an eye-opener - module.exports
is the real deal. exports
is just module.exports
's little helper. Your module returns module.exports
to the caller ultimately, not exports
. All exports
does is collect properties and attach them to module.exports
IF module.exports
doesn't have something on it already. If there's something attached to module.exports
already, everything on exports
is ignored.
Put the following in rocker.js:
module.exports = 'ROCK IT!';
exports.name = function() {
console.log('My name is Lemmy Kilmister');
};
And this in another file, and run it:
var rocker = require('./rocker.js');
rocker.name(); // TypeError: Object ROCK IT! has no method 'name'
The rocker module completely ignored exports.name
, and returned a string 'ROCK IT!'. From that you probably realize that your modules don't always have to be 'module instances'. Your modules can be any legal JavaScript object - boolean, number, date, JSON, string, function, array, and so on. Your module is whatever you set module.exports
to. If you don't set module.exports
to anything explicitly, the properties of exports
and attached to it and returned.
In this case, your module is a class:
module.exports = function(name, age) {
this.name = name;
this.age = age;
this.about = function() {
console.log(this.name +' is '+ this.age +' years old');
};
};
and you'd use it this way:
var Rocker = require('./rocker.js');
var r = new Rocker('Ozzy', 62);
r.about(); // Ozzy is 62 years old
In this case, your module is an array:
module.exports = ['Lemmy Kilmister', 'Ozzy Osbourne', 'Ronnie James Dio', 'Steven Tyler', 'Mick Jagger'];
and you may use it this way:
var rocker = require('./rocker.js');
console.log('Rockin in heaven: ' + rocker[2]); //Rockin in heaven: Ronnie James Dio
So you get the point now - if you want your module to be of a specific object type, use module.exports
; if you want your module to be a typical module instance
, use exports
.
The result of attaching properties to module.exports
is akin to attaching properties to exports
. For example this:
module.exports.name = function() {
console.log('My name is Lemmy Kilmister');
};
does the same thing as:
exports.name = function() {
console.log('My name is Lemmy Kilmister');
};
But note that, they are not the same thing. As I said earlier module.exports
is the real deal, exports
is just its little helper. Having said that, exports
is the recommended object unless you are planning to change the object type of your module from the traditional 'module instance' to something else.
I hope this post helped you understand the difference between exports
and module.exports
, and learn a bit more about how modules work in Node.js. Any questions, ping me in the comments.
As long are you don't overwrite the module.exports
object with an assignment operation, anything attached to module.exports
and exports
will be available in the 'required' module.
If this is the content of your module:
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
The following code would work fine:
var rocker = require('./rocker.js');
console.log('%s is %s', rocker.name, rocker.age); // Lemmy Kilmister is 68
BUT
if you overwrite module.exports
with anything in your module, it will fail:
module.exports = 'LOL';
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
or
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
module.exports = 'WTF';
the order doesn't matter, rocker.age
and rocker.name
will now be undefined
.
Also, note: just because module.exports.age
and exports.name
are exported, does not mean you should use a combination of both. My recommendation is to stick to exports.*
, and be aware of module.exports.*
.
How about returning an array from a module? I am performing a query on a MongoDB to get a list of users based on a group id. That list is then stored in an array which I would like to pass back to the callers of the module.
Very nice explanation good tutorial helped me lot thanks bro
Hi,
I created a file global_var.js as below:
module.exports = {
some_obj : {}
};
I am updating some_obj values frequently in another files by the below process:
var globalVar = require(‘./global_var.js’);
globalVar.some_obj[“some_key”]=”some value”;
but sometime it in not updating or overwrite previous values.
For this purpose which is the better way for global variables/objects in between exports & module-exports ?
Glad I ended up here with beautiful explanation after all those hassles i made trying to figure out what they are and makes difference between those two. Thanks!
Thanks for the explanation which make it quite helpful to understand the differences.
Very helpful tutorial