Flutter For Web:人人都是大前端开发
2020-12-23 16:28
标签:分离 out 接口 互动 code 设置 官方 callback pack 我们对辅导 App 中上课页学习简报页面进行改造,支持浏览器中打开。 iOS 中打开 Flutter Web 页面 浏览器中打开 Flutter Web 页面 Flutter For Web 谷歌官方一直建议暂时不要在生产环境使用。但如果不尝试,我们永远不知道这里会藏有什么样的秘密,什么样的场景适合。对现有 Flutter 改造,增加对浏览器的支持,突破而不失稳重。 如果我们只是新建一个新的项目,只需切换到最新的 master 分支,创建一个新的项目即可。创建完成之后,根目录下会多出一个 web 文件夹,里面只有一个 web 入口文件 index.html。 原有项目中如果直接运行 flutter run -d chrome,会发现控制器中 import 报错,原因是 dart: io 库不支持 web。io 库是 Flutter 中非常常用的库,主要是平台相关的一些 api,改造的第二步我们就需要屏蔽 dart:io 的引入。 原有 Flutter 项目我们通过 MJFlutter 调用 Native 的网络接口,实现数据请求。辅导 web 侧是通过 CGI 请求获得后台数据,现在 web 需要另一种方式,给大家推荐几种方式: b. package:http/html.dart c. package:dio/dio.dart 有了基本的网路请求,配置完 CGI,接下来就是界面的展示。但是你会发现,所有的业务请求都没有回包,无法得到数据。如果作为移动端开发,没有经常接触到 http 请求,一下子发蒙,我觉得可以理解。这个是 Web 开发中经常遇到的 跨域问题。前端开发们这里可以举手了,这个问题我会。简单的处理方式就是开发过程中挂上一个代理,具体就不详细展开了。 与使用 Flutter 实现的页面不同,Flutter For Web 的页面使用 Http 请求获取后台数据。Http 请求中很重要的一点是 header 中的 cookie,这里就需要通过 dart 与 js 之间的交互,还是要称赞下 Flutter 团队的实力。 新建 native_api.js 文件 dart 封装 js 方法 index 入口文件中引入 js 文件 添加完 js 支持后,dart 侧调用 getStringFromJS 方法,并打印结果。 native_api.js 中声明基本方法 dart 封装 js 方法 整体来说,Flutter For Web 达到成熟还有一段时间。在这段时间里,尽早布局,未免不是一件好事。Flutter For Web 现阶段的使用场景并不多,不如直接使用 Web 开发便捷、稳定。但我们可以通过 Flutter,拉近与大前端的距离,感受大前端的魅力,做一个真正的大前端开发。 技术服务于业务,业务推动技术,二者并行,提升用户体验,Flutter 道路上期待大家的反馈。 Flutter For Web:人人都是大前端开发 标签:分离 out 接口 互动 code 设置 官方 callback pack 原文地址:https://blog.51cto.com/15057848/2566501
图片
作者|涂金林
编辑|王文婧
Flutter For Web 已经发布半年多时间,跑在 Flutter 实践道路上的腾讯企鹅辅导团队是如何应用的?
今年 9 月,作为腾讯 Flutter 实践团队之一的我们,有幸参与了 GDD 大会上 Flutter 应用视频的录制,感受到国内众多开发者对 Flutter 的热情。两天时间,讲道理,其实没有太多的干货,但收获还是满满的。有那么点空闲的时间,也关注了一下其他的同学,大家讨论的重心还是第一天主会场的内容。我想吸引大家的一直是 Flutter 新版本 stable1.9 的重磅发布。
新版本一个重要功能就是 Flutter For Web 仓库合入 Flutter master 主仓库,意味着我们可以真正地使用一套代码、一套资源部署大前端。辅导团队经过一段时间的准备,使用 Flutter 开发的 Web 页面也即将发布,希望和大家分享下实践过程和踩坑实例,欢迎一起交流探讨。一、发布准备
网络 cgi 接口现网暂时没有配置,先使用假数据展示。开发过程中,我们涉及到 Flutter 页面转换、网络请求、与 Native 交互、cookie 等,最终的页面发布我们还需要在发布系统中配置。有关基础开发及发布的知识,大家可以关注互动视频大神 weiwei 的一篇分享:《如何使用 Flutter For Web 开发一个需求并上线》,文章介绍的很清楚,最终发布上线需要的产物是:
index.html:h5 访问入口;
main.dart.js:dart 代码转化成 js 后的产物;
assets:静态资源,包括图片、字体,以及我们定制的 js 文件。二、页面改造
我们原先的版本使用 Flutter 1.5.4,增加 Web 支持,我们需要切换到最新的 master 分支,改造运行。
2. 修改 dart:io 库
Flutter For Web 最终运行的是在浏览器中的 js 代码,Flutter For Phone 使用,Platform 引擎与 Native 通信。js 在平台上是通过其他的系统支持(iOS 中的 JavaScriptCore) 与 Native 通信,二者是完全不同的方式,所以 dart: io 无法继续支持。
既然 dart: io 不支持 web,那我们仍然想使用原先的 Flutter 业务 UI 代码,该 如何实现(上文我们说过,我们想使用同一套代码、同一套资源整合大前端)?我们使用不同平台下支持的能力库区分。
import ‘main_web.dart‘ if (dart.library.io) "main_io.dart"; //dart.library.io
UI 侧我们仍然使用同一套代码,逻辑侧通过 library 库分区 native 还是 web,逻辑侧对应不同的平台实现。这几天,我看到一个新的区分方法,简单而且实用:web 侧我们可以判断 0 和 0.0 是否是一个对象。
区分完不同平台,我们还需要辨别不同设备,这里我建议搭建 app 初始化的时候配置完成,后续方便实用。//init
Config.inWeb = identical(0, 0.0);
/////////////////////////////////////
enum K12Platform {iPhone, iPad, android}
class Config {
static bool inWeb = false;
static K12Platform k12platform = K12Platform.iPhone;
static bool inProduction = bool.fromEnvironment("dart.vm.product");
}
3. 网络请求
a. package:http/http.dart
pub 链接:https://pub.dev/packages/http#-readme-tab-import ‘dart:convert‘ as convert;
import ‘package:http/http.dart‘ as http;
main(List
import ‘dart:html‘ as html;
var req = html.HttpRequest.getString("https://www.googleapis.com/books/v1/volumes?q={http}");
pub 链接:https://pub.dev/packages/dio#-installing-tab-
dio 这个网络库,大家之前可能用过,需要注意一点,3.0 之前的版本 Flutter For Web 不支持 (dart:io)。3.0 之后的版本,这个库经过官方大改造,现已支持 Flutter For Web 开发。
我推荐的是 dio 这个库,使用起来会比较方便,参数简单好理解。var url = ‘https://fudao.qq.com/xxx‘;
BaseOptions options = BaseOptions(
method: ‘get‘,
baseUrl: url,
connectTimeout: 5000,
receiveTimeout: 100000,
contentType: ‘json‘,
responseType: ResponseType.plain,
headers: {
‘host‘ : "fudao.qq.com", // 一般就是 webview 的 url 的 host
‘cookieHeader‘: getWebCookie(),
‘accept‘: "*",
‘referer‘: "https://fudao.qq.com/"
}
);
Dio dio = Dio(options);
try {
Response response = await dio.get(url);
if (callback != null) {
callback(response.statusCode, response.statusMessage, response.data);
}
} on DioError catch(e) {
if(e.response != null) {
print(e.response.data);
print(e.response.headers);
print(e.response.request);
} else{
print(e.request);
print(e.message);
}
}
网路问题解决,进入发布调试,上文我们介绍过 Flutter For Web 的最终产物是三个文件。如何发布,前端同学又可以举手了。有一个简单的方式:github pages(配置方法:https://pages.github.com/)。三、JavaScript 扩展
官方说明:https://dart.dev/web/js-interop
pub 地址:https://pub.dev/packages/js![](https://s4.51cto.com/images/blog/202012/18/a8c0871db6523e254eabaa9b8bfa18f5.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
通过 js.dart 这个库,可以实现 web 侧的主要功能。例如 cookie、localStorage。
处理完 Web 侧的基本能力后,需要部署 dart 转成 js 后,与 native 交互的能力。我们知道,目前 app 中 native 与 web 交互的方式主要通过 jsBridge。Native 侧我们已经有了成熟的体系主动调用和接收调用 web 的能力,这部分我们可以不需要修改,减少开发工作量。在 Flutter 侧我们需要添加交互支持,也就是需要在 native_api.js 中添加与 native 交互的能力。
JavaScript 调用 Native 的方式,主要有两种:注入 API 和 拦截 URL SCHEME,你可以根据自己的业务能力,选择合适的方式。相较于 JavaScript 调用 Native,Native 调用 JavaScript 比较简单,不管是 iOS 的 UIWebView 还是 WKWebView,还是 Android 的 WebView 组件,都以子组件的形式存在于 View/Activity 中,直接调用相应的 API 即可。
例如 iOS 中 JavaScript 调用 Native,设置 webView 的 title:function callNativeFunction() {
var url = ‘jsbridge://edu/setCenterTitle?p=%7B%22text%22%3A%22%E9%B1%BC%E9%A5%BC%22%7D#2?title=aaa&desc=bbb&link=http%3A%2F%2Fwww.baidu.com‘;
var jsbridgeNode = document.createElement(‘iframe‘);
var removeTimeStamp;
jsbridgeNode.style.cssText = ‘display:none;width:0px;height:0px;‘;
jsbridgeNode.onerror = function(e) {
// 在 android 4.0-4.3 中,script 节点的 src 赋值成 jsbridge://ui/showDialog 的形式会报错
e.stopPropagation();
}
/*
ios 必须先赋值, 然后 append, 否者连续的 api 调用会间隔着失败
也就是 api1(); api2(); api3(); api4(); 的连续调用,
只有 api1 和 api3 会真正调用到客户端
*/
jsbridgeNode.src = url;
var root = document.body || document.documentElement;
root.appendChild && root.appendChild(jsbridgeNode);
setTimeout(function() {
jsbridgeNode &&
jsbridgeNode.parentNode &&
jsbridgeNode.parentNode.removeChild(jsbridgeNode);
}, 500);
}
四、展望
腾讯企鹅辅导团队会继续实践,不管是 Flutter 实现的页面,还是 Flutter 转 Web 的页面。Flutter For Web 一个复杂的场景,我们会尝试降级及热更新能力,与 Web 同学通力合作,封装 App 和 Web 的基础 API、集成 CI 等,欢迎与我们一起交流。
专家介绍
涂金林,来自江苏苏州。2014 年和 2017 年分别获得东南大学本科和硕士学位。2017 年加入腾讯在线教育部,主要从事移动客户端开发。入职以来,参与腾讯企鹅辅导、腾讯课堂 iOS 和 Android 开发,腾讯企鹅辅导 iOS 负责人。目前主要担任腾讯在线教育 Flutter 项目技术负责人。
活动推荐
近年来,随着 jQuery 的落幕,三大框架的割据以及小程序的爆发,大前端的发展也经历了从静态页面到 JavaScript 跨时代的诞生,再从 PC 端到移动端的转向,以及由依赖后端到前后端分离的架构演变。
腾讯在线教育前端团队,近年来在大前端技术架构演进方面也有了不少突破,如 Hybird 方案、离线包方案、PWA 结合 *** 方案、以及 RN 动态化方案的落地和执行等。
这次 GMTC 全球大前端技术大会(深圳站)2019,我们专门请到了 腾讯的前端高级工程师曹海歌,希望可以从腾讯在线教育前端团队的实操案例中,深入了解腾讯为提升研发效率,进行的前端工程化体系建设过程。扫描下方二维码或点击阅读原文,查看详情。
上一篇:netCDF4读数剧
下一篇:JQuery 高级