package-lock.json作用

对于 package-lock.json作用,我们要先来了解下包版本

npm采用semver作为包版本管理规范。此规范规定软件版本由三个部分组成:

  • 主版本号做了不兼容的重大变更
  • 次版本号做了向下兼容的功能添加
  • 补丁版本号做了向下兼容的bug修复


除了版本号之外,还有一些版本修饰,后面可以带上数字:

  • alpha内测版 eg:3.0.0-alpha.1
  • beta公测版 eg:3.0.0-beta.10
  • rc正式版本的候选版 eg:3.0.0-rc.3


版本匹配

*/x:匹配任意值
1.1.*  =   >=1.1.0 <1.2.0
1.x  =   >=1.0.0 <2.0.0
^xxx:  最左侧非0版本号不变,不小于xxx
^1.2.3  =   >=1.2.3 <2.0.0 主版本号不变
^0.1.2  =   >=0.1.2 <0.2.0 主、次版本号不变
^0.0.2  =   = 0.0.2 主、次、补丁版本号都不变
~xxx: 如果列出了次版本号,则次版本号不变,如果没有列出次版本号,则主版本号不变,均不小于xxx
~1.2.3  =   >=1.2.3 <1.3.0 主、次版本号不变
~1  =   >=1.0.0 <2.0.0 主版本号不变

当我们安装包的时候,会自动添加package-lock.json文件,那么这个文件的作用是什么呢?在这个问题之前,先来看看npm install的安装原理:

 package-lock.json作用
固定版本
当我们安装包的时候,会自动添加package-lock.json文件,那么这个文件的作用是什么呢?在这个问题之前,先来看看npm install的安装原理:

//package.json
{
  "name": "npm",
  "version": "1.0.0",
  "dependencies": {
    "vue": "^2.5.1"
  },
  "devDependencies": {
    "eslint": "^7.0.0"
  }
}



有上面一份npm配置文件,当npm install时会安装两个包:vue ^2.5.1,eslint ^7.0.0 ,符合所配置版本的包是一个范围多个,npm会会安装符合版本配置的最新版本。比如:
vue ^2.5.1 = >=2.5.1 <3.0.0, npm会选择安装2.6.13,因为它在匹配版本范围内,且是目前最新的vue2的版本,它不会选择2.5.0和3.0.0。
那么如果只有一份package.json文件,就很可能导致项目依赖的版本不一样。比如开发时候vue2的最新版本是2.6.13,过了几个月项目要上线,部署的时候vue2的最新版本已经是2.7.0了,那么线上就会安装最新的版本。如果2.7.0有一些不兼容2.6.13的地方,或者有bug,那就会导致我们开发的一个经典问题:开发环境没问题,一上线就坏。如果项目是多个人协同开发,甚至会导致开发环境都不一样。
那么我们来看看package-lock.json文件怎么解决这个问题的:

//package-lock.json
{
  "name": "npm",
  "version": "1.0.0",
  "lockfileVersion": 1,
  "requires": true,
  "dependencies": {
    "vue": {
      "version": "2.6.13",
      "resolved": "https://registry.nlark.com/vue/download/vue-2.6.13.tgz?cache=0&sync_timestamp=1622664849693&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvue%2Fdownload%2Fvue-2.6.13.tgz",
      "integrity": "sha1-lLLBsx/d8d/MNPKOyEi6jwHqTFs="
    },
    .....
  }
}



我们看到package-lock.json文件里直接记录了vue的固定版本号和下载地址。

npm在执行install的时候,会把每个需要安装的包先在package-lock.json里查找,如果找到并且版本符合package.json的配置范围(在范围内就行,不需要最新),就会直接按照package-lock.json里的地址安装。如果没找到或者不符合范围,则安装原本的逻辑安装(符合版本要求的最新版)。
这样就确保,不管时间过了多久,只要package-lock.json文件不变,npm install安装的包的版本都是一致的,避免代码运行的依赖环境不同。

固定依赖结构
我们的一个项目通常会有很多依赖包,而这些依赖包很可能又会依赖其他的包,那如何来避免重复安装呢?
比如:

//package.json
{
  "name": "npm",
  "version": "1.0.0",
  "dependencies": {
    "esquery": "^1.4.0",
    "esrecurse": "^4.3.0",
    "eslint-scope": "^5.1.1"
  }
}



依赖关系如下:

  • esquery : ^1.4.0,
  •     estraverse : ^5.1.0
  • esrecurse : ^4.3.0
  •      estraverse : ^5.2.0
  • eslint-scope :^5.1.1
  •       esrecurse : ^4.3.0
  •             estraverse :^5.2.0
  •       estraverse :^4.1.1

如果按照这个嵌套结构来安装包的话也是可以的,而且npm原来的版本就是这么做的,这样可以保证每个包都安装完整,但是问题是会导致一些包重复安装,如果这个依赖很多的话,重复的数量也会很多。那npm是怎么处理的呢?
npm采用的是用扁平结构,包的依赖,不管是直接依赖,还是子依赖的依赖,都会优先放在第一级。
如果第一级有找到符合版本的包,就不重复安装,如果没找到,则在当前目录下安装。
比如上面的包会被安装成如下的结构:

  • esquery :1.4.0,
  •          estraverse : 5.2.0
  • esrecurse : 4.3.0
  •           estraverse : 5.2.0
  • eslint-scope : 5.1.1
  • estraverse : 4.3.1

包安装的数量从开始的8个减少到了6个,虽然还是有重复,但是因为这个json的结构,又是以包名为键名,所以同一级下只能有一个同名的包,就像 estraverse : 5.2.0不能放在外层,因为外层已经有了以estraverse为名的对象:estraverse : 4.3.1。
package-lock.json记录的就是上面的依赖结构(上面只是简写,每一项还包含一些其他的信息,比如下载地址),这也是node_modules里面包的结构。
所以一个项目只要package-lock.json不变,它的依赖结构就不变,而且npm不用重新解析包的结构了,直接从package-lock.json文件就可以安装完整且正确的包依赖,也提高了重新安装的效率。

你可能感兴趣的:(前端模块化,构建工具,nodejs,npm)