记录一个Flutter空安全升级问题

最近碰到一个奇怪的问题

先来看个现象

工程结构

.
├── README.md
├── android
├── build
├── ios
├── lib
├── pubspec.lock
├── pubspec.yaml
├── subpackage
├── test
└── webview_demo.iml

子工程空安全检测正确✅

jiodg45@jiodg45s-MacBook-Pro subpackage % dart pub outdated --mode=null-safetyShowing dependencies that are currently not opted in to null-safety.
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.

主工程检测却发现子工程出现空安全问题❌

jiodg45@jiodg45s-MacBook-Pro webview_demo % dart pub outdated --mode=null-safety
Showing dependencies that are currently not opted in to null-safety.
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.

Package Name  Current        Upgradable     Resolvable     Latest         

direct dependencies:
subpackage    ✗0.0.1 (path)  ✗0.0.1 (path)  ✗0.0.1 (path)  ✗0.0.1 (path)

十分诡异,于是开启了--verbose查看详细日志,空安全检测具体命令dart pub outdated --mode=null-safety --verbose

可以看到空安全检测主要是对每个库的sdk版本与2.12.0进行比较

  1. 获取依赖,包含git/path/pub三个级别的依赖
  2. 其中工程外的pub依赖关系保存在/Users/jiodg45/.pub-cache/hosted/pub.dartlang.org/.cache/cupertino_icons-versions.json.,对应路径为$HOME/$PUB_CACHE/hosted/HOST_PUB_URL/.cache/{package_name}-versions, 此部分是从pub库上获取,通过json中的environment获取到sdk版本,用于后续比较
  3. 工程内的依赖关系保存在pubspec.lock文件中,gitpath相关的一级依赖也会被添加到此仓库中,以来类型为dependency: transitive
  4. 这样仓库的所有的依赖关系可以从三个文件一次进行查找, pubspec.yaml->pubspec.lock->`` H O M E / HOME/ HOME/PUB_CACHE/hosted/HOST_PUB_URL/.cache/{package_name}-versions

对应的代码可以在pub库的outdated.dart中查看,省略后的关键代码如下,主要逻辑集中在supportsNullSafety,逐一查找package的dart sdkVersion,然后与2.12.0比较

https://github.com/dart-lang/pub/blob/master/lib/src/command/outdated.dart
-> OutdatedCommand

 @override
  Future<List<List<_MarkedVersionDetails>>> markVersionDetails(
      List<_PackageDetails> packages) async {
    final nullSafetyMap =
        await log.spinner('Computing null safety support', () async {
      /// Find all unique ids.
      ...
      return Map.fromEntries(
        await Future.wait(
          ids.map(
            (id) async => MapEntry(
                id,
                (await id.source.bind(cache).describe(id))
                    .languageVersion
                    .supportsNullSafety), 
    ...

所以当子工程的pubspec.yamlsdkVersion指定的最低版本低于2.12.0时会报空安全检测异常. 因此在升级时一定要修改sdk的最低约束,防止误检.

environment:
  sdk: ">=2.12.0 <3.0.0"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值