1. 18

  2. 3

    Coming from npm, and knowing little about Go’s packaging or import system, it took a significant amount of time reading this article to understand two properties npm/Node has that seem to help alleviate the problems Go is grappling with:

    1. npm has a strong semantic versioning culture. Very strong. Packages that don’t respect semver (at least packages that aren’t rando code from someone inexperienced) are in the tens and easy to lock down. That helps a lot to guide upgrade decisions.
    2. Far more importantly, Node’s import machinery doesn’t have any global notion of a package. Meaning, A and B can depend on different, incompatible versions of C and everything is fine because their dependence on C is really an implementation detail that’s hidden from the global system.

    Of course there are valid criticisms of both of these, some that I’m sure I’m not aware of (the author of this article is clearly more of a problem domain expert than I am) but they clearly solve a lot of problems too. The behavior of a solver in npm is a non-issue because there’s no version conflicts to solve, so you just don’t need one in the first place.

    I wonder if this has contributed to npm’s small modules culture too - if you have the possibility of version conflicts then the risk of such a conflict is directly, positively correlated with the number of packages you use. But if there’s no possibility of a conflict (ignoring peer dependencies, which are more uncommon and considered an anti-pattern), then there’s no cost to having more packages in the conflict risk sense.

    1. 3

      go has/had vendoring that is like 2.

      1. 1

        Why isn’t it used to prevent conflicts then?