本文已参与「新人创作礼」活动,一起开启掘金创作之路
#
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.json
npm 会自动忽略。
一般情况下使用 npm i
是可以的,但是为了防止意外情况发生,建议使用 npm ci
来安装依赖,它可以保护项目环境的准确性,并且因为不用梳理各依赖之间的关系,它比npm i
的速度更快。