锁版本的那些事
为什么要锁版本
了解锁版本之前我们需要首先了解下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,是不支持依赖版本锁定的。
1. package.json 锁定版本
也就是去除package.json版本前面的修饰符号,安装时候再加上--save-exact参数,但是这样不能对于依赖本身依赖的其他依赖进行锁定,所以情况非常有限。
2. npm+package-lock.json
第一次npm i的时候会根据当前node_modules目录生成一个固定版本号的package-lock.json文件,后面如果安装新增的依赖,会自动更新这个文件。但如果需要更新当前某个依赖的版本号并锁定到package-lock.json中,需要手动修改package.json中对应的版本或者指定依赖的版本号安装:npm i xxx@x.x.x。
3. yarn+yarn-lock.json
yarn-lock.json与package-lock.json原理类似,习惯用yarn命令的可以采取这种方式。
更好的方法
1. npm ci
npm ci在执行时会进行lock文件的检查,并且对于依赖项不匹配的情况会退出并显示错误,但是这个命令无法单独安装依赖,并且不会向package.json进行写入。
2. yarn --frozen-lockfile
yarn --frozen-lockfile和npm ci类似,需要存在yarn-lock.json文件。
为什么这里没有讲解
npm-shrinkwrap这种方法呢?主要是因为这个方法是npm 5之前的方法,每次依赖有新增或者版本更新之后,要手动自行npm shrinkwrap来生成或者更新版本锁定文件。
参考: