锁版本的那些事

为什么要锁版本

了解锁版本之前我们需要首先了解下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.jsonpackage-lock.json原理类似,习惯用yarn命令的可以采取这种方式。

更好的方法

1. npm ci

npm ci在执行时会进行lock文件的检查,并且对于依赖项不匹配的情况会退出并显示错误,但是这个命令无法单独安装依赖,并且不会向package.json进行写入。

2. yarn --frozen-lockfile

yarn --frozen-lockfilenpm ci类似,需要存在yarn-lock.json文件。

为什么这里没有讲解npm-shrinkwrap这种方法呢?主要是因为这个方法是npm 5之前的方法,每次依赖有新增或者版本更新之后,要手动自行npm shrinkwrap来生成或者更新版本锁定文件。

参考:

请将你的npm依赖版本锁定open in new window