Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

npm - How to actually use package-lock.json for installing based on locked versions?

Tags:

npm

Just updated from npm 3 to 5, to use this feature.

Sorry, I must be missing something totally obvious, but how do make npm respect the pinned versions in package-lock.json file when installing?

Let's say I have a package.json with a fair bit of outdated packages. Doing an npm install will pull in new stuff and breaks my app.

For example, the main package I want to stabilize is bootstrap - I want to block its version at [email protected] for now, but npm install finds 4.0.0-beta.28.

If I npm update any package, package-lock.json gets updated.

Let's go to my development directory.

This is my package.json entry for bootstrap:

"bootstrap": "^4.0.0-alpha.6"

And this is what I see for my installed packages and meta data:

$ npm list 2>/dev/null | grep bootstrap ├─┬ [email protected] ├─┬ [email protected] │ ├── [email protected] deduped   (env) jluc@py$ grep bootstrap package.json package-lock.json package.json:    "bootstrap": "^4.0.0-alpha.6", package.json:    "bootstrap-vue": "^0.16.1", package-lock.json:    "bootstrap": { package-lock.json:      "version": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.0.0-alpha.6.tgz", package-lock.json:    "bootstrap-vue": { package-lock.json:      "version": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-0.16.1.tgz", package-lock.json:        "bootstrap": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.0.0-alpha.6.tgz", 

Looks good. Lock is bootstrap-4.0.0-alpha.6.

But how I use actually use that package-lock.json?

Here's what I did:

  • created a brand new directory
  • copied in package.json and package-lock.json
  • ran npm install.

No good. npm again found bootstrap beta and package-lock.json had no effect, in fact it was rewritten from what npm install did. Which is consistent with the behavior you want in dev, but doesn't tell me how I would use the lockfile to stabilize my packages.

(env) jluc@trynpmlock$ npm list 2>/dev/null | grep bootstrap ├── [email protected] ├─┬ [email protected] │ ├── [email protected] deduped  (env) jluc@trynpmlock$ grep bootstrap package.json package-lock.json package.json:    "bootstrap": "^4.0.0-alpha.6", package.json:    "bootstrap-vue": "^0.16.1", package-lock.json:    "bootstrap": { package-lock.json:      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.0.0-beta.2.tgz", package-lock.json:    "bootstrap-vue": { package-lock.json:      "resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-0.16.1.tgz", package-lock.json:        "bootstrap": "4.0.0-beta.2", 
  • If I delete the package.json and only have a directory with package-lock.json, then npm install installs very little and leaves me with a truncated package-lock.json

  • npm install has a --no-package-lock option, but that prevents updating the package-lock.json.

Basically how do I tell npm install everything from package.json, but respect locks in package-lock.json? Do I use a different command than npm install? Is it because npm install's doc refers to locks in the context of a package installation, but locks don't apply when you install the package.json in its entirety?

Yes, I know I can specify "bootstrap": "4.0.0-alpha.6", minus the ^, to pin the version manually.

My environment:

(env) jluc@py$ npm -v 5.5.1 
like image 955
JL Peyret Avatar asked Nov 24 '17 22:11

JL Peyret


People also ask

What is the package lock in NPM?

To prevent this potential issue, npm uses package-lock.json or, if present, npm-shrinkwrap.json. These files are called package locks, or lockfiles. Whenever you run npm install, npm generates or updates your package lock, which will look something like this: ...metadata fields...

How do I use a locked package with JSON?

Using a locked package is no different than using any package without a package lock: any commands that update node_modules and/or package. json's dependencies will automatically sync the existing lockfile. This includes npm install, npm rm, npm update, etc.

Why can’t I install the same package in multiple versions of NPM?

But in many others, npm is unable to do this. There are multiple reasons for this: different versions of npm (or other package managers) may have been used to install a package, each using slightly different installation algorithms.

What is the difference between package-lock and package-JSON?

A simplistic answer: package.json have your dependencies as usual, while package-lock.json is "an exact, and more importantly reproducible node_modules tree" (taken from npm docs itself ). As for the tricky name, its NPM trying to catch up with Yarn. Show activity on this post.


2 Answers

You need to use the npm ci command to install from package-lock.json.

See: https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable

like image 114
Dave Potts Avatar answered Sep 23 '22 19:09

Dave Potts


Update: As Dave pointed out, the command for this situation is now npm ci. It will install from package-lock.json and will not update it. See the documentation for more information.


According to this comment by a member of the npm CLI team, what you are describing is a "high priority bug".

  1. If you have a package.json and you run npm i we generate a package-lock.json from it.

  2. If you run npm i against that package.json and package-lock.json, the latter will never be updated, even if the package.json would be happy with newer versions.

  3. If you manually edit your package.json to have different ranges and run npm i and those ranges aren't compatible with your package-lock.json then the latter will be updated with version that are compatible with your package.json. Further runs of npm i will be as with 2 above.

If you do run into a case where npm@^5.4.2 mutates a package-lock.json that was otherwise compatible with the paired package.json please open a new issue. This sort of thing would constitute a high priority bug.

like image 45
Jason Schindler Avatar answered Sep 22 '22 19:09

Jason Schindler