npm install 和 npm update 的混淆

3

我正在学习 package.jsonpackage-lock.json 的区别。

我只使用一个名为chance的依赖来进行实验。

我首先通过 npm i chance@1.0.0 命令安装了它,然后 package.json 中显示 "chance": "^1.0.0"package-lock.json 中显示 "version": "1.0.0"

由于我想要查看锁定文件对版本的影响,因此我删除了 package-lock.jsonnode_modules,然后运行 npm install,这时在 package.json 中,chance 的版本仍然是 "chance": "^1.0.0";在新创建的锁定文件中,chance 的版本变成了 "chance": {"version": "1.1.8",,自动更新。

然后我再次删除了package-lock.jsonnode_modules,并运行npm update,结果似乎与前面的实验相同 - 在package.json中我有"^1.0.0",在package-lock.json中有"1.1.8"

我的问题如下:

  1. 无论是在 package.json 还是在 package-lock.json 中,如果 "^1.0.0""1.1.8" 同时存在,则我在项目中实际使用的版本是哪个?我猜是 1.1.8 对吗?因此仅查看 package.json 中的版本不足以确定项目中使用的精确版本依赖?
  2. npm install 什么时候会更改锁定文件?我知道如果我们删除锁定文件,它将使用从 package.json 中允许范围内的最新版本生成一个新的锁定文件。但是否有任何情况下即使我没有删除锁定文件,npm install 也会更改锁定文件?

我期望npm的行为是,当你运行npm i chance@1.0.0时,你的package.json会被更改为精确的版本,不含^"chance":"1.0.0"。但现实情况是不同的……这将导致随后的npm i可能会使用该软件包的任何更高的次要/修补版本来更改package-lock。尽管你只要求安装依赖包的确切版本。 - hastrb
1个回答

2
因此,答案有点复杂。基本上有两个要素:你想要/需要的包的版本和已安装的包的版本。
在构建项目时,你可能不关心给定依赖项的具体版本。大多数情况下,你想要最新的版本,或者是特定主版本附近的最新补丁。package.json 应该记录你作为开发人员认为对你的项目工作所需的内容。因此,如果在 package json 中输入 "chance": "1.0.0",这意味着只有版本 1.0.0 正好是可接受的,任何其他版本都是不可接受的。如果输入 "chance": "^1.0.0",则表示与版本 1.0.0 兼容的任何版本都是可接受的。因此,1.2 或 1.3 也可能很好,但 1.4 可能会引入破坏兼容性的更改。
一旦您决定好需要哪些包,通过编写 package.json 文件,您可以运行 npm install 命令进行安装。但是,npm install 并不能总是精确地安装您所需的版本。例如,假设您想要安装两个包:React v1.13 和 momentJS v2.8。那么您可以像以下这样将它们添加到您的 package.json 文件中:
(注意:这些版本号和依赖关系并非基于真实的 React 或 Moment 版本号)
"momentJS" : "2.8",
"react" : "1.13"

然后运行npm install。你会收到一个错误:包依赖无法解决。(或类似的消息)。问题是React版本1.13需要momentJS 2.9,但你的package json指定了你想要精确的2.8版本。你不能同时拥有两个版本,所以npm无法解决冲突。修复方法如下:
"momentJS" : "^2.8",
"react" : "1.13"

现在你说你需要一个与2.8兼容的moment版本,并且你可以通过npm来满足其他包的要求。再次运行npm install,npm可能会安装版本2.9,它既符合你对“与1.8兼容”的要求,也符合React想要的2.9。现在,我正在开发的Web应用程序总共有超过1,000个依赖项,因此npm绝对需要能够调整版本号以使所有这些包协同工作。
现在解决依赖关系图的方法通常不止一种--调整所有版本号使每个包都满意的方法不止一种。您的软件包锁定文件记录了当前解决方案和实际安装的软件包。
指定软件包版本的所有选项都在此处
希望这可以帮助你!
另外:你的问题的第二部分是“npm会在我删除它之前更改锁定文件吗?”答案是:基本上每次你运行npm install,npm都会更改锁定文件。npm试图做的是尽可能少地更改锁定文件,并保持大多数软件包不变。

非常感谢您详尽的回答!我想我的第二个问题实际上是想问,什么情况下仅运行npm install会更改锁定文件?我记得我遇到过一些奇怪的情况,即使我没有触碰package.json文件,锁定文件也发生了变化... - Joji
@Joji 首先,如果我回答了你的问题,我会很感激你能接受这个答案。如果你在不改变 package json 的情况下运行 npm install,则 package lock 不应更改,但是你不应该依赖它不更改。关于 package lock 如何精确更改的逻辑并不简单。 - Sam Spade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接