Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can node modules require each other

I'm having the following 3 files.

user.js requires room.js and room.js requires user.js.

user.js

var Room = require('./room.js');  var User = function () {}; User.prototype.test = function () {   return new Room(); };  module.exports = User; 

room.js

var User = require('./user.js');  var Room = function () {}; Room.prototype.test = function () {   return new User(); };  module.exports = Room; 

index.js

var User = require('./user.js'); var Room = require('./room.js');  var user = new User(); var room = new Room();  user.test(); room.test(); 

index.js requires both room and user.

Here's the problem. When I run index.js, I will get a TypeError from 'new User()' in room.js. It seems that User in room.js is hidden by the User in index.js.

Am I doing anything wrong? Is this kind of requiring allowed? Any ideas? Thanks.

like image 898
Ziyu Avatar asked Apr 28 '14 13:04

Ziyu


People also ask

Can you use require in a module?

“Require” is built-in with NodeJS require is typically used with NodeJS to read and execute CommonJS modules. These modules can be either built-in modules like http or custom-written modules. With require , you can include them in your JavaScript files and use their functions and variables.

CAN node modules be shared?

Option 1: Link to a Local Project Folder Once you've moved your shared code into a separate project, link the project as a dependency using npm link. Note: The shared library can be maintained in a separate repository or the same repository as your other projects (a.k.a, monorepo).

Why do you need separate modules in NodeJS?

Each module in Node. js has its own context, so it cannot interfere with other modules or pollute global scope. Also, each module can be placed in a separate . js file under a separate folder.

Is node modules required in production?

No, You don't need to push your node_modules folder to production whether it is a static export or dynamic build. When you export a static build the source file is converted into HTML & js files. So there is no need for node modules on production env.


2 Answers

Check out http://nodejs.org/api/modules.html#modules_cycles for how this is handled in node.

You can solve your problem in several ways, for example passing in the dependencies to the instances aka Dependency Injection

// user.js var User = function (Room) { this.Room = Room; }; User.prototype.test = function () {   return new this.Room(); }; module.exports = User;  // room.js var Room = function (User) { this.User = User; }; Room.prototype.test = function () {   return new this.User(); }; module.exports = Room;  // index.js var User = require('./user.js'); var Room = require('./room.js');  var user = new User(Room); var room = new Room(User); 

Another way would be to require the files only when you need them

// user.js var User = function () {}; User.prototype.test = function () {   var Room = require('./room');   return new Room(); }; module.exports = User;   // room.js var Room = function () {}; Room.prototype.test = function () {   var User = require('./user');   return new User(); }; module.exports = Room;  // index.js var User = require('./user.js'); var Room = require('./room.js');  var user = new User(); var room = new Room(); 

Like this, your exports are defined by the time you need them.

But generally, if you have circular dependencies, you are doing something wrong and should think about your architecture. If a User needs to create new Rooms and a Room needs to create new Users, it seems like they both have too much responsibility. Possibly you would want a third component which is responsible for creating and passing the right instances to the Room and User, instead of having them instantiate those directly.

like image 127
Tim Avatar answered Sep 21 '22 04:09

Tim


I think there is much better way how to do it. Just switch export and require like this:

user.js

var User = function () {}; module.exports = User;      User.prototype.test = function () {     return new Room(); };  var Room = require('./room.js'); 

room.js

var Room = function () {}; module.exports = Room;      Room.prototype.test = function () {   return new User(); };  var User = require('./user.js'); 

index.js

var User = require('./user.js'); var Room = require('./room.js');  var user = new User(); var room = new Room();  user.test(); room.test(); 

check this article: https://coderwall.com/p/myzvmg/circular-dependencies-in-node-js

like image 30
balicekt Avatar answered Sep 25 '22 04:09

balicekt