3 ms·
one thing I love about npm, it defaults to all tools and dependencies being versioned and local. No list of tools and system libs I need to install. people com
by greggman3 7y ago
one thing I love about npm, it defaults to all tools and dependencies being versioned and local. No list of tools and system libs I need to install.
people complain about all the deps but deps in C/C++ and even to some degree python are hidden since they are system deps. No one seems to blink an eye when they apt-get something and it requires 60 deps and of course the second apt-get only shows the missing deps so there is this false idea that the dependencies are fewer.
for the most part npm just works. As someone with 15-35yrs C/C++ experience and a bunch of Perl and Python it's refreshing not to have to trash my system with global deps or learn non default modes of operation, that the default is all tools and deps local.
I also get why static typing people hate JS but one thing they got right IMO is there are no namespaces. You import libraries into local variables which seems like a huge win over namespaces.
Note: I also get that c/c++ is generally harder. Different compilers, different flags, different platforms, etc. I’m not saying I have a solution. getting MS (VC++), Apple(Xcode/clang), and GNU(GCC) on the same page might be a start.
- skrebbel 7y agoFWIW, JS does have namespaces: directories. There's no big semantical difference between var Hello = require("someorg/hey"); and in eg C#: using Hello = SomeOrg.Hey; The only difference is that in JS you're forced you choose a name for the variable, whereas in C# (and many other languages) you typically just give it the default name (`using SomeOrg.Hey;`). In short, the node_modules package resolution algorithm is how JS does namespaces. It's the same thing, just with different syntax (and, IMO, a bit more weirdness). The fundamental thing isn't "no namespaces" but "namespaces are package-relative". I wonder whether they got that right through sheer genius, or by accident. (I recognize that I'm being super pedantic here btw, hope that's OK) Note that I agree with the rest of your comment, NPM is splendid and it's impressive how much they got right at the first go, especially given how NodeJS was on a hype train at the time (many things on hype trains only get tooling like this right after the first so many tries).
- greggman3 7y agothat might be true in c# but it's not true in C++ iirc. the library declares its "global" namespace which dicates what global symbol will be generated for the linker. "using" creates an alias for that symbol in consumers of the library but nothing you can do short of changing the source of the library will fix the issue of 2 libraries using the same namespace. This is not true for JS Update : Verified the same issue exists in c#.
- lioeters 7y ago> ..The node_modules package resolution algorithm is how JS does namespaces.. I wonder whether they got that right through sheer genius, or by accident. I recall hearing Ryan Dahl's regrets about design decisions in Node.js, a few of which had to do with the module/package resolution algorithm. 10 Things I Regret about Node.js - https://www.youtube.com/watch?v=M3BM9TB-8yA https://www.youtube.com/watch?v=M3BM9TB-8yA There are some good aspects of it though. I like how modules/packages are just imported objects (the path resolution is a bit weird and seemingly inefficient, i.e., checking every parent folder's node_modules folder). It goes together well, that modules are also self-contained function scopes by default (I suppose a kind of anonymous namespace), that exports a plain object with assigned properties. --- Wow, I just learned about C++20 Modules, looks like a game-changing feature. https://modernescpp.com/index.php/c-20-modules https://modernescpp.com/index.php/c-20-modules
- skrebbel 7y agoYeah I saw that talk too, and I was baffled. He seems totally ready to throw out the baby with the bathwater. Node's package resolution algorithm might not be perfect, but it's better than nearly every other language's (which is "single big unhierarchical dump of packages, good look sorting out the dependencies kthxbye").
- kkapelon 7y ago>one thing I love about npm, it defaults to all tools and dependencies being versioned and local. No list of tools and system libs I need to install. That is not unique to npm. Java/Maven, Ruby/Bundler, Go/Vendor also work like this and I believe that several other languages might work like this. Comparing npm with C/C++ build/package tools is setting a very low bar
- skrebbel 7y agoTrue, but it's nice for JS land that NPM got it right the first time. Ruby gems sucked before bundler (and last I checked, bundler still isn't cross-platform, it's nuts), I lost count of how many Go package managers get published. For at least a decade all of Java land downloaded JARs and put them into the CLASSPATH. It really took quite a while for programming communities to accept that that local packages are a good thing, and NPM was early to the party. And NPM does this recursively, which I think it what greggman is primarily getting at. I don't think many other package managers do this. I mean, the fact that a package's dependencies are local to it too is fundamental. You simply can't get dependency version conflicts (except if package authors do terrible global state hacks, and fortunately this is pretty unheard of). Instead, you just pull in 5 different versions of some logging library or some http client wrapper, and you don't even notice. That's not without its own downsides, but I prefer it to the steaming pile of `override` directives in our Elixir codebase has day.
- kkapelon 7y ago>I don't think many other package managers do this Unless I am missing something, "go mod vendor", and "mvn package" will work in the same manner. They will download all deps of the app itself PLUS all transitive dependencies. No system libraries needed (or touched)
- skrebbel 7y agoI'm no expert, but given the amount of hits "maven dependency conflicts" I get on Google, strongly doubt Maven works the same. Last I checked, it'll indeed pull in all transitive dependencies, but if multiple dependencies need the same subdependency of a different version, you need to work out conflicts. JS simply doesn't have this problem, it's splendid.