Circular Dependencies in Node
It’s inevitable: you will have circular dependencies at some point in your project.
Unfortunately, I’ve had this issue time & time again and didn’t quite realize why it was happening until recently.
The Problem
When a file is
require
d in Node, itsmodule.exports
is immediately defined as an empty{}
.
Most of my code was written like so, where I exported my object at the end of the file:
// my-factory.js
var factoryFeatures = require('./features');
var MyFactory = function(deps) {
...
};
MyFactory.prototype.build = function(specs) {
...
// Create something from the provided specs using
// the required `factoryFeatures`.
...
};
module.exports = MyFactory;
The moment one of my dependencies (say, via line #2
) attempted to
require('../my-factory')
, it would get a reference to that empty {}
.
But, everything goes off the rails during runtime because, on line number #15
,
I’ve overridden {}
with MyFactory
!
The Solution
Add methods/factories onto the initial {}
, so references are never overwritten:
// my-factory.js
...
// Notice how the function is exported as an additional {} property
module.exports.factory = MyFactory;
This way, at runtime, factory
is available via the original module.exports
reference.
Now all circular dependencies are referencing the same object from the first
require
to the last!