一、简介
Fair-Online 是面向Flutter 开发者,提供从Flutter 在线开发,到实时编译预览,打包发布、动态下发端侧更新,实现Flutter 线上动态化的一体化云开发平台。开发者无需配置Flutter 开发环境,在线开发调试代码,即时编译预览,所见即所得,结合58开源团队打造的Flutter 动态化框架 Fair 及热更新平台 FairPushy ,实现Flutter 线上动态化。
目前Fair 云开发平台已在Github 开源:Fair-Online Github ,在线体验地址: Fair-Online Platform
整个工程分为两部分:
- fair_online 前端工程
- fair_online_service 后端服务
二、Flutter低代码
熟悉Flutter 的小伙伴应该都了解过 FlutterFlow ,它是目前比较完善的Flutter 低代码平台,面向的是Flutter 零基础开发者。开发者无需了解Flutter 的控件体系及语法规则,只需使用平台提供的微件和复合组件,拖拽生成页面即可。对于业务逻辑处理,比如网络请求、事件Action处理等,是通过可视化的属性编辑完成,平台会根据开发者的操作生成对应的Flutter 代码。工具的 js模块
在体验使用FlutterFlow 的过程中,我们也发现一些问题。首先,对于页面UI开发,如果要实现一个功能复杂,页面层级较多的UI,使用拖拽组合,会变得非常繁琐困难,这对Flutter 开发者是不够友好的开发方式;其次,对于复杂业务逻辑的处理,比如网络请求,事件Action处理等,使用可视化属性设置,开发也比较繁琐,且学习成本较高。
所以,针对上述问题,在技术选型上,区别于FlutterFlow 等低代码平台的拖拽编辑实现,Fair-Online 是面向Flutter 开发者,提供在线代码编辑器,辅助以可视化的工程、页面、组件创建、编辑,以实现Fair 开发提效,且几乎没有额外的学习成本。为了方便不熟悉Fair 的小伙伴快速上手Fair 开发,平台提供了常用的工程、组件模板以及网络请求等业务逻辑,开发者在创建工程、页面时可选择模板创建,然后二次编辑。
三、Fair-Online架构
整体架构设计分为前后端,都基于Dart 技术栈实现。
其中,上半部分是前端,应用展示层,技术栈使用的是Flutter Web + JS。
中间服务层
- 包括 Code Editor(代码编辑器)和 Preview(预览)等组件。
- Code Editor(代码编辑器)是核心基础功能。其中视图部分使用CodeMirror , 它是一个使用JS实现的文本编辑器三方库;而逻辑部分,比如代码分析、语法检测、代码补全等,使用Flutter 实现。
- Preview(预览功能),是基于Flutter 和Fair SDK 实现。
上层应用层
- 包括Flutter/Fair 的编译运行,Fair 一键打包、代码导出、手机扫码预览等;以及工程、页面等编辑功能。
下半部分是后端,服务层,技术栈使用的是Dart Server。
中间服务层
- 主要包括Fair SDK,Fair 语法检测插件。语法检测是Fair-Online 的重点及实现难点,后文会有详细介绍。
上层应用层
- 主要包含用户工程相关,管理着用户的工程、页面、组件库等。
- 下面详细介绍下Fair-Online 中核心功能的实现。
四、Fair-Online 核心功能
4.1 在线代码编辑器
4.1.1 Flutter Web运行原理
Flutter Web 在Framework 层和移动端Flutter 是相同的,区别在于渲染底层,移动端通过内置skia 引擎调用GPU 进行绘制,而Flutter Web 则是将绘制引擎部分替换为标准HTML 标签以及Canvas 绘制的自定义标签,最终生成可绘制的dom 树。
依托于dart compile 工具的 js模块 (老版本为dart2js 工具),Flutter Web 的构建工具可以将中间产物 app.dill 进行读取和解析,并注入 Math、List、Map 等 JS 工具方法,最终生产出Web 平台所能执行的JS 文件。
4.1.2 Flutter Web与JS的互操作性
Flutter 在移动端的生态丰富,但是在Web 上面就差了很多,目前的Flutter Web 在开发中很大程度上依赖了Web 上丰富的三方库,所以能够与JS 的函数互相调用是很重要的能力。
不同于Flutter 在移动端上面与webview 的交互方式,由于Flutter Web 是运行在浏览器环境中的,并且本身Dart 也会经dart2js 转化为JS 代码,所以在Flutter Web 上面通过dart:js 或是packages:js 可以很轻松实现Dart 和JS 互相调用。
4.1.3 技术选型-CodeMirror
对于代码编辑器的选择上其实没有什么挑选的空间,首先Flutter 技术栈的三方库以移动端为主,所以想要接入代码编辑器这种组件,我们只能从JS 的技术栈上面选择。CodeMirror 是一款在Web 上面老牌的代码编辑器,功能强大,提供了十分丰富的API,并带有多种语言模式和插件,可实现更高级的编辑功能,完全可以满足我们的需求。
依赖Flutter Web 与JS 强大的互操作性,我们可以轻易地在集成CodeMirror,而Google 官方也提供了CodeMirror 的Dart 封装库,其核心实现就是通过dart:js 库对JS 侧的CodeMirror 进行API 的调用和交互 。
CodeMirror 作为Web 上面的UI 库需要基于html 标签来展示,而在Flutter Web 中需要借助HtmlElementView 来往Widget 层次结构中嵌入一个 HTML 元素(在移动端需要使用flutter_webview 插件),动态构建Html 标签需要在platformViewRegistry 注册后使用,对应的代码如下:
/// 构造用于承载CodeMirror的Html标签并注册
final html.HtmlElement element = html.DivElement();
ui.platformViewRegistry.registerViewFactory(getCodeMirrorViewType(),
(int viewId) {
return element;
});
/// 初始化codemirror
editor = (editorFactory..paramsProvider = this)
.createFromElement(element, options: codeMirrorOptions)
..theme = 'darkpad'
..mode = 'dart'
..showLineNumbers = true;
通过简单的初始化配置设定主题和语言模式后后,将HtmlElementView 嵌入Widget 层级中,就可以正常显示代码编辑器,如下所示。
4.1.4 Fair-Online运行原理
当然如果要使代码编辑器具备完善的功能,还少不了对代码进行语法检测分析,通过快捷键触发代码的补全提示等功能,这些也是我们日常开发使用的AndroidStudio 和VSCode 中具备的必要功能。
CodeMirror 只是代码编辑器的UI库,对于代码语法的分析逻辑需要自定义,然后组装分析结果交由CodeMirror 的Hint和Doc操作对象进行实际的展示。在Fair-Online 的架构中,Flutter 和Fair 的语法分析由Dart 编写的服务端完成,具体的运行原理如下图所示:
- 在Flutter Web 监听输入和组合快捷键,触发分析请求。
- Dart Server 通过Analysis Server 和Fair 语法分析插件生成分析结果,并返回给Web 端。
- Web 端通过将结果转化为具体的操作对象,交由代码编辑器来进行文本操作或提示弹窗显示。
- 通过Dart 和JS 的互操作性调用CodeMirror 的具体操作API。
4.2 Flutter在线编译预览
在我们使用Flutter 开发移动端应用时,借助Debug 模式下的Hot Reload 功能可以实现在手机或模拟器上面快速的预览代码改动。在传统的低代码平台上因为采用拖拽控件的方式天然的支持对UI 效果的把控,而Fair 云开发平台上面采用在线编写代码的方式,需要在网页中快速预览所写代码运行后的效果。
4.2.1 Flutter Web上如何在线预览代码运行效果
在代码编辑器的部分中我们提到了Flutter 在Web 平台上运行的核心是dart2js,区别于移动端,在Web 上 dart2js 通过将dart 编译的中间产物dill 转化为JS 来实现。
由于构建Html 标签或者使用Canvas 来展现UI 的逻辑都在js中,按照这个思路我们可以将在线编写的代码通过 dart2js 编译,然后嵌入Html 标签中进行预览。但如果处于同一window 和dom 下的话,资源和JS 环境会共享,会引起冲突,这时需要iframe 标签来解决这个问题。iframe 标签承载了一个单独的嵌入的窗口,它有自己的 document 和window,所以大致思路就是将在线编辑的代码转化为JS 后注入一个iframe 内进行预览。
4.2.2 Dartdevc编译器
Dart 开发编译器(dartdevc,也称为DDC) 一般用于Flutter Web 开发时使用Chrome 运行和调试。区别于 dart2js,dartdevc 支持增量编译,所以在开发调试中可以做到类似移动端Flutter 中HotReload的效果。dartdevc 通常需要配合webdev 一起使用,webdev 是使用Dart 开发和部署Web 应用程序的命令行工具,比如监听文件变化触发重建和重新部署就尤其负责。
4.2.3 Fair-Online编译预览前后端原理
出于对在线编译速度的考量,Fair云开发平台在Dart 后端上面使用dartdevc 替代dart2js 进行对代码的编译,生成的JS 产物返回前端注入到iframe 中进行效果的预览,具体实现流程如下图所示:
- 用户在Fair云开发平台在线编写代码。
- 前端通过用户输入发起编译预览请求。
- 后端接收请求,通过dartdevc 编译器对工程代码进行编译,将生成的JS 产物返回给前端。
- 前端将返回的JS 产物注入到iframe中进行效果的预览。
五、快速入门
5.1 工程创建
输入Fair 云开发平台网址:fair-online.58.com 进入平台首页。
点击开始使用,进入我的工程页面,如下图所示。
点击工程创建,弹出如下Dialog。
输入工程名,选择空工程或者模板工程创建新工程,模板工程中包含13个代码模板。 工程创建成功后,即可进入工程编辑页面,如下图所示。
5.2 页面创建
在工程编辑页面,点击左上方的页面创建,弹出页面创建Dialog。
输入页面路径和页面名称,选择空页面或者模板页面创建新页面。 页面创建成功后,可在页面列表切换查看该工程下所有的页面。
5.3 代码编辑
5.3.1 基本使用
代码编辑器可以在线编写Flutter、Fair代码,从左侧的页面菜单栏中点击选择需要编辑的页面,如下图所示选中了scrollview示例页面,右侧代码编辑区域会加载当前页面的代码,
代码编辑器支持代码提示,如下图所示,输入context变量后,输入 . 会像IDE一样列出context对象所有的方法调用。
代码编辑器支持对Flutter以及Fair语法的检测,当检测出语法问题时会有类似IDE的代码划线警告,右下角有着具体语法错误分析弹窗,点击可以复制报错信息和跳转官方文档查看更多,底部面板点击hide按钮隐藏语法分析弹窗。
Fair云开发平台还针对Fair一些特殊的语法做了支持,如图就是对build函数中不支持的 if else 逻辑控制语句显示警告。
对于Flutter和Fair的语法错误提示,Fair云开发平台支持代码修复,使用 **[Control+Enter] ** 快捷键即可修复代码问题。如下图所示,点击后会使用Fair内置的语法糖来解决逻辑控制语句的问题。
代码编辑器还支持代码辅助功能,对Widget对象使用 **[Control+Enter] **快捷键会有如图所示的提示选项,根据提示可以快捷的包裹常用控件,方便了使用者高效开发。
5.3.2 常用快捷键
| windows快捷键 | mac快捷键 | 动作 |
|---|---|---|
| alt-enter | option+enter | 代码提示 |
| ctrl-space | command-space | 代码补全 |
| ctrl-enter | command+enter | 运行 |
| shift-ctrl-f | shift+command+f | 格式化 |
5.4 Flutter 编译预览
开发过程中,可随时点击Run执行Flutter 编译预览,代码编辑阶段为了提升编译速度,快速预览编码效果,采用的是DDC(Dart Development Compiler)编译模式。 这里需要注意只有被@FairPreviewPage()注解修饰的Widget类可以被服务端识别并返回预览结果。 编译成功后,展示在线预览页面,点击开发对应的页面,查看页面效果。
点击模拟器下方的Device Setting,可切换预览设备。
如果编译失败,可在Console窗口查看错误日志。
5.5 Fair 编译预览
Fair 编译预览分为编译及预览两个步骤。 点击模拟器上方的Build,即可执行 Fair的编译。 编译成功后,可在左边的Fair DSL列表查看Fair 的编译产物。Fair 编译产物包括JSON 和JS 文件,可切换查看。 如果编译失败,可在下方Console 窗口查看日志信息。
编译成功后,点击模拟器上方的Run,执行Fair 预览。 点击Fair 预览-云开发平台使用,进入下图所示Fair DSL 列表。
点击选择Fair DSL,查看页面效果。
5.6 自定义组件
5.6.1 创建与编辑
Fair云开发平台支持自定义组件,左侧面板点击下方添加图标打开自定义组件界面,如图所示列表中有内置的两个组件示例,在这个页面中可以创建新组件、编辑/删除已有的组件
点击右上角添加组件打开组件编辑弹窗,可以在线编辑代码
点击右上角编译预览按钮可以快速预览效果
点击保存即可上传自定义组件
5.6.2 使用
点击左侧面板中的自定义代码按钮,会列出当前的自定义组件列表
点击使用打开对组件详细说明的弹窗,弹窗内容包含名称,简介以及原始代码和FairWidget代码
点击右下角的复制按钮可将FairWidget粘贴到代码编辑器中进行使用
5.6.3 自定义Action
自定义Action可以方便使用者快速的粘贴工具代码以快速开发,具体的创建与编辑操作和自定义组件类似,如图所示是内置的FairNet网络请求Action
使用方法同样也是粘贴到代码编辑器中
5.6.4 手机扫码预览
Fair 云开发平台支持手机扫码实时预览功能,移动端平台相关的功能,如打电话,定位等,可通过扫码在手机上实时预览。 点击工程编辑页面右上角的二维码样式按钮,弹出如下所示Dialog。 Fair 云开发平台提供了 FairPlayground APP,可通过点击如下链接下载安装。安装完成后,打开APP,进入Fair 开发者选项页面,点击扫一扫,扫码Dialog中的二维码,即可预览。
5.7 上传补丁
功能开发完成后,可在Fair 云开发平台上将编译产物上传至热更新平台。 点击右上角的更多菜单。
选择上传补丁,弹出如下所示Dialog。如果还没有搭建热更新平台,Fair 团队开源的FairPushy 了解一下~
5.8 工程导出
Fair 云开发平台支持将平台上开发的代码导出到本地。 点击右上角的更多菜单,选择工程导出,下载的是该工程代码的压缩包。