内容

包依赖项

依赖项是 Pub 包管理器 的核心概念之一。依赖项是您的包需要工作才能正常运行的另一个包。依赖项在您的 pubspec 中指定。您只需列出直接依赖项:您的包直接使用的软件。Pub 会为您处理 传递依赖项

此页面提供了有关如何指定依赖项的详细信息。最后列出了 包依赖项的最佳实践

概述

#

对于每个依赖项,您都需要指定您所依赖的包的名称以及您允许的该包的版本范围。您还可以指定 来源。来源告诉 Pub 如何找到该包。

例如,您可以使用以下格式指定依赖项

yaml
dependencies:
  transmogrify: ^1.0.0

此 YAML 代码创建了对 transmogrify 包的依赖项,使用默认的包存储库 (pub.dev) 并允许从 1.0.02.0.0 的任何版本(但不包括 2.0.0)。要了解此语法,请查看 版本约束

要指定 pub.dev 以外的来源,请使用 sdkhostedgitpath。例如,以下 YAML 代码使用 path 告诉 Pub 从本地目录获取 transmogrify

yaml
dependencies:
  transmogrify:
    path: /Users/me/transmogrify

下一节将描述每个依赖项来源的格式。

依赖项来源

#

Pub 可以使用以下来源来查找包

托管包

#

托管包是可以从 pub.dev 网站(或使用相同 API 的其他 HTTP 服务器)下载的包。以下是声明对托管包的依赖项的示例

yaml
dependencies:
  transmogrify: ^1.4.0

此示例指定您的包依赖于名为 transmogrify 的托管包,并且可以使用 1.4.0 到 2.0.0 之间的任何版本(但不包括 2.0.0 本身)。

如果您想使用 您自己的包存储库,则可以使用 hosted 指定其 URL。以下 YAML 代码使用 hosted 来源创建对 transmogrify 包的依赖项

yaml
environment:
  sdk: '^2.19.0'

dependencies:
  transmogrify:
    hosted: https://some-package-server.com
    version: ^1.4.0

版本约束是可选的,但建议使用。如果未提供版本约束,则假定为 any

Git 包

#

有时您需要使用尚未正式发布的包,处于开发的最前沿。也许您的包本身仍在开发中,并且正在使用同时开发的其他包。为了简化操作,您可以直接依赖于存储在 Git 存储库中的包。

yaml
dependencies:
  kittens:
    git: https://github.com/munificent/kittens.git

此处的 git 表示此包是使用 Git 找到的,后面的 URL 是可用于克隆该包的 Git URL。

即使包存储库是私有的,如果您能够 使用 SSH 连接到存储库,那么您可以使用存储库的 SSH URL 依赖于该包

yaml
dependencies:
  kittens:
    git: [email protected]:munificent/kittens.git

如果您想依赖于特定的提交、分支或标签,请向描述中添加 ref

yaml
dependencies:
  kittens:
    git:
      url: [email protected]:munificent/kittens.git
      ref: some-branch

ref 可以是 Git 允许用于 标识提交的任何内容

Pub 假设该包位于 Git 存储库的根目录中。要指定存储库中不同的位置,请指定相对于存储库根目录的 path

yaml
dependencies:
  kittens:
    git:
      url: [email protected]:munificent/cats.git
      path: path/to/kittens

该路径相对于 Git 存储库的根目录。

Git 依赖项不允许作为上传到 pub.dev 的包的依赖项。

路径包

#

有时您会发现自己同时处理多个相关的包。也许您正在创建框架,同时构建使用该框架的应用。在这些情况下,在开发期间,您确实希望依赖于本地文件系统上该包的实时版本。这样一来,一个包中的更改就会立即被依赖于它的包获取。

为了处理这种情况,Pub 支持路径依赖项

yaml
dependencies:
  transmogrify:
    path: /Users/me/transmogrify

这表示 transmogrify 的根目录为 /Users/me/transmogrify。对于此依赖项,Pub 会直接生成指向引用的包目录的 lib 目录的符号链接。您对依赖包所做的任何更改都会立即显示。您无需在每次更改依赖包时都运行 Pub。

允许使用相对路径,并且将其视为相对于包含您的 pubspec 的目录。

路径依赖项对于本地开发很有用,但在与外部世界共享代码时不起作用——并非每个人都可以访问您的文件系统。因此,如果您的 pubspec 中有任何路径依赖项,则无法将包上传到 pub.dev 网站

相反,典型的工作流程如下

  1. 编辑您的本地 pubspec 以使用路径依赖项。
  2. 处理主包及其依赖的包。
  3. 两者都工作正常后,发布依赖包。
  4. 更改您的 pubspec 以指向其依赖项的现在托管的版本。
  5. 如果需要,也可以发布您的主包。

SDK

#

SDK 来源用于与包一起提供的任何 SDK,这些 SDK 本身也可能是依赖项。目前,Flutter 是唯一支持的 SDK。

语法如下所示

yaml
dependencies:
  flutter_driver:
    sdk: flutter

sdk: 后的标识符指示包来自哪个 SDK。如果它是 flutter,则只要满足以下条件,依赖项就可以得到满足

  • Pub 在 flutter 可执行文件的上下文中运行
  • Flutter SDK 包含具有给定名称的包

如果它是未知标识符,则始终认为依赖项不满足。

版本约束

#

假设您的包 A 依赖于包 B。您如何向其他开发人员传达包 B 的哪个版本与给定版本的包 A 保持兼容?

要让开发人员了解版本兼容性,请指定版本约束。您希望允许尽可能广泛的版本范围,以使您的包用户能够灵活选择。该范围应排除无法正常工作或尚未测试的版本。

Dart 社区使用语义版本控制1

您可以使用传统语法或从 Dart 2.19 开始的脱字符号语法来表达版本约束。两种语法都指定了一系列兼容版本。

传统语法提供了一个明确的范围,例如 '>=1.2.3 <2.0.0'。脱字符号语法提供了一个明确的起始版本 ^1.2.3

yaml
environment:
  # This package must use a 3.x version of the Dart SDK starting with 3.2.
  sdk: ^3.2.0

dependencies:
  transmogrify:
    hosted:
      name: transmogrify
      url: https://some-package-server.com
    # This package must use a 1.x version of transmogrify starting with 1.4.
    version: ^1.4.0

要了解有关 pub 版本系统的更多信息,请参阅包版本控制页面

传统语法

#

使用传统语法的版本约束可以使用以下任何值

允许使用?备注
any所有版本用作空版本约束的显式声明。
1.2.3仅给定版本由于它对使用您包的应用施加了额外的限制,因此限制了对您包的采用。
>=1.2.3给定版本或更高版本
>1.2.3高于给定版本的版本
<=1.2.3给定版本或更低版本
<1.2.3低于给定版本的版本当您知道一个与您的包兼容的上限版本时,请使用此版本。此版本可能是第一个引入某些重大更改的版本。

您可以将任何版本的组合指定为它们的范围相交。例如,如果您将版本值设置为'>=1.2.3 <2.0.0',则将这两个限制组合起来,因此依赖项可以是1.2.32.0.0(不包括2.0.0本身)的任何版本。

脱字符号语法

#

脱字符号语法以简洁的方式表达版本约束。^version表示所有保证与给定版本向后兼容的版本的范围。此范围将包括所有版本,直到下一个引入重大更改的版本。由于 Dart 使用语义版本控制,因此对于任何 1.0 或更高版本的包版本,这将是下一个主要版本;对于任何低于 1.0 的包版本,这将是下一个次要版本。

版本值范围覆盖到脱字符号语法传统语法
>=1.0下一个主版本^1.3.0'>=1.3.0 <2.0.0'
<1.0下一个次要版本^0.1.2'>=0.1.2 <0.2.0'

以下示例显示了脱字符号语法

yaml
dependencies:
  # Covers all versions from 1.3.0 to 1.y.z, not including 2.0.0
  path: ^1.3.0
  # Covers all versions from 1.1.0 to 1.y.z, not including 2.0.0
  collection: ^1.1.0
  # Covers all versions from 0.1.2 to 0.1.z, not including 0.2.0
  string_scanner: ^0.1.2

开发依赖项

#

Pub 支持两种类型的依赖项:常规依赖项和开发依赖项。开发依赖项与常规依赖项的不同之处在于,您依赖的包的开发依赖项将被忽略。这是一个示例

假设transmogrify包在其测试中(且仅在其测试中)使用test包。如果有人只想使用transmogrify(导入其库),则实际上并不需要test。在这种情况下,它将test指定为开发依赖项。其 pubspec 将包含类似以下内容:

yaml
dev_dependencies:
  test: ^1.25.0

Pub 获取您的包依赖的每个包,以及这些包依赖的所有内容(传递性)。它还会获取您的包的开发依赖项,但它会忽略任何依赖包的开发依赖项。Pub 仅获取的包的开发依赖项。因此,当您的包依赖于transmogrify时,它将获取transmogrify,但不会获取test

决定使用常规依赖项还是开发依赖项的规则很简单:如果从libbin目录中的某些内容导入依赖项,则需要将其作为常规依赖项。如果仅从testexample等导入,则可以也应该将其作为开发依赖项。

使用开发依赖项可以使依赖关系图更小。这使得pub运行更快,并且更容易找到满足所有约束的一组包版本。

依赖项覆盖

#

您可以使用dependency_overrides临时覆盖对依赖项的所有引用。

例如,也许您正在更新已发布包 transmogrify 的本地副本。Transmogrify 由依赖关系图中的其他包使用,但您不想在本地克隆每个包并更改每个 pubspec 以测试您本地副本的 transmogrify。

在这种情况下,您可以使用dependency_overrides覆盖依赖项,以指定包含包本地副本的目录。

pubspec 将如下所示

yaml
name: my_app
dependencies:
  transmogrify: ^1.2.0
dependency_overrides:
  transmogrify:
    path: ../transmogrify_patch/

当您运行dart pub getdart pub upgrade时,pubspec 的锁定文件将更新以反映到依赖项的新路径,并且无论在哪里使用 transmogrify,pub 都将使用本地版本。

您还可以使用dependency_overrides指定包的特定版本

yaml
name: my_app
dependencies:
  transmogrify: ^1.2.0
dependency_overrides:
  transmogrify: '3.2.1'

在包解析期间,包自己的 pubspec中的依赖项覆盖才会被考虑。任何被依赖包中的依赖项覆盖都会被忽略。

因此,如果您将包发布到 pub.dev,请记住,您的包的依赖项覆盖会被所有使用您包的用户忽略。

最佳实践

#

积极管理您的依赖项。尽可能确保您的包依赖于最新版本的包。如果您的包依赖于过时的包,则该过时的包可能在其依赖树中依赖于其他过时的包。过时的包版本可能会对应用程序的稳定性、性能和质量产生负面影响。

我们建议遵循以下包依赖项最佳实践。

使用脱字符号语法

#

使用脱字符号语法指定依赖项。这允许 pub 工具在可用时选择较新版本的包。此外,它还在允许的版本上设置了上限。

依赖于最新的稳定包版本

#

使用dart pub upgrade更新到您的 pubspec 允许的最新包版本。要识别应用程序或包中未处于最新稳定版本的依赖项,请使用dart pub outdated

收紧开发依赖项的版本约束

#

开发依赖项定义了仅在开发时才需要的包。已完成的应用程序不需要这些包。这些包的示例包括测试或代码生成工具。将dev_dependencies中包的版本约束设置为您的包依赖的最新版本的最低限度。

收紧开发依赖项的版本约束可能类似于以下内容

yaml
dev_dependencies:
  build_runner: ^2.4.12
  lints: ^2.1.1
  test: ^1.25.8

此 YAML 将dev_dependencies设置为最新的补丁版本。

更新包依赖项时进行测试

#

如果您运行dart pub upgrade而不更新您的 pubspec,则 API 应该保持不变,并且您的代码应该像以前一样运行(但请测试以确保)。如果您修改 pubspec 并更新到新的主版本,则可能会遇到重大更改,因此您需要进行更彻底的测试。

使用降级后的依赖项进行测试

#

在开发用于发布的包时,通常最好允许尽可能宽松的依赖项约束。宽松的依赖项约束降低了包使用者遇到版本解析冲突的可能性。

例如,如果您对foo: ^1.2.3有依赖项,并且发布了foo的版本1.3.0,则保留现有依赖项约束 (^1.2.3) 可能是合理的。但是,如果您的包开始使用在1.3.0中添加的功能,则需要将约束提升到^1.3.0

但是,当需要时,很容易忘记提升依赖项约束。因此,最佳实践是在发布之前针对降级后的依赖项测试您的包。

要针对降级后的依赖项进行测试,请运行dart pub downgrade并验证您的包是否仍能在没有错误的情况下进行分析并通过所有测试

dart pub downgrade
dart analyze
dart test

使用降级后的依赖项进行测试应该与使用最新依赖项进行的常规测试一起进行。如果需要提升依赖项约束,请自行更改或使用dart pub upgrade --tighten将依赖项更新到最新版本。

验证下载的包的完整性

#

在检索新的依赖项时,请使用--enforce-lockfile选项以确保提取的包内容与原始存档的内容匹配。在不修改锁定文件的情况下,此标志仅在以下情况下解析新的依赖项:

  • pubspec.yaml已满足
  • pubspec.lock不存在
  • 包的内容哈希匹配