NPM 如何管理依赖包版本

Nodejs成功离不开 npm 优秀的依赖管理系统。在介绍整个依赖系统之前,必须要了解 npm如何管理依赖包的版本,本文将介绍 npm包 的版本发布规范以、何管理各种依赖包的版本以及一些关于包版本的最佳实践。

查看npm包版本

你可以执行 npm view package version 查看某个 package 的最新版本。

执行 npm view conard versions 查看某个 package 在npm服务器上所有发布过的版本。

执行 npm ls 可查看当前仓库依赖树上所有包的版本信息。

SemVer规范

npm包 中的模块版本都需要遵循 SemVer规范——由 Github 起草的一个具有指导意义的,统一的版本号表示规则。实际上就是 Semantic Version(语义化版本)的缩写。

SemVer规范官网:https://semver.org/

标准版本

SemVer规范的标准版本号采用 X.Y.Z 的格式,其中 X、Y 和 Z 为非负的整数,且禁止在数字前方补零。X 是主版本号、Y 是次版本号、而 Z 为修订号。每个元素必须以数值来递增。

主版本号(major):当你做了不兼容的API 修改

次版本号(minor):当你做了向下兼容的功能性新增

修订号(patch):当你做了向下兼容的问题修正。

例如:1.9.1 -> 1.10.0 -> 1.11.0

先行版本

当某个版本改动比较大、并非稳定而且可能无法满足预期的兼容性需求时,你可能要先发布一个先行版本。

先行版本号可以加到“主版本号.次版本号.修订号”的后面,先加上一个连接号再加上一连串以句点分隔的标识符和版本编译信息。

内部版本(alpha):

公测版本(beta):

正式版本的候选版本rc: 即 Release candiate

React的版本

下面我们来看看 React 的历史版本:

可见是严格按照 SemVer 规范来发版的:

版本号严格按照 主版本号.次版本号.修订号 格式命名

版本是严格递增的,:16.8.0 -> 16.8.1 -> 16.8.2

发布重大版本或版本改动较大时,先发布alpha、beta、rc等先行版本

发布版本

在修改 npm 包某些功能后通常需要发布一个新的版本,我们通常的做法是直接去修改 package.json 到指定版本。如果操作失误,很容易造成版本号混乱,我们可以借助符合 Semver 规范的命令来完成这一操作:

npm version patch : 升级修订版本号

npm version minor : 升级次版本号

npm version major : 升级主版本号

版本工具使用

在开发中肯定少不了对一些版本号的操作,如果这些版本号符合 SemVer规范 ,我们可以借助用于操作版本的npm包semver来帮助我们进行比较版本大小、提取版本信息等操作。

Npm 也使用了该工具来处理版本相关的工作。

npm install semver

比较版本号大小

semver.gt('1.2.3', '9.8.7') // false

semver.lt('1.2.3', '9.8.7') // true

判断版本号是否符合规范,返回解析后符合规范的版本号。

semver.valid('1.2.3') // '1.2.3'

semver.valid('a.b.c') // null

将其他版本号强制转换成semver版本号

semver.valid(semver.coerce('v2')) // '2.0.0'

semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'

一些其他用法

semver.clean('  =v1.2.3  ') // '1.2.3'

semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true

semver.minVersion('>=1.0.0') // '1.0.0'

以上都是semver最常见的用法,更多详细内容可以查看 semver文档:https://github.com/npm/node-semver

依赖版本管理

我们经常看到,在 package.json 中各种依赖的不同写法:

  "dependencies": {

    "signale": "1.4.0",

    "figlet": "*",

    "react": "16.x",

    "table": "~5.4.6",

    "yargs": "^14.0.0"

  }

前面三个很容易理解:

"signale": "1.4.0": 固定版本号

"figlet": "*": 任意版本(>=0.0.0)

"react": "16.x": 匹配主要版本(>=16.0.0 <17.0.0)

"react": "16.3.x": 匹配主要版本和次要版本(>=16.3.0 <16.4.0)

再来看看后面两个,版本号中引用了 ~ 和 ^ 符号:

~: 当安装依赖时获取到有新版本时,安装到 x.y.z 中 z 的最新的版本。即保持主版本号、次版本号不变的情况下,保持修订号的最新版本。

^: 当安装依赖时获取到有新版本时,安装到 x.y.z 中 y 和 z 都为最新版本。即保持主版本号不变的情况下,保持次版本号、修订版本号为最新版本。

在 package.json 文件中最常见的应该是 "yargs": "^14.0.0" 这种格式的 依赖, 因为我们在使用 npm install package 安装包时,npm 默认安装当前最新版本,然后在所安装的版本号前加 ^ 号。

注意,当主版本号为 0 的情况,会被认为是一个不稳定版本,情况与上面不同:

主版本号和次版本号都为 0: ^0.0.z、~0.0.z 都被当作固定版本,安装依赖时均不会发生变化。

主版本号为 0: ^0.y.z 表现和 ~0.y.z 相同,只保持修订号为最新版本。

1.0.0 的版本号用于界定公共 API。当你的软件发布到了正式环境,或者有稳定的API时,就可以发布1.0.0版本了。所以,当你决定对外部发布一个正式版本的npm包时,把它的版本标为1.0.0。

锁定依赖版本

lock文件

实际开发中,经常会因为各种依赖不一致而产生奇怪的问题,或者在某些场景下,我们不希望依赖被更新,建议在开发中使用 package-lock.json。

锁定依赖版本意味着在我们不手动执行更新的情况下,每次安装依赖都会安装固定版本。保证整个团队使用版本号一致的依赖。

每次安装固定版本,无需计算依赖版本范围,大部分场景下能大大加速依赖安装时间。

使用 package-lock.json 要确保npm的版本在5.6以上,因为在5.0 - 5.6中间,对 package-lock.json的处理逻辑进行过几次更新,5.6版本后处理逻辑逐渐稳定。

关于 package-lock.json 详细的结构,我们会在后面的章节进行解析。

定期更新依赖

我们的目的是保证团队中使用的依赖一致或者稳定,而不是永远不去更新这些依赖。实际开发场景下,我们虽然不需要每次都去安装新的版本,仍然需要定时去升级依赖版本,来让我们享受依赖包升级带来的问题修复、性能提升、新特性更新。

使用 npm outdated 可以帮助我们列出有哪些还没有升级到最新版本的依赖:

黄色表示不符合我们指定的语意化版本范围 - 不需要升级

红色表示符合指定的语意化版本范围 - 需要升级

执行 npm update 会升级所有的红色依赖。

依赖版本选择的最佳实践

版本发布

对外部发布一个正式版本的npm包时,把它的版本标为1.0.0。

某个包版本发行后,任何修改都必须以新版本发行。

版本号严格按照 主版本号.次版本号.修订号 格式命名

版本号发布必须是严格递增的

发布重大版本或版本改动较大时,先发布alpha、beta、rc等先行版本

依赖范围选择

主工程依赖了很多子模块,都是团队成员开发的npm包,此时建议把版本前缀改为~,如果锁定的话每次子依赖更新都要对主工程的依赖进行升级,非常繁琐,如果对子依赖完全信任,直接开启^每次升级到最新版本。

主工程跑在docker线上,本地还在进行子依赖开发和升级,在docker版本发布前要锁定所有依赖版本,确保本地子依赖发布后线上不会出问题。

保持依赖一致

确保npm的版本在5.6以上,确保默认开启 package-lock.json 文件。

由初始化成员执行 npm inatall 后,将 package-lock.json 提交到远程仓库。不要直接提交 node_modules到远程仓库。

定期执行 npm update 升级依赖,并提交 lock 文件确保其他成员同步更新依赖,不要手动更改 lock 文件。

依赖变更

升级依赖: 修改 package.json文件的依赖版本,执行 npm install

降级依赖: 直接执行 npm install package@version(改动package.json不会对依赖进行降级)

注意改动依赖后提交lock文件

参考

https://semver.org/lang/zh-CN/

http://deadhorse.me/nodejs/2014/04/27/semver-in-nodejs.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 《瘆人的蛇巷》 洄龍山书翁(原创) 小时,我们家住在一条深胡同里,这条胡同弯弯曲曲,既窄又长还很阴潮,人们称这胡同...
    金鷄書生阅读 1,881评论 15 77
  • 8月19——21日,妈妈带我去西安旅行,这是我期待很久的一天。 19日早上,我早早的就起床了,把所...
    王婧姝阅读 172评论 0 1
  • 文|笔迹 图|网络 朋友,你想象过母亲老了是什么样子吗? 我不敢想,也害怕去想。 从小就生活在农村,家庭不富裕,平...
    笔迹女孩阅读 304评论 0 1
  • 早上小雨。雨滴打在车窗,哔啵哔啵,哔啵哔啵,一寸一寸,蚕食着车内的寂静。向来不习惯与司机攀谈,也恰好约到一个安静的...
    哇啦哇啦119阅读 130评论 0 0