In a modular programming world, we have component-based software design, modular programming, etc.
There are a planty of articles talking about the benifits we can get from the good component design, I'm not going to talk in here.
When we do modular design, just as we have already done in programming world decades, there is an enemy in our world: dependency hell.
You should heard of 'DLL Hell'. A common cause is that apps shares libraries in the same location, so once there are two app depended on the same library with different versions, the former one breaks.
To avoid that, programmers add versions to their libs and many package systems now don't store only one file in the shares folder, they add versions.
Or another solution is: instead of using shared lib path, using different lib path for each project, like using LD_LIBRARY_PATH, CLASS_PATH.
Now we have versions, but developers are lazy, people don't like to update their code every time one dependency update, but people want to enjoy the benefits of bug fixes, and in some cases, update your own file helps nothing:
To make people get auto update for a bug fix, many package managers introduce version range, includes npm, rubygem, maven, etc.
Great, now if a lib my project depends on get a bug fix, I just do a simple upgrade or reinstall via
mvn install, I get bug fixed without any code change.
Great! We are now don't worried some one overwrite my libs! Are we in a safe world? NO.
Let us take a look at following story:
Your great project depended on X(1.0.0) and Y, Y also depended on X (1.0.0). Things works fine now, someday, X get upgraded to 1.1.0; it provides a wonderfull feature you have! But, you can not use it, until Y get upgraded.
What about there are complex dependency tree here.
So people have no choice to re-build the wheel. Wheels can not match each other. I see no package system get ride of that except node/npm.
Let see how node get ride of dependency hell in next article.