Dart 包版本如何工作以及我应该如何对我的 Flutter 插件进行版本控制?

How do Dart Package Versions work & how should I version my Flutter Plugins?

我想知道在我的 Flutter 应用程序中如何解析 Dart 包版本。

说,我有一个依赖项 foo 并像这样声明一个依赖项:

dependencies:
  foo: ^1.2.3

Dart Pub 如何知道要解析哪个版本/新版本可用时会发生什么?


另外,如果我想把我的Flutter插件发布到pub.dev,我如何决定什么时候增加哪个部分的版本?

Dart 包版本控制

所有这些都可以追溯到 Dart 包版本控制,即 Flutter 插件没有区别。

它基于SemVer 2.0.0-rc.1 (Semantic Versioning)。对于 Dart 包,公约的要点如下:

<1.0.0 >=1.0.0
0.major.minor+patch major.minor.patch

请注意,Pub 还支持预发布版本,表示为:

<1.0.0 >=1.0.0
0.major.0-prerelease.patch major.0.0-prerelease.patch

示例版本可能是 0.6.0-nullsafety.0(补丁版本 0.6.0-nullsafety.1)或 2.0.0-dev.1

Learn more about Dart's package versioning.

正在解析版本

要基本了解版本解析试图解决的问题,您可以通读 Resolving shared dependencies section of Dart's package versioning article. The aspect of version resolving that I will look at here is the caret syntax

Caret ^ 语法是 Dart 中解析版本的标准语法,与上面的版本控制 tables 密切相关。每当您使用 foo: ^1.0.0 定义依赖项时,都会涉及一些逻辑来确定可以从该字符串解析哪些版本。

一般来说,^ 匹配 直到主要版本 。这意味着每当您的 API 中有 重大更改 时,您将想要 bump 主版本 因为那时依赖者不会自动升级到您的下一个软件包版本。我将尝试再次说明 table 中的匹配:

^0.4.2+1 ^1.3.0
>=0.4.2+1 <0.5.0 >=1.3.0 <2.0.0

如您所见,caret 语法 将匹配任何大于或等于当前版本但小于下一个 major[=133 的版本=] 版本.

请注意,预发布版本在 Dart 中的处理方式与正常版本不同(不完全根据 SemVer 规范)。你可以找到 the source code for Pub's pub_semver tool on GitHub。它声明预发布版本与插入符语法匹配(并且既不与传统语法匹配):

^1.0.0 matches version?
1.4.2 yes
1.5.0-beta yes
2.0.0-alpha no
2.0.0 no

Learn more about Dart's package dependencies.

pubspec.lock

我很快想提一下 Pubspec 锁定文件 在 Dart 中解决依赖关系的作用。

我认为有一种直接的方式定义了如何获取包版本:

  • pub get 没有 退出 pubspec.lock(初始获取)将获取 最新可能的 版本(根据上述规则并满足共享依赖项的所有直接和传递约束)。
  • pub get with 现有的 pubspec.lock 文件将更喜欢锁定文件中的锁定版本而不是最新版本(如果它们仍然满足潜在新的约束自上次获取以来引入了依赖项)。
  • pub upgrade 丢弃现有的 pubspec.lock 文件,然后以与初始 pub get.
  • 相同的方式运行

因此,您应用中的 运行 pub get 不会意外获取新版本。并且在和同事一起工作的时候,大家在运行 pub get的时候,都会根据pubspec.lock的文件来获取相同的版本,并且在版本控制中包含了lock文件。

Learn more about lockfiles in Dart.

最佳实践

因为the Dart team recommends some best practices for versioning,我想确保直接将它们包含在这里:

Use caret syntax
Specifying dependencies with version ranges is such as ^1.6.3 is a good practice because it allows the pub tool to select newer versions of the package when they become available. Also, it places an upper limit on the allowed version, based on an assumption that packages use semantic versions, where any version of path versioned 1.x is compatible, but where a new version 2.x would be a major upgrade that isn’t semantically compatible with 1.x versions.

Depend on the latest stable package versions
Use pub upgrade to update to the latest package versions that your pubspec allows. To identify dependencies in your app or package that aren’t on the latest stable versions, use pub outdated.

Test whenever you update package dependencies
If you run pub upgrade without updating your pubspec, the API should stay the same and your code should run as before — but test to make sure. If you modify the pubspec and update to a new major version, then you might encounter breaking changes, so you need to test even more thoroughly.