Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding exports in NodeJS

Tags:

node.js

I don't think I quite understand how exports work in Node.js. In a bit of sample code, I noticed the exports object used in this manner:

exports = mongoose = require('mongoose')
mongoose.connect(config.db.uri)
exports = Schema = mongoose.Schema

What is happening behind the scenes when you use exports = twice like that? Looks to me like "mongoose" should not be exported. I did this quick test:

var foo
  , bar

exports = foo = 'foo'
exports = bar = 'bar'

// reports 'bar' only
console.log(exports)

and the second test does overwrite the first export.

like image 779
typeoneerror Avatar asked Mar 09 '12 00:03

typeoneerror


2 Answers

My guess is the original author of that sample code is confused about module.exports vs exports. To use the exports object, you must add properties to it like this:

exports.size = 42;

If you re-assign the exports variable to a new object, you basically lose access to the global exports object that node.js provided for you. If you do this twice or three or N times, the effect is the same. It's useless. For example: mod_b.js

var realExports = exports;
realExports.height = 42;
var exports = {};
exports.weight = 43;

And in mod_a.js

var mod_b = require('./mod_b');
console.dir(mod_b);

Run node mod_a.js and you get:

{ height: 42 }

Notice height is there but weight is not. Now, what you can do is assign module.exports to be an object, and that is the object that will be returned when another module requires your module. So you will see things like.

var x = 10;
var y = 20;
module.exports = {x: x, y: y};

Which will do what you expect. Here's some informative articles on the details.

Node.js Module – exports vs module.exports

What is the purpose of NodeJS module.exports and how do you use it?

Mastering Node

like image 139
Peter Lyons Avatar answered Nov 15 '22 03:11

Peter Lyons


As an extension to @Peter-Lyons answer, your example is valid, your test case is incorrect.

Exporting variables like this is not recommended, but by doing that, you are exposing this variables into a global namespace.

e.g. test0.js

'use strict';

var assert = require('assert');
var test1 = require('./test1');

assert(globalVar1 === 123);
assert(globalVar2.a === 123);

test1.js -- mind the missing 'use strict';

exports = globalVar1 = 123;
exports = globalVar2 = {a:123};

Once again, it's valid, but not recommended.

Cheers.

like image 27
Evan P Avatar answered Nov 15 '22 05:11

Evan P