Explanation for `npm ci` semver ranges


(Michael) #1

Our team necessarily needs to use npm ci in our process, but I am at a loss to explain why package-lock uses semver ranges. I know that npm ci will produce a consistent build, and can hypothesize about the reason for ranges rather than specific versions, but I couldn’t find an explanation for this. Can someone please explain this? Might also be nice to explain on the npm ci Docs page. Thanks!


(Kat Marchán) #2

To answer the question: we moved to using the original specifiers in the requires field of package-lock.json in later versions of npm@5 and npm@6. The main reasons for this were reducing pkglock thrash whenever shared dependencies would get upgraded, and improving the ease of translation between different lock formats.

This doesn’t affect installed versions in any significant way: we still determine what to install based on the concrete version field for individual entries. The difference now is that only packages directly modified but an install or upgrade will get a diff, whereas before, all shared dependents would’ve gotten a diff in requires.

This isn’t an npm ci change, btw. It’s a general installer change.

I’m not sure what the best way to document this is, or whether this should be treated as a regular support issue and not a docs issue, but I’ll let someone else make that decision :sweat_smile:


(Michael) #3

Many thanks for the explanation zkat. For whoever its useful to, I personally think this clarification regarding semver-range, and perhaps even the specifics of implementation, somewhere on https://docs.npmjs.com/files/package-locks would be helpful. When reading about package-lock specifically, these are the most relevant kinds of questions. I understand it is a balancing act in providing the level of detail to be clear to a broad range of versions / situations.