跨端開發的最佳實踐——Chameleon(變色龍 )

前言

近期,在公司落地了一個社區內比較 新(踩)的(坑) 跨端框架 Chameleon,當時的需求是先實現快應用端,以後須要支持 H五、微信小程序、字節小程序等。因爲公司用的技術棧是以 Vue.js 爲主,在作了一番技術選型後,最終選擇了 Chameleon(開始瘋狂踩坑 😳)javascript

這個時候,可能會有人問:爲何不選 uniapp?這麼說吧,uniapp -> 快應用就不是一個坑了,是個炸彈 💣。後面,我會講解爲何不選 uniapp 😲

不過,理性評價,Chameleon 確實是一個優秀的跨端框架。至於優秀在哪?(請繼續閱讀 😶)html

本次文章將會分爲如下三個部分,經過介紹、對比現有前端跨端框架,來逐點講述 Chameleon 優秀之處 😍:前端

  • 爲何咱們須要跨端?
  • 爆炸發展的前端跨端框架
  • Chameleon 將來的跨端方案

1. 😷 爲何咱們須要跨端?

固然,瞭解這個原因的同窗,能夠跳過這個小節哈~

這個問題,咱們能夠分爲兩個維度去解釋:vue

需求的多變性java

現今,小程序實在是太多了...並且,對於日異變動的需求,今天可能和你說的是微信小程序,過了一段時間,可能會和你說一樣的產品,你寫個快應用版的 😲。對於需求方來講,他們並不關注你是怎麼實現的不一樣端,而且,可能還會以爲,你作個同樣的東西只是平臺不同那不是很快嗎web

技術的維護性json

從技術維護維度思考,這是爲了咱們更好地維護代碼,儘可能經過維護一套代碼來實現不一樣端的產品,例如微信小程序、字節小程序、快應用、H5 等等。因此,選擇跨端框架開發的方式,給咱們帶來的好處:小程序

  • 保證上新功能時的穩定
  • 出現問題時的,快速 touble shot
  • 減小寫重複性的代碼
  • and so on...

2. 💥 爆炸發展的前端跨端框架

如今,前端可選擇的跨端框架有不少,Taro、uniapp、kbone、mpvue、Chameleon 等等。固然,其中部分仍是有技術限制的,例如騰訊的 Kbone 只能支持 web 端和微信小程序同構,京東的 Taro 支持的 DSL 是 React,Uniapp 支持的 DSL 是 Vue。因此,框架雖多,可是仍是那句大白話,適合本身所處技術團隊的纔是最好的 🤓️。微信小程序

接下來,咱們來簡單認識一下支持 Vue 的 DSL 的四個跨端框架 mp-vue、uniapp、kbone、Chameleon:前端工程化

2.1 mpvue

mpvue 是 fork 自 Vue@2.4.1 版本,其保留了 Vue2.x 的一部分東西,例如使用 flow 來作靜態類型檢測、默認的一些語法等。mpvue 設計思路大致上是修改 Vue2.x 運行時和模版編譯的部分,針對不一樣的平臺對編譯生成的 AST(抽象語法樹)作語法轉化到指定端的語法,從而完成對不一樣端的代碼生成。

友情提示:mpvue 的 GitHub commit 最近一次 commit 是 17 個月前

2.2 uniapp

uniapp 我想不少同窗都耳熟能詳,估計有些接觸的前端同窗,就是由於這個,畢竟 DCloud 也算是「大名鼎鼎」。前面,也說起 mpvue 最近的一次的 commit 已是 17 個月前,而 uniapp 能夠支持把 mpvue 的項目轉爲 uniapp 的項目(估計能多很多使用者 😏)。

uniapp 在跨端方面確實是很優秀,引入了條件編譯的機制來支持不一樣端的表現,例如咱們要在 H5 和微信小程序兩個不一樣端顯示用戶頭像,前者能夠經過微信提供的數據顯示用戶頭像,後者能夠直接使用 open-data 組件獲取。那麼,經過條件編譯咱們能夠這樣寫:

<!-- #ifdef MP-WEIXIN -->
   <open-data class="img-avatar" type="userAvatarUrl"></open-data>
<!-- #endif -->
<!-- #ifdef H5 -->
   <img :src="avatar" class="avatar" />
<!-- #endif -->
條件編譯,只會將符合這個條件的平臺下的代碼寫入該平臺的項目代碼中

而且,uniapp 能跨端的類型也是很完善的,也支持快應用。可是,不一樣於其餘小程序,快應用是自繪渲染引擎,而不是 webview 渲染。因此,目前 uniapp 對於快應用只支持了 vivo、oppo、華爲這三種廠商。

所以,這也是我起初作技術選型的時候,放棄 uniapp 的緣由。不過 uniapp 還支持轉 webview 版的快應用,可是 webview 版的快應用又不是全部廠商都支持的...

2.3 kbone

kbone 是騰訊團隊推出的一套支持 Web 端和微信小程序端進行同構的跨端框架。可是,顯然相比較前面二者,kbone 的使用場景就略少一些,由於其受限於只支持 Web 端和微信小程序端。不過,若是需求只是 H5 和微信小程序,顯然 kbone 是一個不錯的選擇,畢竟原裝正版(騰訊)的技術支持。

那麼,接下來就輪到 Chameleon 了,主角即將登場 😎~

3. 🐲 Chameleon 將來的跨端方案

Chameleon 做爲跨端框架中的新興勢力,它一樣有一套本身的 DSL(特點領域語言),即也能夠稱它爲 CML。可是,不一樣於上述咱們介紹的跨端框架,Chameleon 擴展多端的方式是採用的多態協議的方式,這裏咱們引用一下官方的介紹

Chamleon 經過定義統一的語言框架 + 統一多態協議,從多端(對應多個獨立服務)業務中抽離出自成體系、連續性強、可維護強的「前端中臺服務」。

3.1 多態協議

官方的介紹中出現了一個你們可能沒有接觸過的一個名詞多態協議。那麼,Chameleon 的多態協議是什麼?

首先,咱們從理論層面瞭解一下什麼是多態協議,Chameleon 的多態協議設計的想法 💡 源於 Apache Thrift - 可伸縮的跨語言服務開發框架。那麼,什麼是 Apache Thrift ?

Apache Thrift 是一個採用 接口描述語言定義並建立服務,支持可擴展的跨語言服務開發的框架。 用大白話講,就是 Apache Thrift 使得不一樣語言(Java、C、PHP)建立的服務能夠被互相調用。

而 Chameleon 框架的核心機制之一 —— 多態協議則是借鑑了這種設計,提供了多態接口多態組件的方式來擴展第三方端(微信小程序、快應用、字節小程序等)。例如,咱們能夠經過定義多態接口來實現不一樣端的特定 API,而後在業務代碼層面直接使用定義好的多態接口就能夠實現一個方法調用在不一樣端下的特定 API,這看起來會是這樣:

而且,對於目前 Chameleon 默認支持的跨端平臺來講,其編譯生成的代碼只是支持了 Chameleon 官方提供的基礎組件和 API,例如在微信和快應用中經常使用到的組件 listtext,API setStoragegetStorage 等等。

那麼,這些不一樣端是如何基於 Chameleon 規定的基礎組件和 API 來擴展實現的呢?接下來,我會以 Chameleon 擴展快應用端的實現爲例,帶你們深刻淺出一番其中的因此然 😲 ~

3.2 如何擴展一個新端

首先,不得不說的一點就是 Chameleon 能夠完美支持跨快應用的開發,可是這個過程有一點點坑,不過踩掉就行~

那麼,這裏咱們來了解一下基於 Chameleon 擴展快應用須要作什麼?這個過程主要是由 6 個 packages 完成:

|—— cml-quickapp-api              ## 實現 CML 提供的 api
|—— cml-quickapp-plugin            ## 實現編譯相關處理,例如生成 .ux 文件、manifest.json 文件
|—— cml-quickapp-runtime            ## 實現 App、Page、Component 組件實例
|—— cml-quickapp-store            ## 實現 CML 的狀態管理
|—— cml-quickapp-ui            ## 實現 CML 的普通組件
|—— cml-quickapp-ui-builtin        ## 實現 CML 的 Native 組件
實際上快應用是 7 個 package,還有一個 cml-quickapp-mixins,它會對一些指令和事件(例如 c-model、touchstart)作兼容處理。

能夠看到擴展一個端,咱們至少須要 6 個 packages,而這 6 個 packages 完成了這 4 點:

而其中每一點須要實現的細節,官方文檔已經講解很詳細了,這裏就不重複論述。本小節只是簡單介紹一下每一個 packages 的職責,讓同窗們能夠具有 debugger 源碼的一點思路,有興趣的同窗能夠自行了解其中的代碼細節。

接下來,咱們講講在業務開發中要如何擴展某個端的特定 API,即多態接口。

3.3 如何擴展某個端的 API(多態接口)

假設,此時咱們處於快應用開發的場景,須要爲應用添加桌面。而快應用添加桌面的 API 不在 Chameleon 官方文檔規定的 API 中,因此這個時候就須要實現多態接口,即咱們要須要自定義快應用添加桌面的 API。

首先,建立 shortcut.interface 文件,在該文件中定義 API 的類型:

<script cml-type="interface">
  type successCallBack = (res: boolean) => void
  type failCallBack = (res: boolean) => void
  type obj = {
    success: successCallBack,
    fail: failCallBack
  }

  interface UtilsInterface {
    installShortCut(obj): void;
    hasInstalled(obj): void;
  }
</script>
相信你們能夠看出來,其實接口的類型定義和 TypeScript 中的類型定義大同小異。

而後,在 shortcut.interface 文件中,定義添加桌面的類,其中包含兩個方法 installShortCut()hasInstalled(),在方法內部能夠直接使用快應用的原生 API:

<script cml-type="quickapp">
class Method implements UtilsInterface {
  installShortCut(obj) {
    quickapp.shortcut.install(obj)
  }
  hasInstalled(obj) {
    quickapp.shortcut.hasInstalled(obj)
  }
}

export default new Method()
</script>
<script cml-type="web">
class Method implements UtilsInterface {
  installShortCut(obj) {
  }
  hasInstalled(obj) {
  }
}
export default new Method();
</script>
...

而且,這裏須要注意 ⚠️ 2 點:

  • 爲了保證其餘端的正常運行,shortcut.interface 文件中一樣須要聲明其餘端對應的方法,這裏咱們能夠是一個空函數
  • 不能直接在方法的內部使用 shortcut API。由於,在快應用中 shortcut 是綁定在 system 上的,而 system 在編譯時會被注入代碼中以 quickapp 存在,因此咱們必須經過 quickapp.shortcut 的方式調用

最後,咱們就能夠在業務代碼中使用添加桌面的 API,而且它只會在快應用下有所表現:

<template>
  <page title="index">
    <text @click="addShortCut"></text>
  </page>
</template>
<script>
import shortCut from "../../components/utils/shortcut.interface";
  
class Index {
    methods = {
      addShortCut() {
        shortCut.installShortCut({
          success: (res) => {
            console.log(res)
          },
          fail: (err) => {
            console.log(err)
          }
        })
      }
    }
}
</script>
而擴展某個端的組件( 多態組件)和擴展 API 大同小異。chameleon-tool 也提供了命令 cml init component 來初始化一個多態組件模版,這一塊官方文檔也詳細介紹了,這裏就不作論述哈。

3.4 小結

多態組件和多態接口都是多態協議的一部分,多態協議還支持多態模版,這會相似於 uniapp 的條件編譯,能夠指定 template 中展現的組件所屬的端(僅做用於 root element)。而且,我想懂得了如何使用多態組件、多態接口、多態模版,那麼使用 Chameleon 開發能夠說是爲所欲爲。

最方便的是萬不得已時咱們能夠改一點源碼哈哈 😄

結語

Chameleon 這個框架給個人感覺,確實是又愛又狠 😷。由於,當時在項目開發過程當中,快應用團隊寫的擴展有幾個問題,我爲了保證項目的正常上線,因此只能硬着頭皮魔改源碼抗着項目往前走 😳,最終項目也成功上線。而後,在週末的時間,我也整理了一些對 Chameleon 框架的理解,以及修復了幾個快應用擴展存在的問題(順手提了個 PR)。

最後,歡迎 👏 打算在業務中嘗試 Chameleon 的同窗一塊兒交流心得(加我微信或公衆號),若是在快應用實現中遇到了坑,我想我應該能夠幫助一二,而且,若是文中存在表達不當或錯誤的地方,歡迎各位同窗提 Issue~

參考

深刻淺出主流的幾款小程序跨端框架原理

Chameleon 統一的語言框架 + 多態協議

Apache Thrift - 可伸縮的跨語言服務開發框架

Chameleon 擴展新端標準

❤️ 愛心三連擊

寫做不易,能夠的話麻煩點個贊,這會成爲我堅持寫做的動力!!!

我是五柳,喜歡創新、搗鼓源碼,專一於 Vue3 源碼、Vite 源碼、前端工程化等技術分享,歡迎關注個人 微信公衆號:Code center

相關文章
相關標籤/搜索