• Node.js 依赖管理(二)—版本号管理1.x.x


    原文链接:https://www.novenblog.xin/detail/?id=67

    本文拜读百度@小蘑菇哥哥Node.js 中的依赖管理正文从这里开始~

    在引入某个依赖项时,采用如下代码:

    npm i xxx -D 或 npm i xxx -S

    如果没有明确的指定xxx的引用版本,则会默认安装最新版本的包,等同于:

     npm i xxx@latest -D

    最后生成的package.json中的依赖项版本如下:

    以a.b.c举例,详解版本号

    a.b.c版本号的含义如下:

    a - 主要版本(也叫大版本,major version)

    大版本的升级很可能意味着与低版本不兼容的 API 或者用法,是一次颠覆性的升级(想想 webpack 3 -> 4)。

    b - 次要版本(也叫小版本,minor version)

    小版本的升级应当兼容同一个大版本内的 API 和用法,因此应该对开发者透明。所以我们通常只说大版本号,很少会精确到小版本号。

    特殊情况是如果大版本号是 0 的话,意味着整个包处于内测状态,所以每个小版本之间也可能会不兼容。所以在选择依赖时,尽量避开大版本号是 0 的包。

    c - 补丁 (patch)

    一般用于修复 bug 或者很细微的变更,也需要保持向前兼容。

     

    之后我们看一下常规的版本号写法:

    “1.2.3” - 无视更新的精确版本号

    表示只依赖这个版本,任何其他版本号都不匹配。在一些比较重要的线上项目中,我比较建议使用这种方式锁定版本。前阵子的 npm 挖矿以及 ant-design 彩蛋,其实都可以通过锁定版本来规避问题(彩蛋略难一些,挖矿是肯定可以规避)。

     

    “^1.2.3” - 兼具更新和安全的折中考虑

    这是 npm i xxx —save 之后系统生成的默认版本号(^ 加上当前最新版本号),官方的定义是“能够兼容除了最左侧的非 0 版本号之外的其他变化”(Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple)。这句话很拗口,举几个例子大家就明白了:

    • “^1.2.3” 等价于 “>= 1.2.3 < 2.0.0”。即只要最左侧的 “1” 不变,其他都可以改变。所以 “1.2.4”, “1.3.0” 都可以兼容。

    • “^0.2.3” 等价于 “>= 0.2.3 < 0.3.0”。因为最左侧的是 “0”,所以这个不算,顺延到第二位 “2”。那么只要这个 “2” 不变,其他的都兼容,比如 “0.2.4” 和 “0.2.99”。

    • “^0.0.3” 等价于 “>= 0.0.3 < 0.0.4”。这里最左侧的非 0 只有 “3”,且没有其他版本号了,所以这个也等价于精确的 “0.0.3”。

    从这几个例子可以看出,^ 是一个更新和安全兼容的写法。一般大版本号升级到 1 就表示项目正式发布了,而 0 开头就表示还在测试版,这也是 ^ 区别对待两者的原因。

     

    “~1.2.3” - 比 ^ 更加安全的小版本更新

    关于 ~ 的定义分为两部分:如果列出了小版本号(第二位),则只兼容 patch(第三位)的修改;如果没有列出小版本号,则兼容第二和第三位的修改。我们分两种情况理解一下这个定义:

    “~1.2.3” 列出了小版本号(2),因此只兼容第三位的修改,等价于 “>= 1.2.3 < 1.3.0”。

    “~1.2” 也列出了小版本号,因此和上面一样兼容第三位的修改,等价于 “>= 1.2.0 < 1.3.0”。

    “~1” 没有列出小版本号,可以兼容第二第三位的修改,因此等价于 “>= 1.0.0 < 2.0.0”

    和 ^ 不同的是,~ 并不对 0 或者 1 区别对待,所以 “~0” 等价于 “>= 0.0.0 < 1.0.0”,和 “~1” 是相同的算法。比较而言,~ 更加谨慎。当首位是 0 并且列出了第二位的时候,两者是等价的,例如 ~0.2.3 和 ^0.2.3。

     

    在 nodejs 的上古版本(v0.10.26,2014年2月发布的),npm i —save 默认使用的是 ~,现在已经改成 ^ 了。这个改动也是为了让使用者能最大限度的更新依赖包。

    “1.x” 或者 “1.“ - 使用通配符
    这个比起上面那两个符号就好理解的多。x(大小写皆可)和
    的含义相同,都表示可以匹配任何内容。具体来说:

    “*” 或者 “” (空字符串) 表示可以匹配任何版本。

    “1.x”, “1.*” 和 “1” 都表示要求大版本是 1,因此等价于 “>=1.0.0 < 2.0.0”。

    “1.2.x”, “1.2.*” 和 “1.2” 都表示锁定前两位,因此等价于 “>= 1.2.0 < 1.3.0”。

    因为位于结尾的通配符一般可以省略,而常规也不太可能像正则那样把匹配符写在中间,所以大多数情况通配符都可以省略。使用最多的还是匹配所有版本的 * 这个了。

     

    “1.2.3-beta.2” - 带预发布关键词的,如 alpha, beta, rc, pr 等
    先说预发布的定义,我们需要以包开发者的角度来考虑这个问题。假设当前线上版本是 “1.2.3”,如果我作了一些改动需要发布版本 “1.2.4”,但我不想直接上线(因为使用 “~1.2.3” 或者 `^1.2.3” 的用户都会直接静默更新),这就需要使用预发布功能。因此我可能会发布 “1.2.4-alpha.1” 或者 “1.2.4-beta.1” 等等。

    理解了它诞生的初衷,之后的使用就很自然了。

    “>1.2.4-alpha.1”,表示我接受 “1.2.4” 版本所有大于1的 alpha 预发布版本。因此如 “1.2.4-alpha.7” 是符合要求的,但 “1.2.4-beta.1” 和 “1.2.5-alpha.2” 都不符合。此外如果是正式版本(不带预发布关键词),只要版本号符合要求即可,不检查预发布版本号,例如 “1.2.5”, “1.3.0” 都是认可的。

    “~1.2.4-alpha.1” 表示 “>=1.2.4-alpha.1 < 1.3.0”。这样 “1.2.5”, “1.2.4-alpha.2” 都符合条件,而 “1.2.5-alpha.1”, “1.3.0” 不符合。

    “^1.2.4-alpha.1” 表示 “>=1.2.4-alpha.1 < 2.0.0”。这样 “1.2.5”, “1.2.4-alpha.2”, “1.3.0” 都符合条件,而 “1.2.5-alpha.1”, “2.0.0” 不符合。

    版本号还有更多的写法,例如范围(a - b),大于小于号(>=a <b),或(表达式1 || 表达式2)等等,因为用的不多,这里不再展开。详细的文档可以参见 semver,它同时也是一个 npm 包,可以用来比较两个版本号的大小,以及是否符合要求等。

     

    下面是其他相关文章推荐:

  • 相关阅读:
    Ubuntu Mysql
    Ubuntu配置大全
    MyEclipse 手动安装 Subclipse 插件
    解决 Ubuntu 11.10 在 RTL8111/8168B 网卡下速度慢的问题
    Ubuntu 多硬盘 LVM 方式安装
    关于编码转换
    Ubuntu 安装时(initramfs) Unable to find a medium containing a live file system错误的解决
    关于 DirectShow 中各个例子的编译转换问题
    ubuntu 中文设置
    javascript 处理鼠标右键事件
  • 原文地址:https://www.cnblogs.com/luowen075/p/10362523.html
Copyright © 2020-2023  润新知