我最近刚升级到npm@5。我现在有一个包锁。包含package.json中的所有内容的Json文件。我希望,当我运行npm install时,依赖版本将从锁文件中提取,以确定应该在我的node_modules目录中安装什么。奇怪的是,它实际上最终修改和重写了我的包锁。json文件。
例如,锁文件的typescript被指定为2.1.6版本。然后,在执行npm install命令后,版本被更改为2.4.1。这似乎违背了锁文件的全部目的。
我错过了什么?我如何让npm尊重我的锁文件?
我最近刚升级到npm@5。我现在有一个包锁。包含package.json中的所有内容的Json文件。我希望,当我运行npm install时,依赖版本将从锁文件中提取,以确定应该在我的node_modules目录中安装什么。奇怪的是,它实际上最终修改和重写了我的包锁。json文件。
例如,锁文件的typescript被指定为2.1.6版本。然后,在执行npm install命令后,版本被更改为2.4.1。这似乎违背了锁文件的全部目的。
我错过了什么?我如何让npm尊重我的锁文件?
当前回答
在他们的github页面上有一个公开的问题:https://github.com/npm/npm/issues/18712
当开发人员使用不同的操作系统时,这个问题最为严重。
其他回答
也许你应该用这样的东西
npm ci
而不是使用npm install 如果您不想更改包的版本。
根据官方文档,npm install和npm ci都安装了项目所需的依赖项。
主要的区别是,npm install确实使用package来安装包。Json作为引用。在npm ci的情况下,它确实使用package-lock来安装包。Json作为参考,确保每次安装的包都是正确的。
你可能会遇到这样的情况:
"typescript":"~2.1.6"
在你的包裹里。NPM将它更新到最新的小版本,在你的例子中是2.4.1
Edit: Question from OP But that doesn't explain why "npm install" would change the lock file. Isn't the lock file meant to create a reproducible build? If so, regardless of the semver value, it should still use the same 2.1.6 version. Answer: This is intended to lock down your full dependency tree. Let's say typescript v2.4.1 requires widget ~v1.0.0. When you npm install it grabs widget v1.0.0. Later on your fellow developer (or CI build) does an npm install and gets typescript v2.4.1 but widget has been updated to widget v1.0.1. Now your node module are out of sync. This is what package-lock.json prevents. Or more generally: As an example, consider package A: { "name": "A", "version": "0.1.0", "dependencies": { "B": "<0.1.0" } } package B: { "name": "B", "version": "0.0.1", "dependencies": { "C": "<0.1.0" } } and package C: { "name": "C", "version": "0.0.1" } If these are the only versions of A, B, and C available in the registry, then a normal npm install A will install: A@0.1.0 -- B@0.0.1 -- C@0.0.1 However, if B@0.0.2 is published, then a fresh npm install A will install: A@0.1.0 -- B@0.0.2 -- C@0.0.1 assuming the new version did not modify B's dependencies. Of course, the new version of B could include a new version of C and any number of new dependencies. If such changes are undesirable, the author of A could specify a dependency on B@0.0.1. However, if A's author and B's author are not the same person, there's no way for A's author to say that he or she does not want to pull in newly published versions of C when B hasn't changed at all.
OP Question 2: So let me see if I understand correctly. What you're saying is that the lock file specifies the versions of the secondary dependencies, but still relies on the fuzzy matching of package.json to determine the top-level dependencies. Is that accurate? Answer: No. package-lock locks the entire package tree, including the root packages described in package.json. If typescript is locked at 2.4.1 in your package-lock.json, it should remain that way until it is changed. And lets say tomorrow typescript releases version 2.4.2. If I checkout your branch and run npm install, npm will respect the lockfile and install 2.4.1.
关于package-lock.json的更多信息:
package-lock。当NPM修改node_modules树或package.json时,Json会自动生成。它描述了生成的确切的树,以便后续安装能够生成相同的树,而不考虑中间依赖项更新。
该文件旨在提交到源存储库中,并用于各种目的:
Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies. Provide a facility for users to "time-travel" to previous states of node_modules without having to commit the directory itself. To facilitate greater visibility of tree changes through readable source control diffs. And optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.
https://docs.npmjs.com/files/package-lock.json
简短的回答:
NPM安装荣誉包锁。Json,如果它满足package.json的要求。 如果它不满足这些要求,则更新包并覆盖包锁。 如果你希望安装失败,而不是覆盖包锁发生时,使用npm ci。
下面是一个可能解释这些事情的场景(经过NPM 6.3.0验证)
在包中声明一个依赖项。json:
"depA": "^1.0.0"
然后执行npm install,它会生成一个包锁。json:
"depA": "1.0.0"
几天后,“depA”的一个更新的小版本发布了,比如“1.1.0”,那么下面的情况是成立的:
npm ci # respects only package-lock.json and installs 1.0.0
npm install # also, respects the package-lock version and keeps 1.0.0 installed
# (i.e. when package-lock.json exists, it overrules package.json)
接下来,手动更新包。json:
"depA": "^1.1.0"
然后重新运行:
npm ci # will try to honor package-lock which says 1.0.0
# but that does not satisfy package.json requirement of "^1.1.0"
# so it would throw an error
npm install # installs "1.1.0" (as required by the updated package.json)
# also rewrites package-lock.json version to "1.1.0"
# (i.e. when package.json is modified, it overrules the package-lock.json)
将来,您将能够使用——from-lock-file(或类似的)标志仅从包锁安装。Json而不修改它。
这对于CI等环境非常有用,因为这些环境中可复制的构建非常重要。
有关该特性的跟踪,请参见https://github.com/npm/npm/issues/18286。
我发现在npm 5.7.1的新版本中加入了新的命令npm ci,它将从package-lock安装。json只
The new npm ci command installs from your lock-file ONLY. If your package.json and your lock-file are out of sync then it will report an error. It works by throwing away your node_modules and recreating it from scratch. Beyond guaranteeing you that you'll only get what is in your lock-file it's also much faster (2x-10x!) than npm install when you don't start with a node_modules. As you may take from the name, we expect it to be a big boon to continuous integration environments. We also expect that folks who do production deploys from git tags will see major gains.