package-lock.json

package.json确定依赖的范围,package-lock.json将这个范围精确到具体版本。主要是为了解决在各个环境中得到确定的node_modules,如果只依赖package.json因为该文件声明的是直接依赖的范围,它无法将直接依赖固定在某个特定版本,也无法声明依赖的依赖。所以需要引入package-lock.json文件来达到我们固定node_modules的目的。

package.json确定当前项目直接依赖的包(例如:dependencies和devDependencies)版本的范围(例如:^1.0.0表示的是大于等于1.0.0小于2.0.0),所以只依赖package.json管理包会有两个缺点:

  1. 同一份package.json安装的依赖版本可能不同,如果依赖包有小版本更新并且引入了bug会导致重新装包的项目报错。
  2. package.json中声明的只是直接依赖,依赖的依赖无法通过package.json控制。例如:项目依赖包A,包A依赖包B,包A的版本可以通过package.json中固定版本号的形式固定下来(A: 1.0.0),但是A的依赖B的版本号可能是^2.0.0,这样包B的版本还是无法固定。

基于以上两个package.json的缺点需要引入新的方案:package-lock.json
package-lock.json文件内容是node_modules文件夹中包结构的快照,npm install 时会根据这份快照生成一模一样的node_modules,所以确保了一份package-lock.json在任何机器,任何时间生成的node_modules都一样,避免了只依赖package.json产生的两个问题。

package-lock.json和package.json配合生成node_modules的步骤如下:

npm7之后的版本生成的package-lock是可信的。

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

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.

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.

如果有一个package.json并且执行了npm i 我们将会生成package-lock.json文件。

如果针对package.json和package-lock.json执行npm i,package-lock.json永远不会更新,即使package.json中依赖的包有更新的版本。

如果你手动编辑了package.json中依赖包版本到不同版本范围并且执行了npm i,并且这个版本范围和package-lock中的不兼容,之后会更新package-lock.json中的版本为兼容package.json内的版本。之后npm i的运行和上面两条的描述一致。

package-lock.json修改的原因

  1. 手动编辑package.json中依赖包后重新install。
  2. 将项目依赖改为开发依赖,或者相反后重新install。
  3. npm registry 的修改后重新npm install,会引起package-lock.json文件中resolved字段的修改,即使包版本一致。
  4. 新增、删除和更新包后重新install。

lock文件生成逻辑

在包版本没有冲突的情况下会将依赖的依赖平铺,如果有冲突则会放到依赖的依赖内部。

例如:a 依赖 b,b 依赖 c,在node_modules中的结构是

|- a@1.0.0
|- b@1.0.0
|- c

如果项目依赖了b@2.0.0:

|- a@1.0.0
|—|-b@1.0.0
|- b@2.0.0
|- c

如果更新依赖,则依赖的依赖同样会更新。例如a发布了版本@1.0.1,b也发布了@1.0.1。npm install a@1.0.1则会变成

|- a@1.0.1
|—|-b@1.0.1
|- b@2.0.0
|- c

npm ci 不会修改package-lock.json的装包命令

In short, the main differences between using npm install and npm ci are:

  • The project must have an existing package-lock.json or npm-shrinkwrap.json.
  • If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.
  • npm ci can only install entire projects at a time: individual dependencies cannot be added with this command.
  • If a node_modules is already present, it will be automatically removed before npm ci begins its install.
  • It will never write to package.json or any of the package-locks: installs are essentially frozen.
  • 项目必须存在package-lock.json文件或者npm-shrinkwrap.json文件
  • 如果package lock中的依赖和package.json中的依赖不匹配,npm ci将会报错退出,而不是更新package lock文件
  • npm ci 一次会安装整个项目:这个命令不能添加单独依赖
  • 如果node_modules文件夹已经存在,在npm ci 开始安装前它将会被自动移除
  • 该命令绝不会写package.json文件和如何package-locks文件:安装本质上是冻结的。

问题和解决方案

package-lock.json冲突怎么办?

从稳定的分支checkout package-lock.json,再重新npm install生成一份新的package-lock.json。

想回退package-lock.json中的依赖的依赖版本怎么办?

在项目中直接install依赖的包对应的版本生成对应的lock文件,在将其从package.json中去除,即可将依赖的依赖版本进行回退。当然回退的版本需要符合版本约束。

参考

我的package-lock.json被谁改了?
package-lock.json
About semantic versioning
npm-ci
package.json详解
npm 依赖管理中被忽略的那些细节

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值