7 Answers
7

While node.js does allow circular require dependencies, as you've found it can be pretty messy and you're probably better off restructuring your code to not need it. Maybe create a third class that uses the other two to accomplish what you need.

+1 This is the right answer. Circular dependencies are code smell. If A and B are always used together they are effectively a single module, so merge them. Or find a way of breaking the dependency; maybe its a composite pattern.
–
JamesSep 30 '14 at 11:39

3

Not always. in database models, for example, if I have model A and B, in model A I may want to reference model B (e.g. to join operations), and vice-versa. Therefore, export several A and B properties (the ones that does not depend on other modules) before use the "require" function may be a better answer.
–
JoaobrunoahJan 26 at 18:38

Try to set properties on module.exports, instead of replacing it completely. E.g., module.exports.instance = new ClassA() in a.js, module.exports.ClassB = ClassB in b.js. When you make circular module dependencies, the requiring module will get a reference to an incomplete module.exports from the required module, which you can add other properties latter on, but when you set the entire module.exports, you actually create a new object which the requiring module has no way to access.

This might be all true, but I would say still avoid circular dependencies. Making special arrangements to deal with modules that have incompletely loaded sounds like it will create a future problem you don't want to have. This answer prescribes a solution to how to deal with incompletely loaded modules...I don't think that's a good idea.
–
Alex MillsJun 1 at 19:05

Sometimes it is really artificial to introduce a third class (as JohnnyHK advises), so in addition to Ianzz:
If you do want to replace the module.exports, for example if you're creating a class (like the b.js file in the above example), this is possible as well, just make sure that in the file that is starting the circular require, the 'module.exports = ...' statement happens before the require statement.

I know I'm digging up an old answer here...
The issue here is that module.exports is defined after you require ClassB.
(which JohnnyHK's link shows)
Circular dependencies work great in Node, they're just defined synchronously.
When used properly, they actually solve a lot of common node issues (like accessing express.js app from other files)

Just make sure your necessary exports are defined before you require a file with a circular dependency.