阿里卖家 Flutter for Web 工程实践

阿里卖家 Flutter for Web 工程实践_第1张图片

作者:马坤乐(坤吾)

Flutter 自 2015 年初次亮相以来,经过了多年的发展已经相当成熟,在阿里、美团、拼多多等互联网公司都有广泛的应用。在 ICBU 阿里卖家上 90+% 的新业务使用 Flutter 开发,ICBU 客户端开发组拥有众多的 Flutter 开发人员。

Flutter for Web (FFW) 早期试验版于 2019 年发布,在当时已经有很多感兴趣同学对其进行调研,当时由于刚发布存在诸多问题不适合在生产环境中使用。在今年(2021)三月份,Flutter 2.0 发布,FFW 正式进入 stable 分支。

阿里卖家外贸资讯版块主要使用 Flutter 开发,在本财年的目标中,外贸资讯的App外推广为开源引流的重要一环。App外资讯推广需要一个承载内容Web页面,对该Web页面的要求如下:

  • 复刻App端相关页面的 UI、功能(主要包含一个dart编写的自定义html解析渲染引擎)【主要工作量】
  • 快速上线
  • App端功能同步

由于缺乏前端同学的支持,想要完成此页面只能由 App 端上同学自己投入,经过一定的考虑我们选择了 FFW,理由如下:

  • 切换到前端技术栈 Rax 等成本稍高,同时目标页面功能复刻需要较多时间
  • 使用 FFW 目标页面上绝大部分代码可复用端上现成 dart 代码
  • App 端上 Flutter 技术栈同学覆盖广

经过以上思考,正式开启 FFW 填坑之旅。

Demo

目前阿里卖家FFW相关页面已上线,从 FFW 发布至今产物 js 文件大的问题就一直存在,理论上会很影响页面加载体验,实际测试中观察到在 PC、移动设备上加载体验尚可,运行很流畅,相关 Demo 如下:

  • 外投内容展示页 demo:https://alisupplier.alibaba.com/content_page/#/web_news_detail?courseCode=PX8K3IYX&sourceId=cata_0
  • 阿里卖家 App 下载页面:https://alisupplier.alibaba.com/content_page/#/sellerapp?s=c_ata

问题总览

创建 FFW 工程比较简单,Flutter 切换到 stable 版本,之后运行命令 flutter create xxxProject 进入工程后点击运行一个 Demo 工程便可运行起来。要将 FFW 应用到实际的工程中,需要考虑的是工程的问题和如何融入阿里的体系的问题,如:怎么发布、开发流程如何管控、怎么请求接口等,总结如下:

阿里卖家 Flutter for Web 工程实践_第2张图片

以上为阿里卖家 FFW 开源引流最小闭环实践中遇到的问题,除此之外 FFW 待建设的问题还有:

阿里卖家 Flutter for Web 工程实践_第3张图片

工程基础

接下来是对最小闭环实践中,工程基础问题的出现原因和解决方案的说明。

环境和复用

参考 App 端 Flutter 开发,FFW 中首先要考虑选择 Flutter 的什么版本,其次是考虑如何复用已有的 Flutter 代码。

1Flutter 版本选择

版本选择问题因 FFW 和 Flutter for App (FFA) 的 Flutter 版本无法统一产生。FFW 需要的 Flutter 版本为 2.0+,而目前我们 App 端内的 Flutter 版本为 1.X+ ,要升级到 2.0+ 版本还需等待不确定的时间。经过一定的考虑目前我们 FFW 和 FFA 选择版本如下:

FFA: hummer/release/v1.22.6.3          -- UC的Hummer分支
FFW: origin/flutter-2.8-candidate.9     -- 官方分支

FFW 不选用 stable 版本是因为在最近刚发布的 iOS 15 上 FFW 页面会因 webGL 问题会卡死,该问题修复方案目前已集成到了candidate版本。(当前最新stable版本为2.10.0,问题已解决)

2代码复用

FFA 代码复用到 FFW 中要考虑的问题分两块:

  • Dart 代码复用
  • 平台相关插件能力复用

Dart 代码复用

FFW 需要 Flutter 2.0+ 版本对应的 dart 版本为 2.12,此版本的 dart 引入了空安全 (Sound null safety) 特性。FFA 上使用的 Flutter 版本为 1.+ 版本对应的 dart 还未引入空安全。同时 Flutter 中新老版本 dart 库代码无法混合编译,所以目前对已有 App 端代码库还无法做到无缝复用,只能通过修改已有代码进行复用,代码修改主要的点有:

  • 可为空的变量,类型后添加?
User? nullableUser;
  • 操作可为空的变量时使用 ? 或 !
nullableUser?.toString();   // 空安全,如为空不会出现NPE
nullableUser!.toString();   // 强制指定非空,如为空会报错
  • 可选参数 @required 注解替换为 required 保留字
/// 老版本
User({
  @required this.name,
  @required this.age,
});

/// 新版本
User({
  required this.name,
  required this.age,
});

低版本代码经过这三步修改后基本可在新版本编译通过,除此之外还会有部分 API 由于版本升级产生变更,也需要相应的修改,如:

/// 老版本
typedef ValueWidgetBuilder 
  = Widget Function(BuildContext context, T value, Widget child);

/// 新版本
typedef ValueWidgetBuilder 
  = Widget Function(BuildContext context, T value, Widget? child);

在 API 变更中这类问题占大多数,修改起来较简单。另外还有一类改动,如在抽象类 TextSelectionControls中,handleCut等方法参数的个数发生了变更:

/// 老版本
void handleCut(TextSelectionDelegate delegate) {...}

/// 新版本
void handleCut(TextSelectionDelegate delegate, 
               ClipboardStatusNotifier? clipboardStatus)

你可能感兴趣的:(flutter,移动开发,客户端,android,ios)