包依赖
依赖项是 pub 包管理器的核心概念之一。依赖项是你的包工作所需的另一个包。依赖项在你的 pubspec 中指定。你只列出直接依赖项:你的包直接使用的软件。Pub 会为你处理传递依赖项。
此页面包含有关如何指定依赖项的详细信息。最后列出了包依赖项的最佳实践。
概述
#对于每个依赖项,你指定你要依赖的包的名称和允许的该包的版本范围。你还可以指定来源。来源告诉 pub 如何定位包。
例如,你可以使用以下格式指定依赖项
dependencies:
transmogrify: ^1.0.0
此 YAML 代码创建了对 transmogrify
包的依赖,使用默认的包存储库 (pub.dev) 并允许从 1.0.0
到 2.0.0
的任何版本(但不包括 2.0.0
)。要了解此语法,请查看版本约束。
要指定 pub.dev 以外的来源,请使用 sdk
、hosted
、git
或 path
。例如,以下 YAML 代码使用 path
来告诉 pub 从本地目录获取 transmogrify
dependencies:
transmogrify:
path: /Users/me/transmogrify
下一节介绍每个依赖来源的格式。
依赖来源
#Pub 可以使用以下来源来定位包
托管包
#托管包是可以从 pub.dev 站点(或另一个说相同 API 的 HTTP 服务器)下载的包。以下是声明对托管包的依赖关系的示例
dependencies:
transmogrify: ^1.4.0
此示例指定你的包依赖于名为 transmogrify
的托管包,并且可以使用从 1.4.0 到 2.0.0 的任何版本(但不包括 2.0.0 本身)。
如果要使用你自己的包存储库,你可以使用 hosted
来指定其 URL。以下 YAML 代码使用 hosted
来源创建对 transmogrify
包的依赖
environment:
sdk: '^2.19.0'
dependencies:
transmogrify:
hosted: https://some-package-server.com
version: ^1.4.0
版本约束是可选的,但建议使用。如果未给出版本约束,则假定为 any
。
Git 包
#有时,你处于前沿,需要使用尚未正式发布的包。也许你的包本身仍在开发中,并且正在使用同时开发的其他包。为了使之更容易,你可以直接依赖存储在 Git 存储库中的包。
dependencies:
kittens:
git: https://github.com/munificent/kittens.git
此处的 git
表示使用 Git 找到此包,之后 URL 是可用于克隆包的 Git URL。
即使包仓库是私有的,你也可以配置你的 git
设置,以使用 HTTPS 访问密钥或SSH 密钥对来访问仓库。然后,你可以通过使用仓库的相应 URL 来依赖该包
dependencies:
kittens:
# SSH URL:
git: [email protected]:munificent/kittens.git
dart pub
命令将 git clone
作为子进程调用,因此你需要提供的只是在执行 git clone <url>
时有效的 <url>
。
如果要依赖特定的提交、分支或标签,请向描述添加 ref
键
dependencies:
kittens:
git:
url: [email protected]:munificent/kittens.git
ref: some-branch
ref 可以是 Git 允许的任何标识提交的内容。
Pub 假定包在 Git 存储库的根目录中。要指定存储库中不同的位置,请指定相对于存储库根目录的 path
dependencies:
kittens:
git:
url: [email protected]:munificent/cats.git
path: path/to/kittens
路径是相对于 Git 仓库的根目录的。
Git 依赖项不允许作为上传到 pub.dev 的包的依赖项。
路径包
#有时,你会发现自己同时处理多个相关的包。也许你在构建使用它的应用程序时正在创建一个框架。在这些情况下,在开发过程中,你真正希望依赖本地文件系统上该包的实时版本。这样,一个包中的更改会立即被依赖它的包获取。
为了处理这种情况,pub 支持路径依赖项。
dependencies:
transmogrify:
path: /Users/me/transmogrify
这表示 transmogrify
的根目录是 /Users/me/transmogrify
。对于此依赖项,pub 会生成一个直接指向所引用包目录的 lib
目录的符号链接。你对依赖包所做的任何更改都会立即看到。你无需每次更改依赖包时都运行 pub。
允许使用相对路径,并且将其视为相对于包含 pubspec 的目录。
路径依赖项对于本地开发很有用,但在与外界共享代码时不起作用——并非每个人都可以访问你的文件系统。因此,如果包的 pubspec 中有任何路径依赖项,则无法将该包上传到 pub.dev 站点。
相反,典型的工作流程是:
- 在本地编辑你的 pubspec 文件,使用路径依赖。
- 开发主包和它所依赖的包。
- 一旦它们都正常工作,发布被依赖的包。
- 修改你的 pubspec 文件,指向现在已托管的被依赖包的版本。
- 如果需要,也发布你的主包。
SDK
#SDK 源用于任何随包一起发布的 SDK,这些包本身也可能是依赖项。目前,仅支持 Flutter SDK。
语法如下:
dependencies:
flutter_driver:
sdk: flutter
sdk:
后的标识符表示包来自哪个 SDK。如果它是 flutter
,则只要满足以下条件,依赖项就是可满足的:
- Pub 在
flutter
可执行文件的上下文中运行 - Flutter SDK 包含具有给定名称的包
如果它是未知的标识符,则始终认为依赖项不满足。
版本约束
#假设你的 Package A 依赖于 Package B。你如何告知其他开发者 Package B 的哪个版本与 Package A 的给定版本兼容?
为了让开发者了解版本兼容性,请指定版本约束。你希望允许尽可能广泛的版本范围,以便为你的包用户提供灵活性。该范围应排除那些无法工作或未经测试的版本。
Dart 社区使用语义化版本控制1。
从 Dart 2.19 开始,你可以使用传统语法或插入符语法来表达版本约束。两种语法都指定了兼容版本的范围。
传统语法提供了一个明确的范围,如 '>=1.2.3 <2.0.0'
。插入符语法提供了一个明确的起始版本 ^1.2.3
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.3
到 2.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' |
以下示例显示插入符语法
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 文件将如下所示:
dev_dependencies:
test: ^1.25.0
Pub 获取你的包依赖的每个包,以及那些包传递依赖的任何内容。它还会获取你的包的开发依赖项,但它会忽略任何依赖包的开发依赖项。Pub 仅获取你的包的开发依赖项。因此,当你的包依赖于 transmogrify
时,它将获取 transmogrify
,但不会获取 test
。
在常规依赖项和开发依赖项之间做出决定的规则很简单:如果依赖项是从 lib
或 bin
目录中的内容导入的,则它需要是一个常规依赖项。如果仅从 test
、example
等导入,则它可以并且应该是一个开发依赖项。
使用开发依赖项可以缩小依赖关系图。这使得 pub
运行速度更快,并且更容易找到一组满足所有约束的包版本。
依赖覆盖
#你可以使用 dependency_overrides
来临时覆盖对依赖项的所有引用。
例如,也许你正在更新 transmogrify 的本地副本,这是一个已发布的包。transmogrify 被依赖关系图中的其他包使用,但你不想在本地克隆每个包并更改每个 pubspec 文件来测试 transmogrify 的本地副本。
在这种情况下,你可以使用 dependency_overrides
来覆盖依赖项,以指定保存包本地副本的目录。
pubspec 文件如下所示:
name: my_app
dependencies:
transmogrify: ^1.2.0
dependency_overrides:
transmogrify:
path: ../transmogrify_patch/
当你运行 dart pub get
或 dart pub upgrade
时,pubspec 文件的 lockfile 将更新以反映你的依赖项的新路径,并且无论在哪里使用 transmogrify,pub 都会使用本地版本。
你还可以使用 dependency_overrides
来指定包的特定版本
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
中包的版本约束设置为你的包依赖的最新版本的下限。
收紧你的开发依赖项的版本约束可能如下所示:
dev_dependencies:
build_runner: ^2.4.13
lints: ^2.1.1
test: ^1.25.8
此 YAML 将 dev_dependencies
设置为最新的补丁版本。
每次更新包依赖时都要进行测试
#如果你在不更新 pubspec 文件的情况下运行 dart pub upgrade
,则 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
选项来确保提取的包内容与原始存档的内容匹配。在不修改 lockfile 的情况下,此标志仅在以下情况下解析新的依赖项:
pubspec.yaml
已满足pubspec.lock
未缺失- 包的内容哈希匹配
除非另有说明,本网站的文档反映了 Dart 3.6.0。页面最后更新于 2024-12-11。 查看源代码 或 报告问题。