迁移到空安全

Last updated: ... / Reads: 40 Edit

Dart 2.19 是支持空安全迁移的最终版本,包括 dart migrate 工具。要将包迁移到空安全,请使用 Dart 2.19.6 SDK。要了解更多信息,请参阅 Dart 3 和 null 安全性。

本页介绍如何以及何时将代码迁移到空安全。以下是迁移您拥有的每个包的基本步骤:

  1. 等待您依赖的包迁移。
  2. 迁移包的代码,最好使用交互式迁移工具。
  3. 静态分析你的包的代码。
  4. 进行测试以确保您的更改有效。
  5. 如果该包已在 pub.dev 上,则将空安全版本发布为预发布版本。

如果您的应用程序或库很大,请查看大型 Dart 项目的渐进空安全迁移。

迁移应用程序在技术上与迁移包相同。在迁移应用程序之前,请确保所有依赖项均已准备就绪。

1.等待迁移

我们强烈建议按顺序迁移代码,首先迁移依赖图的叶子。例如,如果包 C 依赖于包 B,包 B 又依赖于包 A,则应首先将 A 迁移到空安全,然后是 B,然后是 C。

null-safety-migration-order

尽管您可以在依赖项支持空安全之前进行迁移,但在依赖项迁移时您可能必须更改代码。例如,如果您预测某个函数将采用可为空参数,但包将其迁移为不可为空参数,则传递可为空参数将导致编译错误。

您可以而且应该在迁移依赖于您的包的包之前先迁移该包。您的 null 安全包可供尚未使用 null 安全的包和应用程序使用,只要它们使用 Dart 2.12 或更高版本即可。例如,Dart 和 Flutter 核心库是 null 安全的,并且它们仍然可以由尚未迁移​​到 null 安全的应用程序使用。

本节告诉您如何在空安全模式下借助 dart pub outdated 命令检查和更新包的依赖项。这些说明假定您的代码处于源代码控制之下,以便您可以轻松撤消任何更改。

切换到 Dart 2.19.6 版本

切换到 Dart SDK 2.19.6 版本。这包含在 Flutter 3.7.12 SDK 中。

检查您是否有 Dart 2.19.6:

dart --version
Dart SDK version: 2.19.6

检查依赖状态

使用以下命令获取包依赖项的迁移状态:

dart pub outdated --mode=null-safety

如果输出表明所有包都支持空安全,那么您可以开始迁移。否则,使用 Resolvable 列查找空安全版本(如果存在)。

为什么所有依赖项都需要支持空安全?当应用程序的所有直接依赖项都支持 null 安全性时,您可以以健全的 null 安全性运行应用程序。当所有开发依赖项都支持空安全时,您可以运行具有良好空安全性的测试。由于其他原因(例如代码生成),您可能还需要空安全开发依赖项。

这是一个简单包的输出示例。每个包的绿色复选标记版本都支持空安全:

pub-outdated-output

输出显示该包的所有依赖项都有支持 null 安全的可解析预发布。

如果您的包的任何依赖项尚不支持 null 安全性,我们鼓励您联系包所有者。您可以在 pub.dev 的包页面上找到联系方式。

更新依赖项

在迁移包的代码之前,请将其依赖项更新为空安全版本:

  1. 运行 dart pub upgrade --null-safety 升级到支持空安全的最新版本。注意:此命令会更改您的 pubspec.yaml 文件。
  2. 运行 dart pub get 。

2. 迁移

您的代码需要空安全的大多数更改都很容易预测。例如,如果变量可以是 null ,则其类型需要 ? 后缀。如果命名参数不应为空,请将其标记为 required 或为其指定默认值。

您有两种迁移选择:

  • 使用迁移工具,它可以为您轻松完成大部分可预测的更改。
  • 手动迁移您的代码。

提示:要在迁移代码时获得更多帮助,请查看 null 安全常见问题解答。

使用迁移工具

迁移工具采用 null 不安全的 Dart 代码包并将其转换为 null 安全。您可以通过向 Dart 代码添加提示标记来指导工具的转换。

在启动该工具之前,请确保您已准备好:

  • 使用 Dart SDK 2.19.6 版本。
  • 使用 dart pub outdated --mode=null-safety 确保所有依赖项都是空安全且最新的。

通过在包含包的 pubspec.yaml 文件的目录中运行 dart migrate 命令来启动迁移工具:

dart migrate

如果您的包已准备好迁移,则该工具会生成如下行:

View the migration suggestions by visiting:

  http://127.0.0.1:60278/Users/you/project/mypkg.console-simple?authToken=Xfz0jvpyeMI%3D

在 Chrome 浏览器中访问该 URL 以查看交互式 UI,您可以在其中指导迁移过程:

migration-tool

对于每个变量和类型注释,您可以查看该工具推断出的可为空性。例如,在前面的屏幕截图中,该工具推断第 1 行中的 ints 列表(以前是 int 的列表)可以为空,因此应该是 int? 。

了解迁移结果

要查看每个更改(或未更改)的原因,请在“建议的编辑”窗格中单击其行号。原因显示在“编辑详细信息”窗格中。

例如,考虑以下来自空安全之前的代码:

var ints = const <int>[0, null];
var zero = ints[0];
var one = zero + 1;
var zeroOne = <int>[zero, one];

当此代码位于函数外部(函数内不同)时,默认迁移是向后兼容的,但并不理想:

var ints = const <int?>[0, null];
var zero = ints[0];
var one = zero! + 1;
var zeroOne = <int?>[zero, one];

通过点击第3行链接,您可以看到迁移工具添加 ! 的原因。因为您知道 zero 不能为 null,所以可以改进迁移结果。

改善迁移结果 当分析推断出错误的可为空性时,您可以通过插入临时提示标记来覆盖其建议的编辑:

  • 在迁移工具的“编辑详细信息”窗格中,您可以使用“添加 /?/ 提示”和“添加 /!/ 提示”按钮插入提示标记。

这些按钮会立即向您的文件添加注释,并且无法撤消。如果您不希望插入该工具的提示,可以使用常用的代码编辑器将其删除。

  • 即使该工具仍在运行,您也可以使用编辑器添加提示标记。由于您的代码尚未选择空安全,因此您无法使用新的空安全功能。但是,您可以进行不依赖于空安全功能的更改,例如重构。

完成代码编辑后,单击从源重新运行以获取更改。

下表显示了可用于更改迁移工具的建议编辑的提示标记。

提示标记 对迁移工具的影响
expression /*!*/ 将 ! 添加到迁移的代码中,将表达式转换为其基础的不可为空类型。
type /*!*/ 将类型标记为不可为空。
/*?*/ 将前面的类型标记为可为空。
/*late*/ 将变量声明标记为 late ,表明它具有后期初始化。
/*late final*/ 将变量声明标记为 late final ,表明它具有延迟的一次性初始化。
/*required*/ 将参数标记为 required 。

单个提示可能会对代码中的其他地方产生连锁反应。在前面的示例中,手动添加 /!/ 标记,其中为 zero 分配其值(第 2 行),使迁移工具将 zero 的类型推断为 int 而不是 int? 。此类型更改可能会影响直接或间接使用 zero 的代码。

var zero = ints[0]/*!*/;

根据上述提示,迁移工具将更改其建议的编辑,如以下代码片段所示。第 3 行 zero 之后不再有 ! ,并且第 4 行 zeroOne 被推断为 int 列表,而不是 < b4> 。

 第一次迁移
 var ints = const <int?>[0, null];
var zero = ints[0];
var one = zero! + 1;
var zeroOne = <int?>[zero, one];
有提示的迁移
var ints = const <int?>[0, null];
var zero = ints[0]/*!*/;
var one = zero + 1;
var zeroOne = <int>[zero, one];

选择退出文件

尽管我们建议一次性全部迁移,但有时这是不切实际的,尤其是在大型应用程序或包中。要选择退出文件或目录,请单击其绿色复选框。稍后,当您应用更改时,除了 2.9 版本注释之外,每个选择退出的文件都将保持不变。

有关增量迁移的更多信息,请参阅不健全的 null 安全性。

请注意,只有完全迁移的应用程序和包才与 Dart 3 兼容。

应用更改

如果您喜欢迁移工具建议的所有更改,请单击“应用迁移”。迁移工具删除提示标记并保存迁移的代码。该工具还更新了 pubspec 中的最小 SDK 约束,该约束将包选择为 null 安全。

下一步是静态分析您的代码。如果有效,则测试您的代码。然后,如果您已在 pub.dev 上发布了代码,请发布空安全预发行版。

手动迁移

如果您不想使用迁移工具,可以手动迁移。

我们建议您首先迁移叶库 - 不从包导入其他文件的库。然后迁移直接依赖于叶子库的库。最后迁移具有最多包内依赖项的库。

例如,假设您有一个导入其他(空安全)包和核心库的 lib/src/util.dart 文件,但没有任何 import '<local_path>' 指令。考虑首先迁移 util.dart ,然后迁移仅依赖于 util.dart 的简单文件。如果任何库具有循环导入(例如,A 导入 B,而 B 又导入 C,而 C 导入 A),请考虑将这些库一起迁移。

要手动迁移包,请按照下列步骤操作:

  1. 编辑包的 pubspec.yaml 文件,将最小 SDK 约束设置为至少 2.12.0 :
environment:
  sdk: '>=2.12.0 <3.0.0'
  1. 重新生成包配置文件:
dart pub get

使用至少 2.12.0 的较低 SDK 约束运行 dart pub get 会将包中每个库的默认语言版本设置为最小值 2.12,将它们全部选择为空安全。

  1. 在 IDE 中打开该包。

您可能会看到很多分析错误。没关系。

  1. 迁移每个 Dart 文件的代码,使用分析器识别静态错误。

根据需要添加 ? 、 ! 、 required 和 late 来消除静态错误。

有关手动迁移代码的更多帮助,请参阅不健全的 null 安全性。

3. 分析

更新您的包(在 IDE 或命令行中使用 dart pub get )。然后使用 IDE 或命令行对代码执行静态分析:

 dart pub get
 dart analyze     # or `flutter analyze`

4. 测试

如果您的代码通过分析,请运行测试:

 dart test       # or `flutter test`

您可能需要更新需要空值的测试。

如果您需要对代码进行大量更改,那么您可能需要重新迁移它。如果是这样,请在再次使用迁移工具之前恢复代码更改。

  1. 发布 我们鼓励您在迁移后立即发布软件包(可能是预发行版):

设置包版本以指示重大更改。 更新 SDK 约束和包依赖项。 发布包。如果您不认为此版本是稳定版本,则将该包发布为预发行版。 更新包版本 更新包的版本以指示重大更改:

如果您的软件包已经是 1.0.0 或更高版本,请增加主要版本。例如,如果先前版本为 2.3.2 ,则新版本为 3.0.0 。

如果您的软件包尚未达到 1.0.0 ,请增加次要版本或将版本更新为 1.0.0 。例如,如果先前版本为 0.3.2 ,则新版本为 0.4.0 或 1.0.0 。

检查你的 pubspec 在发布包的稳定空安全版本之前,我们强烈建议遵循以下 pubspec 规则:

将 Dart lower SDK 约束设置为您测试过的最低稳定版本(至少 2.12.0 )。 使用所有直接依赖项的稳定版本。 欢迎来到空安全 如果到目前为止,您应该拥有一个完全迁移的、空安全的 Dart 包。

如果您依赖的所有包也都被迁移,那么您的程序就空引用错误而言是健全的。运行或编译代码时,您应该看到如下输出:

Compiling with sound null safety Dart 团队的全体成员感谢您迁移代码。


Comments

Make a comment