helinjiang

2016-04-29 23:25

npm 中如何下载特定的组件版本

本文作者:IMWeb helinjiang 原文出处:IMWeb社区 未经同意,禁止转载

本文详细讨论了 npm 中依赖版本的版本号配置写法及比较。

1. 开篇

为了更好的进行说明,我们选择了 lodash 来演示,因为它是被其他模块依赖最多的模块之一。本文是在 windows 7 64位系统中进行测试,npm 版本为 v3.8.1,其他的平台和 npm 版本在某些提示上可能会稍有不同。

运行 npm install lodash --save 命令,安装下载 loadash,此时 package.json 文件中会是这个样子的:

{
  "name": "test",
  "dependencies": {
    "lodash": "^4.11.1"
  }
}

有没注意到那个 ^4.11.14.11.1 是版本号很容易理解(这里只是当前的最新版本,后续 loadash 版本更新之后可能会有变化),前面的 ^ 符号是什么鬼?你甚至还见过这样的 ~4.11.14.11.1<4.11.1 等写法,都有什么区别?

2. 语义化的版本控制

在进入主题之前,我们得先了解一个很重要的概念,就是语义化的版本控制(Semantic Versioning Specification (SemVer)),目前的版本为 v2.0.0。具体规则请看官网文档,这里只是简单介绍。

语义化版本格式为:主版本号.次版本号.修订号,例如 4.11.1,版本号递增规则如下:

  1. 主版本号:当你做了不兼容的 API 修改,
  2. 次版本号:当你做了向下兼容的功能性新增,
  3. 修订号:当你做了向下兼容的问题修正。

我们先假设所有的 npm 包的版本命名都符合这个规范,这是讨论的基础。

3. 版本号的配置写法

package.json 文件中,我们配置 dependencies 等依赖关系时,有几种配置方式。

3.1 ^ (caret,插入符)和 ~ (tilde,波浪符)

^ (caret,插入符)和 ~ (tilde,波浪符)是我们见得最多的,也是最容易迷惑的,我们放在一起来对比,就会更明白些。除了在 package.json 中直接指定之外,我们也可以运行 npm install lodash@^3.3.0npm install lodash@~3.3.0 来直接安装。

3.1.1 含义和对比

用法举例 含义 范围 备注
^4.11.1 Compatible with 4.11.1 4.11.1 <= version < 5.0.0
4.x.x>=4.11.1
主版本号不变
~4.11.1 Reasonably close to 4.11.1 4.11.1 <= version < 4.12.0
4.11.x>=4.11.1
主版本号和次版本号都不变

很难用准确的词去翻译它们的含义,自己去查字典吧。

从其定义来看,使用 ^ 会更激进,因为它会获得“尽可能新的且能够保持兼容性的版本”;而使用 ~ 会更温和更保险,因为它会获得“尽可能靠近指定版本的升级版本”。

当它们也有共同点:

  • 当通过这两种方式获取的结果中,主版本号一定是不变的,因为主版本号意味这 API 不兼容。
  • 可选版本的最低版本号都是大于或等于指定的版本,不能比它还低;如果在该范围内没有任何版本,则会报错如下。

3.1.2 例外场景 0.x.x

任何规则都有例外。0.x.x 版本意味着“Anything can change at any time.”。主版本号为 0是为了做快速开发。在版本成型之前,开发者可以任意更改其代码,甚至做不兼容的变更而不受约束,然后通过修改次要版本,来控制版本;如果你的软件被用于正式环境,或已经有了稳定的 API 被使用者依赖,则将其升级到 1.0.0 版本或以上。

因此,针对 0.x.x,指定其依赖版本号时会更趋于谨慎,而 ^ 的行为也变得和 ~ 一样了。例如 ^0.3.0~0.3.0 取值都是 0.3.0 <= version < 0.4.0

3.1.3 自测一下

我们以 lodash 为例,这里有几份测试用例,如果你都能算对,那么说明你明白了其中的区别了。为了便于讨论,我们先列出 lodash 的所有有效版本,运行命令 npm view lodash versions,获得结果如下:

[ '0.1.0', '0.2.0', '0.2.1', '0.2.2', '0.3.0', '0.3.1', '0.3.2', '0.4.0', '0.4.1', '0.4.2', '0.5.0-rc.1', '0.5.0', '0.5.1', '0.5.2', '0.6.0', '0.6.1', '0.7.0', '0.8.0', '0.8.1', '0.8.2', '0.9.0', '0.9.1', '0.9.2', '0.10.0', '1.0.0-rc.1', '1.0.0-rc.2', '1.0.0-rc.3', '1.0.0', '1.0.1', '1.0.2', '1.1.0', '1.1.1', '1.2.0', '1.2.1', '1.3.0', '1.3.1', '2.0.0', '2.1.0', '2.2.0', '2.2.1', '2.3.0', '2.4.0', '2.4.1', '2.4.2', '3.0.0', '3.0.1', '3.1.0', '3.2.0', '3.3.0', '3.3.1', '3.4.0', '3.5.0', '3.6.0', '3.7.0', '3.8.0', '3.9.0', '3.9.1', '3.9.2', '3.9.3', '3.10.0', '3.10.1', '4.0.0', '4.0.1', '4.1.0', '4.2.0', '4.2.1', '4.3.0', '4.4.0', '4.5.0', '4.5.1', '4.6.0', '4.6.1', '4.7.0', '4.8.0', '4.8.1', '4.8.2', '4.9.0', '4.10.0', '4.11.0', '4.11.1' ]
测试用例 返回结果
^4.11.2 error
~4.11.2 error
^4.8.1 4.11.1
~4.8.1 4.8.2
^3.9.1 3.10.1
~3.9.1 3.9.3
^3.8.3 3.10.1
~3.8.3 error
^0.3.0 0.3.2
~0.3.0 0.3.2

3.1.4 "npm install xx --save" 不再使用 ~

npm 版本 在 v1.4.3 做了一次更新 (Node v0.10.26(Stable)开始将 npm 升级到 v1.4.3), npm install xx --save 之后,保存在 package.json 文件中的依赖版本号前面,将使用 ^ (caret,插入符),而不是 ~ (tilde,波浪符)。

Default npm install --save and its counterparts to use the ^ version specifier, instead of ~. (0a3151c,@mikolalysenko)

3.2 大于或小于指定版本

使用大于号(>)或小于号(<)的场景会比较少见,但 npm 也是支持的,

用法举例 含义 范围
>4.11.1 大于 4.11.1 的最新版本 version > 4.11.1
<4.11.1 小于 4.11.1 的最新版本 version < 4.11.1
测试用例 返回结果
>3.8.1 4.11.1
<3.8.1 3.8.0

3.3 等于指定版本

可以使用等号(=),也可以不写。即 "lodash":"=3.8.0""lodash":"3.8.0" 是一样的意思。我们也可以通过 npm install lodash@3.8.0 来安装指定版本。

更多阅读

2条评论

    您需要 注册 一个IMWeb账号或者 才能进行评论。