4 ms·
I am curious why go doesn't just vendor dependencies like npm does when confronted with conflicting requirements instead of trying to figure out a version that
by j_bond 9y ago
I am curious why go doesn't just vendor dependencies like npm does when confronted with conflicting requirements instead of trying to figure out a version that satisfies all worlds? I always found this to be a nice feature when working with npm.
I am also firm believer in version-pinning/lockfiles. Updating versions should be a separate workflow with first-class built-in tools to support it. I think that is the area where most package managers fall flat. They basically rely on the developer to do all the heavy lifting.
- TheDong 9y agonodejs's "require", which pulls different versions depending on which module calls it, is a cool trick. Unfortunately, it also has a downside, and in go that downside would be noticeable. Let's take one easy example: a logging library. Let's say I pull in "logrus v1.0.1" and one of my dependencies pulls in "logrus v1.0.2". In my "main" function, I set logrus's default loglevel to debug (logrus.SetLevel(logrus.DebugLevel)). If go did the thing nodejs does (a different copy of logrus for my dependency than my main), the "logrus.SetLevel" would only affect my package, not any of my dependencies; they'd still log at a default level. This would be true of other things; "func init" code would run once per dependency that had that library, not just once, maps wouldn't be shared, pools, etc. This is a lot more memory usage, but it's also really surprising, especially in the case of logging. I definitely prefer having only one copy of a library in memory and having package-level variables (like loglevel) work as expected. If that ends up failing and I need two different versions, vendor+import-path rewriting allows an escape hatch These days, npm actually tries to minimize and flatten dependency versions as much as possible to avoid the huge memory tax.