出處:https://mp.weixin.qq.com/s?__biz=MzA4Nzg0MDM5Nw==&mid=2247493593&idx=1&sn=4b35f91b84544a10db3f628e89870ecf
前言
大家好, 我們是哈囉出行普惠用車前端團隊, 在面臨諸多業務挑戰情況下, 我們團隊在2020年all in Taro, 完成了人效與穩定性的提升。本文將分享此技術策略的演進過程。
現狀與問題
在2020年上半年, 普惠用車前端團隊小程式端主要迭代3個小程式, 哈囉出行微信小程式、哈囉順風車微信小程式、哈囉出行支付寶小程式。在19年我們已經使用Taro實現了2個微信小程式的程式碼複用。假設完成順風車支付寶小程式的需求開發需要4天, 那麼3個小程式的人力基本上是這樣:
微信順風車與微信哈囉出行複用同一套程式碼所以只要開發一端,加上2端測試的時間一共是4人日, 支付寶哈囉出行由於是原生語法需要獨立開發4人日, 一共是 4人日支付寶哈囉出行 + 4日的微信 = 8人日, 拆成2個同學做一週可完成迭代, 看上去似乎還可以接受。但是深究其中, 產品想要的效果2端是一樣的, 開發卻要寫2套, 開發與測試人力被浪費了一部分, 2個開發者2種邏輯思路, 如果線上出現問題也要分別排查, 這種情況一直持續到哈囉打車專項..
哈囉打車是2020年哈囉普惠用車團隊的新業務, 也是公司重點戰略專案, 能夠像其他網約車平臺一樣釋出即時單, 目前在珠三角城市陸續開城, 價格優惠. 大家可以進入哈囉出行支付寶小程式和哈囉出行App嘗試使用。
哈囉打車是一種新的業務嘗試, 產品希望微信與支付寶效果對齊同步迭代, 這就對我們人效提出了巨大的要求, 如果還按照之前2個端2套程式碼的方式, 哈囉打車一端的前端工作量為85人日, 我們假設先編寫支付寶這端, 在開發對業務程式碼熟悉的情況下按照過往經驗推算微信端的程式碼工作量減半, 那麼算下來就是:
一共是 85(支付寶端)+42.5(微信端算支付寶的一半) = 127.5人日, 假設需要在1個月內完成則需要6個同學, 然而, 我們並沒有這麼多人。產品也不能接受很長的等待時間, 這真是一個挑戰. 但好訊息是, 打車與順風車有一些類似的程式碼。
豪華馬車沒有五菱宏光快 -- 魯迅
突破與創新All in Taro
所以我們決定使用一個能夠同時編寫支付寶與微信的跨端框架, Taro是我們在19年就在使用的跨端框架, 我們在微信小程式上使用它, 他表現的很好雖然我們只是在微信上使用, 但其與社群接軌的語法和jsx, 給我們的程式碼增加了不少健壯性。
我們也在19年使用了monorepo的方式實現了2個小程式使用同一套程式碼, 使得人效提高30%, 我們對它很熟悉, 於是我們決定也在這次的專案中使用它。
Taro已經發布到第三個大版本了, 在比較了一系列資料與綜合考量之後, 我們選擇最新的Taro3.0。
| | v3 | v2 | | dist dev size | 2.6M | 416K | | dist pro size | 272K | 192K | | package size | (142.5 KB) | 192K |
萬事開頭難
正如如上所說, 打車與順風車有一些類似的程式碼, 但是語法又不太類似, 所以也許我們可以copy過來翻譯一下語法, 太好了! 馬上開幹。
在半小時的複製黏貼之後, 突然發現jsx寫錯了 似乎是尖括號少了一個那麼是哪裡呢? 半小時後..
嗯? 還是不對, 忘記匯入依賴了? 半小時後..
生命週期居然拼錯了.. 好了現在完美了, 第一個頁面跑起來了, 等等!? 也就是說我第二個頁面第三個都需要重複這個步驟? 真是有些枯燥啊
真正的聖鬥士同一份程式碼不會編寫2次 -- 魯迅
alipay2taro
為什麼我們不把這個這個過程自動化呢? 這聽起來真不錯.
Taro官方的解決方案
taro其實官方帶一個轉譯器taroize, 能把微信小程式轉換成jsx, 我們馬上嘗試了下, 發現他的實現原理與我們的想要的大相徑庭,自帶一個runtime框架, 變數名稱也不好維護.
只能對整個專案依賴runtime框架生命週期沒有轉譯變數名比較奇怪維護性差或者? 我們可以學習改造他, 然後編寫我們自己的轉換器!
我們需要做些什麼
我們需要將xml, config, js轉換成tsx
首先我們來看看2種語言有什麼區別
我們需要:
匯入一個react宣告,去掉"Compent"把data變成statedefaultprops變成propsonload對映成didmountxml轉換成jsx在render函式中區分props與data檔名稱元件名稱統一重新命名引入react宣告區分元件與頁面轉換區別等等..那我們應該怎麼做呢?
我們需要解析輸入的3種程式碼, 需要使用到以下工具。
利用這些工具, 創造一個流程
先透過@babel/parser把程式碼變成json形式的資料結構(AST)利用@babel/traverse與@babel/types操作剛剛的AST,進行節點刪除和移動新增。這部分很重要下面會詳細講。隨後利用@babel/generator再還原回來變成程式碼最後使用prettier格式化成可讀性強的程式碼簡單來說就是這樣啦.
@babel/types
babel/types提供了節點的各種構造功能, 接下來我會以建立React宣告開始做一個示範,
當我們拿到ast之後, 首先我們如何創造一個import的節點的呢?
我們在babel官網上查詢他的建構函式
隨後呼叫這個api, 並把它封裝成一個方法, 隨後呼叫它, 最後推進body中去.(taro中taroize包的相關實現)。
這樣我們就有一個react聲明瞭!
不知道結點是什麼型別也沒關係 可以在https://astexplorer.net/查詢到。
@babel/traverse
traverse能夠在AST節點中暢遊一番,他會遍歷所有的結點你可以自由操作他們, 並改變他們。
遇到CallExpression(函式呼叫)時候, 我們判斷是不是pagex或者是Component呼叫, 是的話則抓到他的物件.(taro中taroize包的實現)。
parsePage函式就是我們的核心, 我們來實現它。
在上圖中我們迴圈了支付寶js物件中的每個屬性, 我們判斷是不是要我們轉換的, 如果是我們就call相應的節點type的建構函式, 最後一個個推進class中。
至此我們已經解決的大部分的關鍵問題。
xml? jsx?
對了還有render函式呢, 他可是非常重要. 支付寶中使用xml作為檢視邏輯, 所以我們可以使用 himalaya-wxml 把它轉為類似ast的結構, 節點的屬性會變成key value結構, 我們繼續操作他。
看起來我們完成了所有的工作, 於是我決定封裝一個npm包, 使他可以被命令列的方式呼叫。
沉澱與展望
結局的最後, 是我們用一個月時間與4個同學順利完成了哈囉打車專案。
另外我們轉換複用線上順風車9個頁面, 人效提升1.4倍。3個頁面測試階段沒有bug, 平滑的完成了遷移, 現在迭代也只需要1個同學1份程式碼就能完成。
之後, 哈囉出行普惠用車前端團隊也會輸出更多關於人效、質量提升幸福感的工具與系統。
出處:https://mp.weixin.qq.com/s?__biz=MzA4Nzg0MDM5Nw==&mid=2247493593&idx=1&sn=4b35f91b84544a10db3f628e89870ecf