Flutter 3.47 与 Dart 3.13:你必须了解的迁移指南

0 阅读6分钟

欢迎关注微信公众号:FSA全栈行动 👋

一、核心结论

大多数 Flutter 版本发布时,你可能只需要扫一眼标题,看两个新出的 Widget,然后关掉页面继续写代码。但这次不一样,这篇更新的内容极其硬核,它不是在增加新特性,而是在重构地基。

我仔细研读了官方发布的 Flutter 3.47Dart 3.13 的公告,得出的结论很直接:对于开发者来说,这次发布只有两件事需要立刻提上日程,剩下的——比如 Impeller 登陆桌面、Wasm 的进展、Dart 的新语法——都可以等。

这两件事分别是:

  1. Material 和 Cupertino 移出了 SDK:它们将变成独立的包,随 pub.dev 每周更新,而不再受限于 SDK 每季度的发布节奏。

  2. iOS 27 强制要求 UIScene 架构:如果你的 App 还没有完成迁移,在 Xcode 27 下构建时,启动时会直接崩溃。

二、Material 与 Cupertino 的“解耦”大动作

以前,如果你想用一个最新的 Material 组件(比如某个 Chip 的样式微调),你必须升级整个 Flutter SDK,哪怕这个更新带了一堆你根本用不到的底层逻辑改动。

Flutter 3.47 开始,material_uicupertino_ui 已经搬到了 pub.dev

1、为什么要这么做?

这本质上是把设计系统从“框架的一部分”变成了“框架的用户”。

维度以前的 SDK 模式现在的独立包模式
更新频率SDK 每季度发布pub.dev 每周更新
耦合度高(UI 与渲染、调度器深度绑定)低(解耦,支持风格中立的 Core
适用场景通用场景支持自定义设计系统,降低维护门槛

这其实是一件好事。对于想要极速迭代 UI 风格的团队,或者想要打造完全自定义设计系统的工程,这个变化简直是福音。

2、怎么迁移?

迁移其实非常简单,Flutter 团队准备了自动修复工具。

你只需要在项目根目录运行一条命令:

dart fix --apply --code=migrate_design_widgets

它会自动把你的 import 'package:flutter/material.dart' 改成 import 'package:material_ui/material_ui.dart'

注意: 如果自动修复没能帮你更新 pubspec.yaml,记得手动加上依赖:

flutter pub add material_ui
# 如果用了 Cupertino,也记得加上
flutter pub add cupertino_ui

3、一个很巧妙的“桥接”方案

这里有个细节值得重点关注。如果你现在马上迁移,你的业务代码跑通了,但你依赖的那 30 多个第三方插件还在用旧的 import 'package:flutter/material.dart' 怎么办?你总不能等整个生态都迁移完你才动手吧?

Flutter 3.47 引入了一个叫 MaterialUiCompatibilityBridge 的东西,这就是解决这个问题的“神兵利器”。你只需要在 MaterialAppbuilder 属性里套一层:

import 'package:material_ui/material_ui.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: (BuildContext context, Widget? child) {
        // 这一行能保证那些还没迁移的第三方插件依然正常工作
        return MaterialUiCompatibilityBridge(child: child!);
      },
      home: const HomeScreen(),
    );
  }
}

有了这个“桥接”,你完全可以先升级自己的业务代码,而不用担心第三方插件把你搞挂。

三、iOS 27 的硬性要求

如果说 Material 的迁移是“选择题”,那 iOS 27 的要求就是“生存题”。

Xcode 27iOS 27 将带来一个硬性规定:所有基于 UIKitApp 必须采用 UIScene 生命周期。

如果你的 App 在构建时没适配这个架构,启动时会直接 Crash。这可不是什么 Warning,是实打实的闪退。

1、为什么要现在就看?

最坑的地方在于,你的 CI 流程现在跑在 Xcode 26 上,一切看起来都是 Green 的。等到秋天 Xcode 27 正式发布,你的 CI 环境自动更新了,你的发布任务可能正卡在上线前夕。

2、哪些情况需要手动操作?

大部分 App 只需要通过 Flutter CLI 自动完成迁移,但有两种情况比较折腾:

  1. 你的 AppDelegate 里写了自定义的 Native 代码。

  2. 你依赖的某个 Plugin 还在用旧的生命周期管理方式。

我个人的建议是:这周就赶紧去跑一下 iOS 27Beta 版本

四、其他值得折腾的变动

除了上面两个大事,还有几个硬核更新值得你关注。

1、Impeller 登陆桌面

之前桌面端(macOSWindowsLinux)在使用 Skia 时,经常会遇到所谓的“第一帧卡顿”(Shader Compilation Jank)。这其实是因为 Skia 在运行时动态编译着色器,第一帧渲染时比较吃力,缓存后再就顺滑了。

现在,Impeller 已经成为了桌面端的默认渲染器

Impeller 的思路很暴力:不再运行时编译,而是在编译阶段就预编译好一套固定的着色器集。这样,第一帧也能丝滑无比。

2、Dart 3.13 的“瘦身”与新特性

Dart 3.13 的主题是“简洁”。

  • 语法糖Primary Constructors 正式稳定了。以前写个 class 需要写一堆成员变量和构造函数,现在一行搞定。

  • 格式化dart format 现在会自动按规则给 import 分组了,代码整洁了不少。

  • FFI 树摇(Tree-shaking):这是一个针对 Package 作者的重量级功能。通过 @RecordUse() 注解,Dart 现在可以追踪到底哪些 Native 符号是被真正调用的。这意味着,如果你只用了 SQLite 的三个函数,编译出来的 Binary 就不会包含那几百个你没用过的函数。

3、Wasm 的“最后一公里”

Flutter Web 的终极目标是 Wasm。为了解决大项目在 Wasm 下初始加载慢的问题,Dart 3.13 引入了延迟加载(Deferred Loading)

通过 flutter build web --enable-wasm-deferred-loading,你的 App 在启动时不需要一次性拉下所有代码,这对提升 IPL(首屏加载时间)非常有帮助。

五、最后

总结一下,这次升级的重心在于“解耦”与“基建”。

建议你的行动指南:

  • 本周(高风险):iOS 27 Beta 环境下测一下你的 App 是否会闪退。

  • 本月(截止日期): 运行 dart fix 尝试迁移 Material 包,并评估迁移成本。

  • 本季度: 关注 Impeller 在桌面端的稳定性,尝试 Wasm 编译。

如果你是维护 Package 的开发者,请务必把 Material 的迁移当成一次 Major Release 来处理,因为你的下游用户正盯着你的更新呢。


参考资料:

如果文章对您有所帮助, 请不吝点击关注一下我的微信公众号:FSA全栈行动, 这将是对我最大的激励. 公众号不仅有Android技术, 还有iOS, Python等文章, 可能有你想要了解的技能知识点哦~