Deep dependencies (npm style) are great when (1) you are relatively memory/bandwidth unconstrained, and (2) your programming style is purely functional. (1) is pretty obvious, so I want to elaborate on (2):
With an object-oriented programming style, you are often passing around instances of your class.
var widget = new Widget
widget.groupWith(otherWidget)
You clearly don't want widget
to interact with slightly different versions of itself through otherWidget
. (Trying to do so would require that we are extremely disciplined with what the Widget::groupWith
method calls on otherWidget
.) Asking for this to work is, in my opinion, a fundamentally bad idea from an architectural point of view. Ideally, it should not be possible for two versions of the Widget
class to exist in the same app. Bundler on Ruby enforces this, and it's awesome.
So npm's (current) way of resolving dependencies makes object-oriented code hard and functional code easy. This works OK on the server side, but I suspect it becomes a bigger problem in the browser, where we need a lot of long-lived state that is quite naturally expressed as objects. All the JS UI code on the web I've written has been heavily object-oriented.
As an aisde, the problem I sketch out above surfaces in code like this:
// Can't do this because Widget might be a different version from a different module
//if (widget instanceof Widget)
// So let's resort to this:
if (widget.constructor.name === 'Widget') {
// Now cross fingers that widget's class is not too different from the version we expect...
widget.doStuff() // hopefully widget has this method and behaves as expected
}
Continue discussion on Twitter please, Gist comments are cumbersome :)