3 ms·
Coming from node world, global dependencies like in java and python are a total deal breaker. In node same library in two different versions can coexist in dif
by furstenheim 6y ago
Coming from node world, global dependencies like in java and python are a total deal breaker.
In node same library in two different versions can coexist in different parts of the dependency tree and that's totally fine (there are some small exceptions). You give up some space but the gains are incredible.
In contrast, in Java I've got runtime errors because a library down the tree was importing some other library with the same package name.
- raverbashing 6y agoYeah it's not a "deal breaker" but I agree it's pretty annoying. Venvs in python kinda soften the blow on a global dependency level, but it could happen your project needs two conflicting dependencies
- furstenheim 6y agoYeah, maybe "deal breaker" is to strong. But I've had consumers of a library not being able to use it because a critical dependency (html parser) was not the same version as they had
- usui 6y agoThis is one thing that I have always wondered about. Lots of app-development frameworks insist and die by the practice that is trying to be smart about common dependencies or global dependencies like Ruby gems/Bundler. In all of my experience, running "npm install" has always been a much easier affair than bundle install. The amount of time saved by npm's dumber approach has added much greater value than the hard disk space saved. I'm trying to see what I'm missing about the two dependency packaging philosophies, but in practice npm is by far the best experience for a dev on the frontlines. Is it just hard drive space that is the problem?
- furstenheim 6y agoTotally, and if you mix it with yarns plug and play you should get best of both worlds
- bremac 6y agoIn the case of Ruby, it's not really trying to be smart. Ruby loads everything into a single namespace, so loading multiple versions of the same dependency could cause classes, modules, etc. from version 1.1 to overwrite those already loaded by version 1.0. The dependency manager is constrained by the language. The same is true of most languages that I'm aware of, though Java can load multiple versions of the same class. The biggest problem caused by using multiple versions of the same library is that object representations are not stable across versions. Let's say you use a library "foo" that creates and manipulates Foo objects. You want to serialize them to JSON, so you use the third-party library "foo-json". If you have foo@2.1.0 and foo-json depends on foo@1.9.7 then foo-serializers will likely fail to serialize the Foo objects created by your application. This is why npm supports peer dependency constraints, though usually they're invisible to you as a user. There are also performance and cost issues associated with using multiple versions of each library: 1. Starting the application requires loading many of those library versions, so you will have higher start-up latency than if you only had one copy of each library. 2. If the target platform uses method-based JIT compilation (e.g. Java), each of those libraries will be compiled independently when it is used. This can cause the application to feel sluggish between the time it initially starts up and the time that all of the copies of the libraries on the hot path have been compiled. 3. The program needs to be loaded into memory to execute it. You're not only paying for more hard disk space, but also more RAM. The additional memory required can start to add up if you're running enough replicas of the application in production. For many small applications the performance and cost issues aren't major concerns, but they can become problematic as the application grows.