锁版本的那些事
为什么要锁版本
了解锁版本之前我们需要首先了解下package.json
中必不可少的dependencies
字段以及devDependencies
两个的区别:
dependencies
:指定项目运行所依赖的模块,安装使用--save
命令devDependencies
:指定项目开发所需要的模块,安装使用--save-dev
它们的值都是一个对象。该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围。
对应的版本可以加上各种限定,主要有以下几种:
- 指定版本:比如
1.2.2
,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。- 波浪号(
tilde
)+指定版本:比如~1.2.2
,表示安装1.2.x
的最新版本(不低于1.2.2
),但是不安装1.3.x
,也就是说安装时不改变大版本号和次要版本号。- 插入号(
caret
)+指定版本:比如ˆ1.2.2
,表示安装1.x.x
的最新版本(不低于1.2.2
),但是不安装2.x.x
,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为 0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。- latest:安装最新版本。
当我们使用比如
npm install package -save
安装一个依赖包时,版本是插入号形式。这样每次重新安装依赖包npm install
时”次要版本“和“小版本”是会拉取最新的。
正是因为如此,导致我们在同一份package.json
使用npm i
命令会获取到不同的依赖版本,导致了各种各样的问题,所以需要我们进行依赖的版本锁定。俗称"锁版本"
怎么锁版本
首先要说的是,很多同学可能习惯使用
cnpm
,因为安装速度确实比npm
快不少,但在版本依赖锁定方案中,最基础的一条就是:不要使用cnpm
,因为cnpm
,是不支持依赖版本锁定的。
package.json
锁定版本
1. 也就是去除package.json
版本前面的修饰符号,安装时候再加上--save-exact
参数,但是这样不能对于依赖本身依赖的其他依赖进行锁定,所以情况非常有限。
npm
+package-lock.json
2. 第一次npm i
的时候会根据当前node_modules
目录生成一个固定版本号的package-lock.json
文件,后面如果安装新增的依赖,会自动更新这个文件。但如果需要更新当前某个依赖的版本号并锁定到package-lock.json
中,需要手动修改package.json
中对应的版本或者指定依赖的版本号安装:npm i xxx@x.x.x
。
yarn
+yarn-lock.json
3. yarn-lock.json
与package-lock.json
原理类似,习惯用yarn命令的可以采取这种方式。
更好的方法
npm ci
1. npm ci
在执行时会进行lock
文件的检查,并且对于依赖项不匹配的情况会退出并显示错误,但是这个命令无法单独安装依赖,并且不会向package.json
进行写入。
yarn --frozen-lockfile
2. yarn --frozen-lockfile
和npm ci
类似,需要存在yarn-lock.json
文件。
为什么这里没有讲解
npm-shrinkwrap
这种方法呢?主要是因为这个方法是npm 5
之前的方法,每次依赖有新增或者版本更新之后,要手动自行npm shrinkwrap
来生成或者更新版本锁定文件。
参考: