▲ | crote 4 days ago | |
> They would be resolved by just picking the version 'closest to root', as explained in the article. Which is going to lead to horrible issues when that library isn't compatible with all your other dependencies. What if your app directly depends on both L1 and L2, but L1 is compatible with L3 1.2 ... 1.5 while L2 is compatible with L3 1.4 ... 1.7? A general "stick to latest" policy would have L1: "L3==1.5", L2: "L3==1.7" (which breaks L1 if L2 wins). A general "stick to oldest compatible" policy would have L1: "L3==1.2", L2: "L3==1.4" (which breaks L2 if L1 wins). The obvious solution would be to use L3 1.4 ... 1.5 - but that will never happen without the app developer manually inspecting the transitive dependencies and hardcoding the solution - in essence reinventing the lock file. > It is, the app developers can just put in a direct dependency on the fixed version of L2. As mentioned earlier, this is the version that will be resolved for the project. And how is that going to work out in practice? Is that direct dependency supposed to sit in your root-level spec file forever? Will there be a special section for all the "I don't really care about this, but we need to manually override it for now" dependencies? Are you going to have to manually specify and bump it until the end of time because you are at risk of your tooling pulling in the vulnerable version? Is there going to be tooling which automatically inspects your dependencies and tells you when it is safe to drop? > This is the same even if you use a lockfile system. When you update dependencies you are explicitly updating the lockfile as well, so a bunch of transitive dependencies can change. The difference is that in the lockfile world any changes to transitive dependencies are well-reasoned. If every package specifies a compatibility range for its dependencies, the dependency management system can be reasonably sure that any successful resolution will not lead to issues and that you are getting the newest package versions possible. With a "closest-to-root" approach, all bets are off. A seemingly-trivial change in your direct dependencies can lead to a transitive dependency completely breaking your entire application, or to a horribly outdated library getting pulled in. Moreover, you might not even be aware that this is happening. After all, if you were keeping track of the specific versions of every single transitive dependency, you'd essentially be storing a lockfile - and that's what you were trying to avoid... |