您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Yarn 依赖与版本

包依赖对包的成功至关重要。 你很可能会用到其他包里已有的来开发自己包的。 那些“其他包”称为项目依赖。

所以依赖都在 package.json 里声明,包含开发依赖、运行依赖、可选依赖等。 每个依赖都需要指明依赖和最低可用版本。

yarn.lock 里保存了每个依赖的安装版本,这可以确保你的包每次安装的一致性。

不同的依赖有着不同的目的。 开发构建时需要一部分,程序运行时也需要一部分。 因此有着不同的依赖类型(比如 dependencies、devDependencies 和 peerDependencies)。

package.json 可以包含以下依赖类型:

{
  "name": "my-project",
  "dependencies": {
    "package-a": "^1.0.0"
  },
  "devDependencies": {
    "package-b": "^1.2.1"
  },
  "peerDependencies": {
    "package-c": "^2.5.4"
  },
  "optionalDependencies": {
    "package-d": "^3.1.0"
  }
}

大多数情况下只会用到 dependencies 和 devDependencies,但这些类型都很重要。

这是所谓的常规依赖,确切地说,是运行时所需要的(比如 React 和 immutableJS)。

这是开发依赖,就是那些只在开发过程中需要,而运行时不需要的依赖(比如 Babel 和 Flow)。

这是“同伴依赖”,一种特殊的依赖,在发布包的时候需要。

有这种依赖意味着安装包的也需要和包同样的依赖。 这对于像 react 这样也被人安装的、需要单一 react-dom 副本的包很有用。

这是可选依赖,意味着依赖是……可选的。这种依赖即便安装失败,Yarn也会认为整个依赖安装过程是成功的。

这种类型适用于那些即便没有成功安装可选依赖,也有后备方案的情况(比如 Watchman)。

这是“打包依赖”,在发布包时,这个数组里的包都会被打包(Bundle)。

这种类型的依赖应该在项目内部使用,基本上和普通依赖相同。执行 yarn pack 同样会进行打包。

普通依赖通常从 npm registry 安装,这些情况下,打包依赖比普通依赖更好用:

当你想使用不在 npm registry 里的,或者被过的第三方库时;

当你想把自己的项目作为模块来重用时;

当你想和你的模块一起发布一些时。

语义化版本

Yarn 里的包遵守 ,也叫 “semver”。 当你从资源库安装新包,它会和语义版本范围一起被到你的 package.json。

版本号可以划分为 主版本号.次版本号.修订号,类似这些: 3.14.1、 0.42.0、 2.7.18。 不同的情况对应不同的版本号增长:

主版本号:新的版本不兼容老版本的 API

次版本号:新的版本新增了部分,并向下兼容

修订号:新的版本修复了部分bug,并向下兼容

注意: 有时语义版本也会包含一些“”或者“扩展”,用于预发布版本或者测试版本,比如 2.0.0-beta.3。

开发者所说的“兼容”通常表示新的版本“向下兼容”(次版本号和修订号)。

版本范围

请在 package.json 里同时使用依赖和其版本范围来指明所需要的依赖:

{
  "dependencies": {
    "package-1": ">=2.0.0 <3.1.4",
    "package-2": "^0.4.2",
    "package-3": "~2.7.1"
  }
}

你一定注意到了除版本号外的那些特殊字符。 这些字符有 >=,<,^和~,它们是运算符,用来指定版本范围。

版本范围的用处是标明依赖的哪个版本会在中起作用。

每个版本范围组成 比较器。这些比较器是简单 运算符 后面跟着 版本号。以下是一些基本的运算符:

注意:如果没有明确指定运算符,那么版本范围认为 =,也就是说 = 是可选的。

用空格连接若干比较器可以创建 比较器集合。 最终版本范围是它包含的比较器的交集。 例如,比较器集合 >=2.0.0 <3.1.4 表示“大于或等于 2.0.0 并小于 3.1.4”。

完整的版本范围可以包含多个用 || 连接的比较器集合的并集。 如果并集的任何一边满足条件,整个版本范围就满足条件。 例如,版本范围 <2.0.0 || >3.1.4 意味着“小于 2.0.0 或者大于 3.1.4”。

版本号也可以包含预发布(比如 3.1.4-beta.2)。 如果比较器包含有预发布的版本,它将只匹配有相同 major.minor.patch 的版本。

例如,版本范围 >=3.1.4-beta.2 将匹配 3.1.4-beta.2 或 3.1.4-beta.12,但不会匹配 3.1.5-beta.1,即使在理论上 3.1.5-beta.1版本 “大于或等于” (>=) <0>3.1.4-beta.2</0> 版本。

预发布版本通常包含一些不兼容的,而且通常你也不会愿意匹配到指定版本之外的预发布版本,所以上述匹配规则很有用。

连字符范围(例如 2.0.0 - 3.1.4)标明了包含集合。数字 0 会被用来填充版本号中缺少的那些部分(例如 0.4 或 2)。

字符 X、x 或者 * 都可以作为符,用于填充部分或全部版本号。

被省略的那部分版本号认为 x 范围。

同时使用字符 ~ 和次版本号,表明允许修订号变更。同时使用字符 ~ 和主版本号,表明允许次版本号变更。

注意︰在波浪号范围中指定预发布版本将只匹配和它完整版本号相同的预发布版本。 例如,版本范围 ~3.1.4-beta.2 会匹配 3.1.4-beta.4 但不匹配 3.1.5-beta.2,因为 major.minor.patch 版本不同。

字符 ^ 表明不会版本号中的第非零数字,3.1.4 里的 3 或者 0.4.2 里的 4。

注意︰yarn add [package-name] 命令认使用 ^ 范围。

版本号中缺少的部分将被 0 填充,且在匹配时这些位置允许改变。

语义版本系统的完整规范: 。

用真实的包测试语义版本:。

package.json 里的 resolutions 字段用于解析选择性版本,可以通过此依赖版本。 这通常需要手动编辑 yarn.lock 。

有些时候,项目会依赖不常更新的包,但这个包又依赖另需要立即的包。 这时候,如果这个(不常更新的)包的依赖列表里不包含需要的包的新版本,那就只能等待作者,没别的办法。

项目的子依赖(依赖的依赖)需要紧急安全更新,来不及等待直接依赖更新。

项目的直接依赖还可以正常工作但已经停止维护,这时子依赖需要更新。 同时,你清楚子依赖的更新不会影响现有系统,但是又不想通过 fork 的方式来直接依赖。

项目的直接依赖定义了过于宽泛的子依赖版本范围,恰巧这其中的某个版本有问题,这时你想要把子依赖限制在某些正常工作的版本范围里。

在 package.json 里 resolutions 字段,用于覆盖版本定义:

package.json

{
  "name": "project",
  "version": "1.0.0",
  "dependencies": {
    "left-pad": "1.0.0",
    "c": "file:../c-1",
    "d2": "file:../d2-1"
  },
  "resolutions": {
    "d2/left-pad": "1.1.1",
    "c/**/left-pad": "1.1.2"
  }
}

之 yarn install。

如果定义了无效的版本解析规则,比如错写了无效的包名,会收到警告。

如果定义的版本解析的版本号、版本范围无效,也会收到警告。

如果定义的版本解析规则的版本号、版本范围与原始版本范围不兼容,同样会收到警告。

嵌套包机制(Nested packages)可能会挂。

这是一项新,因此会在某些极端情况下挂掉。


联系我
置顶