npm - How to actually use package-lock.json for in

2019-02-08 06:26发布

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 bootstrap@4.0.0-alpha.6 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
├─┬ bootstrap@4.0.0-alpha.6
├─┬ bootstrap-vue@0.16.1
│ ├── bootstrap@4.0.0-alpha.6 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
├── bootstrap@4.0.0-beta.2
├─┬ bootstrap-vue@0.16.1
│ ├── bootstrap@4.0.0-beta.2 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

标签: npm
2条回答
神经病院院长
2楼-- · 2019-02-08 07:06

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

查看更多
3楼-- · 2019-02-08 07:09

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.

There is another tool in development called cipm that will install strictly based on package-lock.json. This might be what you're really after. The reasoning for it are described by another npm CLI engineer, in the same thread.:

package.json is an authoritative manifest file, and package-lock.json is considered to be a manifestation of a particular package.json at a point in time.

...

There is no option/flag to freeze installs to force them to ignore package.json. There is also no intention of implementing this into npm.

...

Because the use case of "I wanna make sure this is locked down" is still valid, instead of adding that --freeze option, we're working on getting cipm out the door, because we believe this solves the use case of wanting to make damn sure your CI or production builds are obeying package-lock.json.

There is a lot more detail in GitHub issue 17979 as well as this SO thread: Why does "npm install" rewrite package-lock.json?

It is also worth noting that there is another GitHub issue to update the documentation around package-lock.json.

查看更多
登录 后发表回答