Flutter For Web:人人都是大前端開發

Flutter For Web:人人都是大前端開發

Flutter For Web 已經發布半年多時間,跑在 Flutter 實踐道路上的騰訊企鵝輔導團隊是如何應用的?

今年 9 月,作為騰訊 Flutter 實踐團隊之一的我們,有幸參與了 GDD 大會上 Flutter 應用視頻的錄製,感受到國內眾多開發者對 Flutter 的熱情。兩天時間,講道理,其實沒有太多的乾貨,但收穫還是滿滿的。有那麼點空閒的時間,也關注了一下其他的同學,大家討論的重心還是第一天主會場的內容。我想吸引大家的一直是 Flutter 新版本 stable1.9 的重磅發佈。

新版本一個重要功能就是 Flutter For Web 倉庫合入 Flutter master 主倉庫,意味著我們可以真正地使用一套代碼、一套資源部署大前端。輔導團隊經過一段時間的準備,使用 Flutter 開發的 Web 頁面也即將發佈,希望和大家分享下實踐過程和踩坑實例,歡迎一起交流探討。

頁面改造

Flutter For Web 谷歌官方一直建議暫時不要在生產環境使用。但如果不嘗試,我們永遠不知道這裡會藏有什麼樣的秘密,什麼樣的場景適合。對現有 Flutter 改造,增加對瀏覽器的支持,突破而不失穩重。

1. 增加 Web 支持

我們原先的版本使用 Flutter 1.5.4,增加 Web 支持,我們需要切換到最新的 master 分支,改造運行。

Flutter For Web:人人都是大前端開發

如果我們只是新建一個新的項目,只需切換到最新的 master 分支,創建一個新的項目即可。創建完成之後,根目錄下會多出一個 web 文件夾,裡面只有一個 web 入口文件 index.html。

Flutter For Web:人人都是大前端開發

2. 修改 dart:io 庫

原有項目中如果直接運行 flutter run -d chrome,會發現控制器中 import 報錯,原因是 dart: io 庫不支持 web。io 庫是 Flutter 中非常常用的庫,主要是平臺相關的一些 api,改造的第二步我們就需要屏蔽 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

Flutter For Web:人人都是大前端開發

UI 側我們仍然使用同一套代碼,邏輯側通過 library 庫分區 native 還是 web,邏輯側對應不同的平臺實現。這幾天,我看到一個新的區分方法,簡單而且實用:web 側我們可以判斷 0 和 0.0 是否是一個對象。

Flutter For Web:人人都是大前端開發

區分完不同平臺,我們還需要辨別不同設備,這裡我建議搭建 app 初始化的時候配置完成,後續方便實用。

3. 網絡請求

原有 Flutter 項目我們通過 MJFlutter 調用 Native 的網絡接口,實現數據請求。輔導 web 側是通過 CGI 請求獲得後臺數據,現在 web 需要另一種方式,給大家推薦幾種方式:

a. package:http/http.dart

pub 鏈接:https://pub.dev/packages/http#-readme-tab-

b. package:http/html.dart

c. package:dio/dio.dart

pub 鏈接:https://pub.dev/packages/dio#-installing-tab-

dio 這個網絡庫,大家之前可能用過,需要注意一點,3.0 之前的版本 Flutter For Web 不支持 (dart:io)。3.0 之後的版本,這個庫經過官方大改造,現已支持 Flutter For Web 開發。
我推薦的是 dio 這個庫,使用起來會比較方便,參數簡單好理解。

有了基本的網路請求,配置完 CGI,接下來就是界面的展示。但是你會發現,所有的業務請求都沒有回包,無法得到數據。如果作為移動端開發,沒有經常接觸到 http 請求,一下子發矇,我覺得可以理解。這個是 Web 開發中經常遇到的

跨域問題。前端開發們這裡可以舉手了,這個問題我會。簡單的處理方式就是開發過程中掛上一個代理,具體就不詳細展開了。

網路問題解決,進入發佈調試,上文我們介紹過 Flutter For Web 的最終產物是三個文件。如何發佈,前端同學又可以舉手了。有一個簡單的方式:github pages(配置方法:https://pages.github.com/)。

JavaScript 擴展

與使用 Flutter 實現的頁面不同,Flutter For Web 的頁面使用 Http 請求獲取後臺數據。Http 請求中很重要的一點是 header 中的 cookie,這裡就需要通過 dart 與 js 之間的交互,還是要稱讚下 Flutter 團隊的實力。

官方說明:https://dart.dev/web/js-interop

pub 地址:https://pub.dev/packages/js

Flutter For Web:人人都是大前端開發

Flutter For Web:人人都是大前端開發

dart 封裝 js 方法

Flutter For Web:人人都是大前端開發

Flutter For Web:人人都是大前端開發

添加完 js 支持後,dart 側調用 getStringFromJS 方法,並打印結果。

通過 js.dart 這個庫,可以實現 web 側的主要功能。例如 cookie、localStorage。

Flutter For Web:人人都是大前端開發

Flutter For Web:人人都是大前端開發

dart 封裝 js 方法

處理完 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:

展望

整體來說,Flutter For Web 達到成熟還有一段時間。在這段時間裡,儘早佈局,未免不是一件好事。Flutter For Web 現階段的使用場景並不多,不如直接使用 Web 開發便捷、穩定。但我們可以通過 Flutter,拉近與大前端的距離,感受大前端的魅力,做一個真正的大前端開發

騰訊企鵝輔導團隊會繼續實踐,不管是 Flutter 實現的頁面,還是 Flutter 轉 Web 的頁面。Flutter For Web 一個複雜的場景,我們會嘗試降級及熱更新能力,與 Web 同學通力合作,封裝 App 和 Web 的基礎 API、集成 CI 等,歡迎與我們一起交流。

Flutter For Web:人人都是大前端開發

技術服務於業務,業務推動技術,二者並行,提升用戶體驗,Flutter 道路上期待大家的反饋。


分享到:


相關文章: