npm依赖版本锁定和管理

前几天测试的时候遇到个问题,测试的时候出现依赖升级问题,由于测试同学是重新换了个机子,重装了环境,导致下载过程中依赖升级。npm带来便利的时候也带一些问题。如果您觉得比较啰嗦,直接看结果。

我们的vue项目最早依赖2.1.8版本做了组件和项目,为了保证产品的稳定性,决定锁死版本。可以参考这篇文章,介绍了框架升级分析的方法。

如果你也是使用vue可能需要注意以下依赖:

1
2
3
4
"vue-loader": "9.9.5",
"vue-style-loader": "1.0.0",
"vue": "2.1.8",
"vue-template-compiler": "2.1.8"

针对这种依赖升级解决方法:

  1. 只发布编译后的文件

这样测试同学就无需关心,升级依赖后再重新打包发布。

优点: 测试同学无需关注依赖安装
缺点: 产出目录充斥着各种版本的文件,增量存储repo越来越大

  1. 不通过包管理工具,直接把 node_modules打包,测试环境解压,每次升级依赖重新发布

开发直接把 node_modules 打成tar包, 部署的时候解压然后,再通过 npm run test打包测试. 一般现在一个项目一个node_modules打包后几十M(gzip之后),更新依赖之后解压。

好处: 无网络
坏处: 有一些c++的npm包,在不同的系统环境下是不同的,因此在osx下的node_modules,在Ubuntu失效。 好在我们的项目没有这种依赖包,所以也可以做一种方案。若有c++的包,则需要在本地装虚拟环境,如vagrantdocker跑测试对应的环境. 每当此时心里总是在想,咱还是前端开发吗[捂脸]

  1. 包管理工具锁死

node发展历程中出现了几种方式来做版本锁定, 以下面package.json为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "npm-lock",
"version": "0.0.1",
"description": "test dependies lock way",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "[email protected]",
"license": "MIT",
"devDependencies": {},
"dependencies": {
"vue": "^2.2.0"
}
}

没有下列命令的情况下, 查看 vue版本是 2.5.9, npm outdate没有输出,也就是最新版本。以下是三种锁定版本的方案,如果觉得文章啰嗦,可以直接查看表格比较:

- npm-shrinkwrap.json package-lock.json yarn.lock
命令 npm shrinkwrap
生成方式 需要命令生成 npm安装自动生成 yarn安装自动生成
npm版本 任意 >=5.0.0 任意
额外安装 yarn
增加依赖 npm i -S [email protected] && npm shrinkwrap npm i -S [email protected] yarn add [email protected]
更新 npm uni -S vue && npm I -S [email protected] npm uni -S vue&& npm i -S [email protected] yarn upgrade [email protected]
删除 npm uni -S vue npm uni -S vue yarn remove vue
发布 支持 不支持 支持
离线 不支持 不支持 支持
缓存 不支持 不支持 支持

npm shrinkwrap

为了确保我们使用的vue版本是2.2.0, 删除依赖,重新下载. 以下测试环境参数:

node: v6.10.2
npm: 3.10.10

npm i [email protected] -S, 查看node_modules vue版本是2.2.0

npm官方提供 npm shrinkwrap命令,生成 npm-shrinkwrap.json文件。

下面对依赖做增加,删除,修改的操作,看看 npm-shrinkwrap.json变化

1. 增加依赖

npm i [email protected] -S, npm-shrinkwrap.json 自动将vue-http及其依赖添加进去

2. 删除依赖
npm uni vue-http -S, 删除的时候自动删除npm-shrinkwrap.json中的vue-http及其依赖; 若忘了加 -S 或 -D, 则无法删除, 不够智能。

3. 升级/降级依赖

npm up [email protected] -S ,升级依赖,依赖没有升级,npm-shrinkwrap.json无更新,略显鸡肋。所以更新的话,直接通过上述方式删除,再添加吧。

4. 结果

把node_modules删掉,npm i, 依赖完美下载成功。

优点:npm天然支持
缺点:需要手动触发,update不生效

yarn

重新把npm shrinkwrap验证逻辑跑一遍.

1. 新增依赖

yarn add [email protected] [email protected]的时候,自动生成了 yarn.lock文件及其相关依赖

2. 删除依赖

yarn remove vue-http, 自动删除依赖

3. 更新依赖

yarn upgrade [email protected], 依赖更新成功, yarn.lock版本更新成功

4. 结果

把node_modules删掉,npm i, 依赖完美下载成功。更重要的是, yarn会在本地缓存一份依赖,存储在 $HOME/.yarn-cache目录下,

存储文件的规则是: registry-package_name-version,下载前会检查缓存中是否命中,若命中直接从本地获取,因此速度更快。

优点: 通过yarn命令操作,可以自动更新yarn.lock,从缓存中读取速度快. 支持离线模式
缺点: 还需要在下载一个yarn命令

package-lock.json

package-lock.json是npm 5.0之后, 对应的node版本是8.0.0, npm下载的时候会自动的出现在目录中. 将Node升级到8.0.0进行以上测试.

1. 增加依赖

npm i [email protected] -S, 自动生成的package-lock.json 自动将vue-http及其依赖添加进去

2. 删除依赖
npm uni vue-http -S, 删除的时候,自动删除package-lock.json中的vue-http及其依赖; 不需要加 -S -D

3. 升级/降级依赖

npm up [email protected] -S ,升级依赖,依赖没有升级,package-lock.json无更新,。所以更新的话,直接通过上述方式删除,再添加吧。是npm update的问题

4. 结果

把node_modules删掉,npm i, 依赖完美下载成功。

优点:npm天然支持, 比较智能。
缺点:只有npm5.0之后支持,若低于8.0.0版本的node需要手动下载npm5. 另外package-lock.json不能发包。 因此官方给出可以通过 npm shrinkwrappackage-lock.json重命名为 npm-shrinkwrap.json.

总结

对比总结,采用yarn管理,好处除了安装一个依赖之后,版本锁定智能,下载一次后速度快。yarn使用的包也是npm上的包可以在各个node版本中使用。

推荐阅读