npm
npm 是 Node 自带的软件包管理工具,以往我们在多人协同开发过程中经常使用 npm i 来安装/更新项目依赖,但在 NPM v6 版本后,为什么大家更推荐使用 npm ci 了呢!
npm i 和 npm ci 到底有什么区别?
首先,我们来了解一下执行 npm i 和 npm ci命令到底发生了什么?
执行 npm i 命令主要做了两件事:
-
首先,它会根据
package.json文件,创建node_modules文件夹并安装对应的依赖版本; - 然后, 生成/更新
package-lock.json文件;
执行 npm ci 命令也做了两件事:
-
首先,它会删除
node_modules文件夹; - 然后,依照
package-lock.json(或npm-shrinkwrap.json)文件 创建新得node_modules文件夹并精准安装对应的依赖版本;
ps: npm-shrinkwrap.json文件,是在 NPM v5 版本之前,通过运行npm shrinkwrap命令产生用来精准控制安装依赖版本的文件;
知道了 npm i 和 npm ci 命令都做了什么,我们就知道了为什么推荐使用 npm ci 了,因为它能够精准安装对应的依赖版本;
为什么 npm i 不能精准安装依赖?
npm i 不能精准安装依赖主要是因为package.json文件里面的依赖版本往往是一个范围,并不是一个固定的版本,它允许依赖的升级;而package-lock.json 文件,是对package.json文件,做了依赖的版本检查以及梳理后生成的,所以npm ci能够快速精确的安装依赖;
那么什么精准安装依赖?精准安装依赖解决了什么问题?
所谓精准安装依赖,就是不受语义版本控制的影响,精确安装指定的版本依赖,保证了项目的‘完美复制’;
例如:在项目部署的时候,使用 npm ci 保证了依赖版本一致,不会因为出现线上和开发版本不一致而引发的bug;
语义版本控制 semver
语义版本控制简单来说对软件的版本号赋予了语义,软件的版本号通常由版本符号和三个数字组成;
例如版本号:2.1.3其中
-
第一个数字
2代表主版本号,表示进行了不兼容的更新; -
第二个数字
1代表次版本号,表示以向后兼容的方式添加功能的更新; -
第三个数字
3代表补丁版本号,表示进行向后兼容的缺陷修复的更新; -
2.1.3指定特定的版本号2.1.3; -
~2.1.3当运行npm update时,会匹配所有 2.1.x 版本,但是不包括 2.2.0; -
^2.1.3当运行npm update时,会匹配所有 2.x.x 版本,但是不包括 3.0.0; *2.1.3当运行npm update时,会匹配安装最新版本;
package-lock.json和npm-shrinkwrap.json什么区别?
npm-shrinkwrap.json是在 NPM v5 版本之前,用来精准控制安装依赖版本的,package-lock.json在 NPM v6 版本,用来精准控制安装依赖版本的。package-lock.json 比 npm-shrinkwrap.json更加成熟、简单。
npm-shrinkwrap.json是手动运行npm shrinkwrap命令创建/更新的,而package-lock.json会在修改pacakge.json或者node_modules时自动产生/更新。
并且 npm-shrinkwrap.json会在发布包中出现,而package-lock.jsonnpm 会自动忽略。
一般情况下使用 npm i 是可以的,但是为了防止意外情况发生,建议使用 npm ci来安装依赖,它可以保护项目环境的准确性,并且因为不用梳理各依赖之间的关系,它比npm i的速度更快。










