Recently I wrote a dependency injection container for node. DAGon (npm wont let you use caps so dagon). It worked quite nicely and I really liked using it in my app. However, node people have stated at every turn that such a thing is anathema.
The reason they say is because you should write small modules that do one thing SRP. Well this was a bit confusing for me. You see each file that you write in node exports a value, either a function or an object and is called a module. And in my rather large application, each of those files did just one thing. They were in fact modules that were SRP. This didn’t help me with the fact that I needed to reference modules everywhere using relative paths. And that those modules needed to be configured and so on. The case for a container that handles all that seemed stronger and stronger.
However, if you hit me in the head enough times, at the right angle, I sometimes learn something. It seems that the word module is kind of overloaded. Yes your file is a module, but I think what people are referring to is a module which is in it’s own repository, with it’s own package.json and index.js ( or starting file ). This module is still small and SRP so the relative paths are right next door. Usually in the same folder.
Now you require your truly autonomous modules in your top level app. The small pieces are easier to test because by necessity, they are not entwined with other parts of the app. The top level app acts sort of like a controller that orchestrates these other pieces.
Well I decided to bend to the pressure and my new understanding and I rewrote my app using this pattern. I’ll summarize that process as follows: The refactor was pretty easy. Fixing 7 million tests, not so much. Tests tend to be tied to the implementation at least at a very low level, and as the implementation had fundamentally changed all my tests were pooched. Still it felt kind of good to have these highly discrete modules.
In my next post I’ll talk about the difference between building the app, in this manner versus building it with a DI Container.