4 ms·
When you `npm install` a package by default when other users `npm install` it it will install the most recent patch version - even if it's different from the on
by inglor 11y ago
When you `npm install` a package by default when other users `npm install` it it will install the most recent patch version - even if it's different from the one you installed. So if you install dependencies through `npm install --save` which is the default and advertized way - you can get completely different code between production and staging.
As a library maintainer, patches breaking the library is something that happens (not often, but still) - testing can eliminate a lot but not all bugs.
- kibwen 11y agoI'm not trying to dispute that a problem exists, only that semver is a red herring here. It seems like the problem that you describe doesn't have to do with semver, rather that it has to do with npm lacking something like lockfiles.
- girvo 11y ago> npm lacking something like lockfiles `npm shrinkwrap --dev` will give you a shrinkwrap file, with dev-deps also locked. Still, it took me 3 months of heavy Node usage before I found that out. Over in PHP land, while Composer has its own set of faults, it's at least generating a lockfile automatically.
- pygy_ 11y agoIt is semver compounded with the "^x.y.z" version requirements for dependencies that NPM uses as a default when a package author `npm install --save` something. When someone else installs that package it will bump y or z if `x > 0`, and z if `x == 0 && y > 0` for all dependencies. You can manually freeze deps to 'x.y.z'. The main problem is the "^" default.
- Silhouette 11y agoThe main problem is the "^" default. This is true. A secondary problem is the culture of having so many dependencies, which has been much discussed this past week. Even if you lock everything to a static version for consistency, how many people really know which packages from which sources they are relying on to build their system today? Presumably you trust your direct dependencies, and they in turn trust theirs, and so on, but all it takes is one package five levels deep in the tree where the developer was in a rush and npm install'd something vulnerable or malicious to compromise the entire tree.
- TheCoreh 11y agoEven if you manually freeze deps to 'x.y.z', the deps of your deps might still be specified with '^'. Ideally you'd shrinkwrap, and commit node_modules to your repo. (In case packages get deleted)
- jdavis703 11y agoWhat's the point of shrinkwrap if you're commiting node_modules? And also why not use a package manager like RPM, Debian, etc so you don't bloat your Git history? (Genuine questions, I know many advocate what you're saying).
- chromakode 11y agoVendoring by storing node_modules works great. It's not necessary to shrinkwrap in that case -- all the same data is derived from the node_modules directory tree. For production, I often use a separate git repo for storing node_modules, referenced as a submodule of the code repo. This has two advantages: * You retain history for your full dependency tree separately from your codebase. * Every commit of your code repo exactly specifies the contents of its dependency tree, since the submodule references your deps repo by commit hash.
- acemarke 11y agoRe-re-posting a comment I've made in a few threads now, because I feel this needs to get more awareness: I'm still learning and prototyping my first JS/NPM/React project, but https://github.com/JamieMason/shrinkpack https://github.com/JamieMason/shrinkpack seems to me like it solves _most_ of the issues involved here. It pulls down all the tarballs, and updates the npm-shrinkwrap.json to point to those instead. That way you check in a much smaller "node_shrinkwrap" folder of a few hundred tarballs and 15-20MB, rather than a node_modules folder of 30K files and 150MB and a bunch of platform-specific build outputs. Still doesn't solve the issue of installing new/updated dependencies that might actually require pulling in something that vanished, but at least once you've done an install and run "shrinkpack", you've got everything you need to rebuild right there.
- jonahx 11y agowhat is the recommended way to globally change that default?
- insin 11y agonpm config set save-exact true
- DrJokepu 11y agoI mean, don't use `npm install --save` then. I'm not really sure why people started using it in the first place, it's such a lazy thing to do. Instead, add it to your package.json yourself with the exact specific version you want (none of the ^a.b.c funny business).
- inglor 11y agoWhen I bootstrap code I npm install --save, I have 10 packages I usually need right off the bat and I don't want to start an investigation every time I do this.
- madeofpalk 11y agoor rather, npm install --save-exact :) then upgrade with npm shrinkwrap
- igl 11y agoecho "save-prefix=''" > ~/.npmrc
- Silhouette 11y agoInstead, add it to your package.json yourself with the exact specific version you want Unfortunately, the same problem then arises for your dependencies. If any of them don't specify exact versions, you are still vulnerable to getting uncontrolled changes. This is why things like npm shrinkwrap exist, but it's still crazy that NPM's default behaviour is the uncontrolled case.
- DrJokepu 11y agoYes, libraries should specify exact versions as well, it's insane that they don't.
- joshribakoff 11y ago> you can get completely different code between production and staging. That's not NPM's fault, its the fault of the way you deploy code. Even if you locked down a version, git is mutable so someone could change their code. That's why I "rsync" the code to production, so I know its the same as development.
- JdeBP 11y agoIt's also why one wag suggested using Twitter (which "doesn't have an edit button") as a repository: * https://gist.github.com/rauchg/5b032c2c2166e4e36713 https://gist.github.com/rauchg/5b032c2c2166e4e36713