你們好,我叫李偉濤,來自凹凸實驗室。今天跟你們分享的主題是用 React 開發小程序的探索之路 。前端
在目前市面上已經有很是多的小程序開發框架,其中的佼佼者如 wepy 以及 mpvue ,他們都是很是優秀的小程序開發框架。可是它們都有一個共同的特色,都是經過類 vue 語法的小程序開發框架。這點對於國內一些 react 的開發者來講就顯得有點遺憾了。vue
咱們團隊在去年就總體轉入了 react 開發陣營,對於咱們團隊來講, react 會更加熟悉一些。因此咱們一直在探索如何用 react 開發小程序,前端時間咱們開源了一個框架,叫作 Taro 。本次也會圍繞這個,來分享 探索使用 react 開發小程序。主要包含如下五個部份內容:react
開發小程序由三部分組成,這三大部分都是由四種類型文件,以下圖所示:git
咱們以 JS 文件爲例:github
咱們在寫原生小程序的時候,這兩份代碼是很是常見的。 它們都是藉助函數工廠類的方式去構建頁面以及組件。 在小程序中的一大特點就是使用字符串模板的形式來編寫界面,如圖:小程序
以上就是一些小程序官方寫法上的一些約定,但也是這些約定,讓開發者存在一些開發上的痛點,這些痛點主要集中在:微信小程序
在開發體驗上,代碼組織稍顯複雜。 當組件和頁面愈來愈多,項目愈來愈龐大的時候開發成本就會顯得有點高,其次就是編碼體驗不夠順暢,以下圖:性能優化
頁面或者組件沒法被繼承的時候,咱們在實現一些功能的時候會受到一些限制 ,同時小程序自己提供了一些 API ,可是卻沒有提供一個跟編輯器很好結合的東西,當咱們在使用這些 API 的時候缺少智能提示。 其次就是字符串模板稍顯孱弱。例如 :微信
當咱們實現一個日期格式化的時候,點擊的時候沒法傳參,還有就是直接寫一個格式化函數是沒法運行的,咱們須要藉助 wxs 這樣的一些工具去實現這樣的一個功能,可是這樣是很是麻煩的。 還有就是小程序的代碼規範並非很統一,以 Button 組件爲例:架構
一些屬性參數都是有很大的差別的。 其次就是缺少統一的自動化編譯處理,致使沒法直接在小程序中直接使用一些 新的 ES 語法,以及 SASS 、 LESS 來書寫樣式代碼。
在性能瓶頸上面,小程序的總體架構是這樣的:
分爲視圖層和邏輯層,這兩個層之間是有一個特定的通訊方式的,當咱們在調用 setData 去更新視圖的時候,小程序首先把你傳入的數據 使用 JSON.stringify 進行序列化,以後拼接成一段可執行的 JS 腳本,最後運行。在這樣的一層通訊機制上,致使去調用 setData 的去更新視圖的時候成本很是之高。因此小程序官方也是提供了一些對於性能優化上的提示
針對以上的痛點和限制,業界也有一些優秀的解決方案,諸如 mpvue, wepy, 可是它們都是類 vue 的開發框架。正如前面所說,這樣子的話對於咱們團隊或者使用 react 的開發者有點遺憾。
使用 react 來開發應用帶來的的一些好處:
react 和 小程序是有一些共同特色的
正由於這樣,也是更加想用 react 來開發小程序。 通過進一步的研究發現,小程序和 react 之間的差別是很是大的 主要是因爲三大塊的差別:
JS 代碼對比:
生命週期對比:
模板對比:
這麼大的差別致使咱們想用 react 來開發小程序的難度很是之大,因此咱們應該怎麼使用 react 來開發小程序呢? 仔細思考一下咱們的需求,咱們是但願經過 react 語法的代碼來開發小程序,那麼其中的核心工做就是將 react 代碼經過某種轉換操做,變成小程序能夠運行的代碼。這樣一種在兩種語法之間轉換的這種操做其實就涉及到一個編譯原理。 編譯原理的一個大體過程大概如圖所示:
其中最核心的就是把源代碼編譯成 AST (虛擬語法樹),而後將 AST 進行轉換操做得出目標代碼。 在 JS 中,它是有本身的 AST 規範來進行定義,這個規範就是 ESTree Spac
在 JS 領域中,有很是多的 JS 的解析器,來幫你把代碼轉換成語法樹的工具,其中最廣爲應用的就是 BABEL。
它提供了一套很是完成的工具來幫你作代碼轉換。 從源代碼到語義分析,咱們均可以藉助 BABEL 來進行轉換。 在這以後的語法樹轉換、代碼優化仍是須要們本身來進行的,這一部分也是很是繁瑣且複雜。
在 Taro 中,咱們經過在編譯時處理以及運行時適配來轉換成小程序代碼,
編譯時的處理:
在 JSX 中,一般有各類各樣的寫法:
這致使在編譯的時候很是複雜,須要作大量的測試用例來保證轉換是正常的。
代碼編譯出來時候,仍是不能只在小程序上運行的,小程序須要一個運行時的適配來幫助咱們把代碼運行在小程序裏面。 運行時的框架主要是一些生命週期的轉換適配,還有一些事件處理。
僅僅這些是不夠的,若是真正須要投入開發使用仍是有點差距的。這個時候我麼你須要一個開發工具來進行配合。
同時,Taro 來提供了一些貼心的功能,來幫助咱們得到良好的開發體驗
開源之初,因爲種種緣由,Taro 的微信小程序端組件化採用的是小程序 <template />
標籤來實現的,利用小程序 <template />
標籤的特性,將組件 JS 文件編譯成 JS + WXML 模板,在父組件(頁面)的模板中經過 <template />
標籤引用子組件的 WXML 模板來進行拼接,從而達到組件化的目的。 實踐證實,Template 模板方案是一個失敗的組件化方案,Taro 開源初期的 Bug 主要來源於此。由於這一方案將 JS 邏輯與模板拆分開了,須要手工來保證 JS 與模板中數據一致,這樣在循環組件渲染、組件多重嵌套的狀況下,要保證組件正確渲染與 props 正確傳遞的難度很是大,實現的成本也很是高。並且,囿於小程序 <template />
標籤的缺陷,一些功能(例如自定義組件包含子元素,等)沒法實現。
因此,在通過艱辛的探索與實踐以後,咱們採用了小程序原生組件化來做爲 Taro 的小程序端組件化方案,而且經過一些處理,繞開了小程序組件化的諸多限制,爲 Taro 的穩定性打下了堅實基礎,並帶來了如下好處:
其中有個重要的改進,小程序端性能的優化
最初的版本中,僅僅是對小程序 setData 作了一次異步封裝,最終調用 setData 更新的時候仍是傳入了完整數據。
以前咱們講到過在頻繁的調用 setData 和 數據量很是大的時候,小程序就會變得異常卡頓,性能不好。
Taro 在框架級別幫助開發者進行了優化,在 setData 以前進行了一次數據 Diff,找到數據的最小更新路徑,而後再使用此路徑來進行更新
除此以外,咱們還作了更多
從 開源 到如今,Taro 一共經歷了 1800 餘次提交,平均天天近 20 次,最多的一天達 30 次。每一次提交都是進步,每一次提交都讓 Taro 更增強大。通過這麼屢次迭代以後,已經讓 Taro 得到重生,尤爲是小程序組件化重構完成以後,Taro 從舊版架構的泥潭中一躍而出,成爲更加健壯的開發框架。 在咱們本身不斷反思、優化的同時,也積極融入開源社區,依託社區的力量去建設 Taro。 Taro 到目前爲止,一共收到了 500 餘個 ISSUES,已關閉近 400 個,正是由於這些 ISSUES ,讓咱們不斷意識到 Taro 的不足,讓咱們知道如何去進行迭代。 同時,咱們也一直鼓勵社區的開發者積極提 PR,一個優秀的開源項目須要依靠整個社區的力量才能完善起來,到目前爲止,一共收到了 120 餘個 PR,已幾近所有合入,這些 PR 爲 Taro 注入了許多新鮮血液,讓 Taro 更加健壯,咱們也指望能有更多的開發者能夠加入進來,一塊兒來讓 Taro 更加美好。 在 GitHub 上交流之餘,咱們也爲開發者們開通了官方微信羣供你們一塊兒討論 Taro 與技術,目前已有超過 1700 位開發者在關注、使用 Taro ,期待更多開發者的加入。
在開源期間,隨着 Taro 的逐步完善,愈來愈多的開發者加入到 Taro 的使用、開發中,產生了更多更優秀的使用案例。
Taro 的發展離不開廣大開源愛好者的幫助,在此特別鳴謝廣大 Taro 的使用者以及 Taro 主要貢獻者
Taro 將會繼續保持迭代,目前已經規劃了以下重要功能:
在編譯時與運行時提供代碼診斷的功能,分析代碼優劣,斷定代碼寫法是否規範,以便幫助開發者規避一些因爲寫法帶來的問題。 同時將提供一套測試方案,方便開發者書寫並運行組件測試用例,提高代碼質量。
目前 Taro 只能一次調試一個端,這對於開發多端應用來講效率略低,因此,計劃提供微信小程序/ H5 / React Native 端同時調試的功能,能夠一鍵啓動多端同時編譯,從而得到多端同步預覽。
目前已支持 Taro 代碼到小程序代碼、 H5 代碼的轉換,在將來,將提供逆向轉換功能,幫助開發者將本來就存在的小程序/H5 項目直接轉換成 Taro 項目,從而讓本來只能運行在一端的項目得到多端運行的能力,下降開發者的重構成本。
Taro 是遵循 React 語法規範的,可是 React 一直在迭代在變化,Taro 做爲 React 的追隨者也將會保持與 React 新特性同步,讓 Taro 最大程度接近 React 開發體驗。
目前 Taro 已經完成了快應用端組件庫與 API 的適配,快應用端的文件轉換與模板轉換也正在開發中,不久的未來就會發布支持快應用端轉換的版本。 支付寶小程序與百度智能小程序支持 已預研支付寶小程序與百度智能小程序轉換的可行性,即將進入開發。
目前 Taro 是依靠開發者手工編寫代碼來得到多端應用的,Taro 將來計劃提供一個多端可視化拖拽搭建的功能,能夠經過拖拽組件的方式來生成多端應用。 同時,Taro 將聯合各大公司小程序開發團隊,推出豐富的行業模板,爲各行業應用可視化搭建提供完整的解決方案。
在開源之初,Taro 一直處於封閉的狀態,沒有適配的 UI 庫,也沒法使用第三方組件庫,而這些對開發效率的桎梏很是嚴重,社區內對此反饋較多。因此,咱們基於 Taro 推出了首個能夠跨多端使用的多端 UI 庫 Taro UI,目前已經支持了微信小程序與 H5 端,不久以後將完成 React Native 端的適配,能夠同步提供給 React Native 端使用。