多平臺背景
小程式是一種無需安裝即可使用的應用。從2017開始,小程式增速加快,潛力巨大,因此許多網際網路平臺都擁有都加快了小程式發展步伐,出現瞭如微信小程式,支付寶小程式,百度小程式等。
易盾的行為式驗證碼功能自從推出微信小程式SDK後,受到許多客戶的好評,並接到大量其他平臺的諮詢。從產品和業務的發展角度考慮,支援更多平臺的小程式能更好地滿足客戶的需求,增強自身產品亮點。
為什麼做轉換工具
當SDK需要支援多個平臺時,若每個版本都單獨維護則會增加大量維護成本,因此我們需要一個方案來解決跨端輸出問題。
經過調研,市場上關於多平臺的方案主要有兩種,一種是使用跨端框架,如Taro等;另一種是使用轉換工具轉換後再修改,如百度提供的wx2。我們分析了兩種方案的優劣勢,結果如下:
綜上,跨端框架更適用於應用,對SDK來說太重;轉換工具更適合SDK,但市場上的轉換工具存在平臺缺失等限制。為了解決這一問題,易盾透過自研轉換工具,實現一份原始碼一鍵輸出多端小程式的SDK。
功能及實現
經過各家小程式的文件對比,多家小程式的語法、介面等與微信小程式相似,主要差異在於一些功能支援度、模板屬性的命名規則等細節。
為了實現多平臺轉換,轉換工具基於微信小程式的原始碼,包括以下支援功能:
• 轉換檔案目標型別
各平臺相似功能的檔案字尾並不相同,需要將相似功能的檔案轉成目標平臺的字尾。
• JS/模板 API替換
各平臺相似的功能API可能命名不同,需要替換成對應的API
• JS API polyfill
各平臺相似功能的API可能存在使用或功能細節上的區別,可以利用polyfill抹平差異
• 環境變數
類似process.env,可以區分平臺。針對某平臺實現時可使用環境變數
• 語法相容檢測
檢測是否存在其他平臺不支援的特性
整體設計方案
設計方案針對不同的檔案型別,進行了不同的轉換處理。當前工具是基於任務流對原始檔進行轉換,整體流程如下:
1. 對不同檔案型別進行處理
2. 對模板、樣式、JSON檔案進行內容替換,實現屬性等轉換
3. 需要樣式命名隔離的平臺,如支付寶小程式,增加命名隔離處理
4. 對於應用級別或外掛複製project.conifg.json到目標資料夾
5. 對JS進行API處理,包括全域性變數及API處理
6. 複製api polyfill檔案至根目錄
7. 完成轉換,並輸出至目標資料夾
整體流程
模板/樣式/JSON轉換
由於模板語法差異較小,對於檔案內容可直接用替換的方式實現模板轉換,例如wx:if替換成s-if,模板資料格式轉換,實現微信轉成百度小程式。
需要注意的是,支付寶元件沒有做樣式命名隔離,為了防止命名衝突,對元件的樣式加字首處理實現隔離。
JSON檔案元件命名規則需要轉換,使用內容替的方式處理。例如對於微信轉百度小程式進行如下圖所示的處理:
值得注意的是,不同平臺間的小程式模板標籤、屬性支援程度不一,對於平臺無法支援的TAG、屬性儘量不使用。在轉換前,先使用語法相容檢測功能檢測下是否存在目標平臺不支援的屬性。同樣的方式可以使用於樣式檔案的處理。
除了內容需要處理,模板檔案及樣式檔案字尾都需修改成對應平臺的檔案字尾。
JS轉換
轉換工具對於js的處理主要是基於babel的語法抽象能力,主要經過如下步驟,最終處理成目標平臺的js檔案:
1. 抽象生成語法樹
2. 遍歷並處理節點
3. 將語法樹轉換成文字
babel三部曲
處理js的第二步是js轉換的關鍵,利用babel的外掛機制,對不同的節點進行處理。js的處理有統一的處理流程,如環境變數的處理,API的替換等。此外,各平臺獨立也可以根據自己需求對節點進行處理。
如下圖所示,所有平臺都會對屬性節點執行全域性變數替換,並支援各平臺做額外的處理。
值得注意的是,SDK類產品存在一個雷區,即修改全域性性的屬性容易對客戶的應用產生影響。為了防止該情況的發生,轉換工具對各平臺差異的API使用runtime transform的方式進行polyfill,不更改全域性上、變數上的任何方法。
因此,轉換工具除了轉換部分的功能,還包含一個polyfill庫,這個庫支援客戶自定義,如專案中已存在的polyfill。
落地遇到的坑
轉換工具第一個落地專案是驗證碼小程式SDK,落地後流程如下:
在落地過程中,開發者不可避免地陷入一些“坑”中。一是,由於轉換工具的polyfill不完整,影響部分API的轉換。二是,原來的程式碼存在不可轉換的相容性問題。三是,小程式轉換工具不能完全抹平平臺之間的差異。
其中,最大的問題就是prop的差異。如果子孫元件共享一個物件,原先在微信上的方案無法在其他平臺實現,索性可以透過環境變數區分平臺,以支援另一種方案。
當然,先用工具提供語法相容檢測功能,並檢測可能存在的不相容API,也是一種方式。但這僅作為一個參考,畢竟官方的API處在不斷補全的過程中。
成果
在改造驗證碼小程式SDK原專案後,我們實現了一份原始程式碼,支援一鍵輸出微信、百度、位元組跳動、頭條小程式版本,實現驗證碼支援更多平臺,且一定程度上降低維護成本。