当产品说要把所有移动端(小程序、H5、APP)等 UI 做成一致,又不想投入更多的开发人力。那作为开发,有哪些方案可以用呢?
Canva
就是完全套壳的 APP,用了一套 Web 响应式布局,适配了 All。但缺点也很明显,在 APP 上只能是通过 webview,会频繁的白屏及重绘(看滚动条位置就能看出来,保存不住上几个页面的页面状态),更搞笑的是没做离线化,弱网络打开 APP 会卡在 launch 页,首页都进不去 [手动狗头]。在 Flutter 3.0 时代后,Flutter 官方算是进一步优化了 build web 的一些问题,减少了包体积,至此,笔者也由于某些原因兴(bei)趣(po)满(wu)满(nai)的开始尝试这大前端极致互卷之路。
用 Flutter 来做 Web 最主要的是想复用 APP 的 UI。(其他方面确实赶不上直接用 React / Vue 来开发来的舒适。特别是需要更为重视 SEO 的业务,Flutter 官方对 SEO 都没有任何建议)
先看一下总体架构设计:
这个设计的目的:
那其实重点的需要有一个通信层,让 TS / JS 与 Flutter web 可以优雅的通信。
让 Flutter 开发同学只关心 UI 展示,让前端同学只关心业务实现,尽可能减少沟通及语言学习成本。
那其实通信层上就需要做到双端无感,这很容易想到使用 codegen 的方式(codegen 会单独开一个专栏来聊一聊)。
代码核心上,主要是使用 Flutter 提供的官方一方库 https://pub.dev/packages/js[1] , 虽然它的版本是 0.6+,没有到 1.0 正式版,但隶属于 dart-lang/sdk 还是可信赖的。
在研究了该库的 example https://github.com/google/chartjs.dart/ (google 组织下,也是很有保证的)后发现了一个官方使用的 codegen 生成 chartjs.dart 类的工具。
《https://github.com/dart-lang/js_facade_gen[2] 》根据 TS 代码生成 dart 抽象调用层。
在各种挠头尝试下,最终确认这库是用不了的 [手动狗头]
用不了的原因也很简单
如上图所示,虽然这库也是在 dart-lang 中,但这库已经3年没更新了,Flutter 这3年大大小小也发了几十个版本,生成的 dart 代码上林林总总各种报错不能用 ...
那是否要重新造轮子?
在研究了它的源码后,发现其实也还是对 TS 的 AST 进行字符串处理(codegen 的本质就是字符串处理)
那我们就可以改造源码的方式进行本地使用。
例如去支持生成 Flutter 空安全语法:
也做了不少增强性工作,原因是这两点:
所以我们在 TS 中增加了 @DartObject 注解来做定义,通过内置 json_annotation
直接生成 Flutter Model(当然这需要执行额外的命令,但我们把它封装成一个 vscode extensions
即可很方便使用)。
代码上只要写 TS 代码即可。
/**
* 首页模版 Model
*/
@DartObject()
export class GDHomeTemplateListModel {
/**
* id
*/
id?: string
/**
* 模版名称
*/
name?: string
/**
* 预览图
*/
preview?: GDHomeTemplateListPreviewModel
test?: string
}
不能添加视频,所以不太好描述 - -|
举个例子,测试是模版接口调用
下图是 TS 通过 fetchAPI 实现接口调用的测试代码
下图是 Flutter 通过生成的 GDModuleAPI.home.fetchTemplates
方法直接调用 TS 层代码
可以看到 Flutter 正常使用 TS 定义的模型了
再放一张测试结果图:
可以看到,接口请求真实发生且已将模版列表渲染成功。
可以看到过程上做到了极大解耦:
本文主要是记录下调研过程,整体方案已经是可用的,接下来就会进入到方案开发。
[1]packages: https://pub.dev/packages/js/example
[2]js_facade_gen: https://github.com/dart-lang/js_facade_gen
- EOF -