从package-lock看npm版本锁定相关知识

前言

随着前端模块化开发的流行,项目中基本都会使用node和npm来下载和管理各个依赖模块。在项目的根目录中,package.json、package-lock.json就是描述模块信息的文件。下文将围绕基础知识、两者关联、风险与稳定性展开叙述

一、基础背景

1、版本号规则

从package-lock看npm版本锁定相关知识_第1张图片

1. 版本号格式为:X.Y.Z,并且 X、Y、Z 均为正整数并且不断递增。X 表示大版本(major)、Y 表示小版本(minor)、Z 表示补丁版本(patch)
2. 版本不能变更,变更必须再发布一个新版本。XYZ分别递增表示不兼容的变更、向后兼容的新功能、向后兼容的Bug修复(同时大版本可能包含小版本或补丁版本的改动)
3. 0.Y.Z 表示初始版本,这种版本下的 API 不能保证稳定,随时可能变更。

2、* ^ ~定义与区别

从package-lock看npm版本锁定相关知识_第2张图片

通常会错误地将*^~简单理解为识别 [major, minor, patch] 三元组中第一位、第二位、第三位,平时不会有问题,但一旦是预发版本号0.X的情况,就会发现不是这么回事。

实际上,三者的定义如下

1. *意味着安装最新大版本的依赖包
2. ^ 指的是只要不修改 [major, minor, patch] 三元组中,最左侧的第一个非0位,都是可以的

^1.2.3 匹配 >=1.2.3 < 2.0.0

^0.2.3 匹配 >=0.2.3 <0.3.0

^0.0.3 匹配 >=0.0.3 <0.0.4

3. ~ 简而言之就是允许修改最后一位被指定的版本号

~1.2.3 匹配 >=1.2.3 <1.3.0

~1.2 匹配 >=1.2.0 <1.3.0 (Same as 1.2.x)

~1 匹配 >=1.0.0 < 2.0.0

~0.2.3 匹配 >=0.2.3 <0.3.0

~1.2 匹配 >=1.2.0 <1.3.0 (Same as 0.2.x)

~0 匹配 >=0.0.0 < 1.0.0(Same as 0.x)

4. 不带标志,1.2.3则意味着指定版本的依赖包

更多详情,如预发布版本见官网https://www.npmjs.cn/misc/semver/

3、命令行引入版本区别(以koa为例)

1. npm install koa --save

未指明版本号安装模块,会默认安装模块的最新版本, package.json 文件中。如:“koa”: “^2.11.0”,会更新小版本

2. npm install --save [email protected]

指明版本号安装模块,会安装模块的指定版本, package.json 文件中。如:“koa”: “^1.0.0”,会更新小版本

3. npm install

如果删除lock文件和node-modules,install之后会根据package.json 文件中"koa": “^1.0.0”,更新小版本,lock显示实际的安装可能为"1.7.0"

4、其他细节

(1) 如果没有-save,会把X包安装到node_modules目录中,不会修改package.json,之后npm install不会自动安装

(2) 如果只在开发时需要,运行时不需要的包,可以npm install X –save-dev,会添加在package.json的devDependencies属性下

二、package-lock.json文件与package.json两者有什么区别与关联?

1、生成方式

  1. package.json文件已不再自动生成,npm init ,根据命令行提示输入一些基本信息,可初始化生成package.json文件
  2. 执行"npm install"时,node会重新生成package-lock.json文件,然后把node_modules中的模块信息全部记入package-lock.json文件

2、两者的区别

  1. package.json文件只记录通过npm install方式安装的模块信息,而这些模块所依赖的其他子模块的信息不会记录。
  2. package-lock.json文件锁定所有模块的版本号,包括主模块和所有依赖子模块。

3、包的下载流程规则

从package-lock看npm版本锁定相关知识_第3张图片

4、改动影响

以下内容针对于npm 5.4.2之后的版本(之前变动见https://www.zhihu.com/question/62331583)

  1. 两个文件的模块信息不冲突时(如package.json中模块版本区间^1.1.0包含lock文件中已安装的版本^1.7.0)
    执行npm install,node从package.json文件读取模块名称,从package-lock.json文件中获取版本号,然后进行下载或者更新
  2. 两个文件的模块信息冲突时(如package.json中模块版本区间^1.1.0不包含lock文件中已安装的版本^2.11.0)
    执行npm install,node从package.json文件读取模块名称和范围,按其规则下载包,并更新package-lock.json文件版本

5、常见问题

  1. 如上2所说,一旦冲突,会根据package.json的范围重新更新文件版本,如果不想自动覆盖的话怎么做?
    执行npm ci而非npm i, 这样当package-lock.json指定的依赖版本不在package.json指定的依赖版本范围内时,npm会报错并取消安装。

三、版本锁定的风险及维稳

1、存在的风险

  1. 包被删除,其他依赖此包的应用全部受到了影响。比如left-pad事件(作者因npm方未经自己许可,将自己的一个工具kik权限转移给了同名公司,Azer一怒一下删了所有的包,所有直接或者间接依赖left-pad这个模块的 NPM 包就忧伤的挂掉了,包括 babel 这样的热门项目)。
  2. 新版本发布未按照规范,不兼容大版本改动却使用了补丁版本或小版本发布,导致install之后应用出错
  3. 手动修改了package.json文件,存在冲突,导致lock文件被更新覆盖

2、版本下架相关规则

官方地址:https://docs.npmjs.com/unpublishing-packages-from-the-registry

  1. 发布后的72小时内,没有其他包依赖此包,可删除。
  2. 72小时候,删除需满足以下条件:
    (1)没有其他包依赖
    (2)过去一周少于300下载量
    (3)只有一个开发者
  3. 如果整个包删除,不能再重新发布,可更名或用一个未发布过的版本号去发布。
  4. 删除不可撤销,且24小时内不能发布任何内容。
  5. 不满足删除条件,可以选择弃用,将所有权转移到npm官方账号下。
  6. 任何情况,可联系相关支持人员处理 [email protected]

3、如何保证稳定性

  1. 使用package-lock文件,改动package.json文件时使用npm ci命令,避免自动覆盖更新lock文件。
  2. 出现问题时,可以通过git查看lock文件变动,找到旧的模块版本,通过命令行指定安装版本号。
  3. 私服管理核心包以及不太稳定的包,避免被删。

引文
https://blog.csdn.net/weixin_44135121/article/details/89880261
https://www.jianshu.com/p/1d2e2f8c9ab2
https://segmentfault.com/a/1190000019602042
https://blog.csdn.net/weixin_34332905/article/details/89120935
https://segmentfault.com/a/1190000019602042
https://baijiahao.baidu.com/s?id=1633727314928157498&wfr=spider&for=pc

你可能感兴趣的:(【前端】打包及基础配置,npm)