So, what I'm not sure is that. if in ModuleA, I have:
var mongoose = require('mongoose');
mongoose.connect(pathA);
And in ModuleB, I have:
var mongoose = require('mongoose');
mongoose.connect(pathB);
And in the main program, I have:
var mA = require('./moduleA.js'),
mB = require('./moduleB.js');
So, when I run the main program, I guess I will create two mongoose "instances"; one connecting to pathA and one connecting to pathB, is that right?
Also, in Module B, before I connect to pathB, is it connected to pathA or nothing?
Thanks.
I just did a couple of tests with the latest node V0.4.6. I confirmed the following:
- The variable returned from "require" is a singleton.
- Subsequent changes will change the data of the required module among all other modules that include it.
- Mongoose's connection is a bit weird. Even if you disconnect and set it to a new connection path, it still uses the old connection path.
So, what I mean by the above points 1 and 2 is:
If you have a Module Master:
var myStr = 'ABC';
module.exports.appendStr = function(data) {
myStr += ' ' + data;
};
module.exports.output = function() {
console.log("Output: " + myStr);
};
And if you have two other modules:
Module A
var mc = require('./moduleMaster.js');
var ma = function() {mc.appendStr(' MA '); };
ma.prototype.output = function() {
mc.output();
}
module.exports.create = function() {
return new ma();
};
module.exports._class = ma;
Module B
var mc = require('./moduleMaster.js');
var mb = function() {mc.appendStr(' MB '); };
ma.prototype.output = function() {
mc.output();
}
module.exports.create = function() {
return new mb();
};
module.exports._class = mb;
Now when you run a test script that requires both Module A and Module B, instantiate them and output:
mTestA.output();
mTestB.output();
You will get the following output:
ABC MA
ABC MA MB
instead of
ABC MA
ABC MB
Therefore, it is a singleton. not just local to the module.
I came across this post, and while the accepted answer shows it is a Singleton, my response to the original question "In Node.js, am I creating a new object when “Require”?" is "it depends".
murvinlai 's answer/logic still holds true through the latest versions of Node ( v0.10.18 as of this writing ), but that's if you have your required file setup that way. For instance, and I'm trying to use a more verbose example to avoid any confusion, if you had the following "User" code in User.js ( structured different than murvinlai 's answer )
/**
* User Model
*/
function modelUser() {
var User = {
/**
* User::_id
*
* @var integer
*/
"_id" : null,
/**
* Set id
*
* @param integer id
* @return User
*/
"setId" : function(id)
{
User._id = id;
return User;
},
/**
* Get id
*
* @return integer
*/
"getId" : function()
{
return User._id;
},
}
return User;
}
exports.modelUser = modelUser;
Now if you took the above code, you may find that in many cases with no modification you would not have the Singleton issue. IE with:
var user1 = require("./application/models/User.js").modelUser(); // In one module
var user2 = require("./application/models/User.js").modelUser(); // In another module
user1.setId(1);
console.log(user1.getId());
console.log(user2.getId());
You would get 1, null. Additionally, and I'm not even sure you would need this, but you could use the new operator on the require ( since it's essentially just returning a function ). IE with:
var user1 = new require("./application/models/User.js").modelUser(); // In one module
var user2 = new require("./application/models/User.js").modelUser(); // In another module
user1.setId(1);
console.log(user1.getId());
console.log(user2.getId());
And you would get the same output.
Again, the original question was a bit broad ( ant the issues may have ultimately been with mongoose ( as mentioned in #3 of murvinlai 's response ), but the above is an example of another way of doing things to yield an actual new object off each of the require()'s. Now you may want to think before doing this as there are times where you will want the Singleton ( say to store cached values in a ORM/Mapper ), but in closing are you creating a new object, it depends..