螞蟻前端研發最佳實踐(推薦)


螞蟻前端研發最佳實踐(推薦)

準備這個題目時我 google 了下前端最佳實踐,排在前面的是講前端代碼規範,語意、可讀性、編碼規範、空格還是 Tab 等等,我覺得這是我們第一代的最佳實踐。

而現在都 9012 年了,最佳實踐也經歷了很多代的變更,下面是我們在這方面的思考和實踐。

自我介紹

螞蟻前端研發最佳實踐(推薦)

目錄

螞蟻前端研發最佳實踐(推薦)

為什麼要有最佳實踐?

螞蟻前端研發最佳實踐(推薦)

螞蟻前端研發最佳實踐(推薦)


不知大家在這些方面是否有疑惑?

  • 前端發展快,每次發佈 Umi 版本時,除了點贊,還有人求別發,表示實在學不動了。右邊這張圖是之前的朋友圈看到的,轉到公司群裡,有共鳴的人不少,說明一定程度反應了現在前端社區的情況。
  • 面對海量“輪子”,我應該學哪些,不學哪個?,我的前端知識點學習列表已經是完全學不完的狀態,比如社區上光數據流方案就有幾百個,其中值得一看的也有四五十個吧。
  • 然後,大家在創建項目時,是否也有過選擇困難?


螞蟻前端研發最佳實踐(推薦)


這裡舉一個具體的例子,

  • 框架
  • 基於 React 的框架
  • 語言
  • CSS 方案
  • 數據流
  • 請求庫
  • 等等

可以發現,每個點都會有不少選擇,並且有時還真的很難選,因為每個人看待它的角度不同。所以,對於開發者來說,真的有點太難了!他只是想完成需求,然後回家睡覺,為啥需要選這麼多,就不能給個默認的嗎?

螞蟻前端研發最佳實踐(推薦)


然後,

  • 如果每個項目都要選,我覺得會很難。當然,也有人可能會覺得是一種樂趣。
  • 而對於團隊而言,如果每個項目的選擇還都不一樣,那麼團隊的研發成本和效率都會是問題。想象一下,如果一個同學換個項目組,需要接觸完全不同的技術棧。

所以,對於團隊而言,保持一致非常重要。

螞蟻前端研發最佳實踐(推薦)

那麼,如何保持一致?不同團隊會有不同的選擇,通常有這幾類,

  • 文檔
  • 腳手架
  • 框架

約束能力和迭代能力也是逐步遞增。

我們最早應該是用的文檔。比如做一些代碼約定,用 Tab 還是空格,用兩個空格還是 4 個空格,行尾要不要加分號等等,這一類主要靠開發者自覺,所以我覺得不太靠譜,這也是為啥後來有 eslint。

腳手架比文檔好點,但也依賴開發者的自覺性,因為還是可以隨便改。前幾年 React 社區上有不少做的很好的腳手架,但現在基本上都沒有活躍的了。

第三種方式是框架,他的約束性可以做的比較強。比如約定用 less,如果開發者用了 sass,就給他報個錯。同時相比其他兩種方式,還有迭代能力。腳手架交給用戶之後是很難更新的,框架則是自己更新後,開發者的項目自動生效。

當然,這三者不是互斥關係,可以都用嘛。

螞蟻前端研發最佳實踐(推薦)


然後如何決定用啥方案,用 SASS 還是 LESS,要不要用 TypeScript,甚至目錄用複數還是單數這種極其無聊的事情。

不同團隊會有不同的選擇,

  • STAR 數,大家通常會選 STAR 數多的,社區認同感很重要,比如 DVA 在螞蟻的推廣就是先從社區做起的
  • 簡單 vs. 規範,有人會選擇概念少而簡單的,有人會選擇概念多但看起來更規範的
  • 先入為主,先佔坑的往往具有優勢
  • 老闆喜歡,

老闆喜歡其實 “很重要”。有些大家吵很久但決定不了的事,往往會很自覺地找老闆或者德高望重的同學進行拍板,我們也是如此。

螞蟻前端的選擇

螞蟻前端研發最佳實踐(推薦)

螞蟻前端研發最佳實踐(推薦)


我們在不同時期的最佳實踐是不同的,曾經還開發過 spm,不自量力地試圖挑戰 npm + webpack 組合,雖然失敗了,但敢想也是一種勇氣。(做 spm 時,webpack 還沒出來)

螞蟻前端研發最佳實踐(推薦)


我們有很多方向,然後每個方向又有很多選擇,圖上是我們目前的選擇。

從這裡可以看到幾點,

  • 選擇的內容基本上是社區主流的,不脫離社區是基本原則
  • 很多子方向都選擇了自研或者正在考慮自研

為啥要自研呢?

螞蟻前端研發最佳實踐(推薦)


我覺得自研會帶來一些好處,

  • 自主權 vs. 成本,在擁有自主權的時候,需要評估其帶來的成本,以及潛在的棄坑可能
  • 定製化,
  • 需求滿足,社區方案有時並不能很好地契合我們的需求,尤其當我們很深入地去使用的時候
  • 售後服務,出錯是能找到 owner 的同學是非常重要的一點

有些開源庫看起來美好,但真正用下來會發現坑不少。比如組件的文檔工具,目前是選擇的 docz 和 storybook,但兩者用地都有些說不出來的不舒服,並且和 umi 是兩個生態的東西,所以我們正考慮基於 umi 開發自己的文檔工具,可能叫 umipress 或者 father-doc 。

螞蟻前端研發最佳實踐(推薦)


沉澱的方式是以框架為主,文檔、腳手架、資產市場為輔。

  • 框架具有更強大的約束性和迭代能力,這也是我們所需要的
  • 對外是 Umi,面向社區
  • 對內是 Bigfish,在 Umi 的基礎上解決流程和業務問題

插件和插件集

螞蟻前端研發最佳實踐(推薦)

螞蟻前端研發最佳實踐(推薦)


我們把使用到的技術都沉澱到框架(Bigfish)裡。框架像是一個魔法球,把各種技術棧吸到一起,加工後吐給用戶,以此來支撐業務。

對於用戶來說,Bigfish 框架是唯一依賴。唯一依賴會帶來一些實際的好處,這也是我們一直在內部堅持這一點的原因,

  • 技術收斂,保持團隊開發模式的一致性
  • 無痛升級,我們既要保持對社區的技術跟進,又要讓業務項目跟上步伐,這些中間的屎只能讓框架吃掉,讓開發者儘可能地無痛升級
  • 應用治理,相比散落的遍地開花的依賴,唯一依賴可以讓我們更好地推動用戶升級框架,因為只要管一個點即可

唯一依賴的問題就是大而全,雖然看起來挺不優雅,但實際用過之後會發現還蠻香的,除了一開始安裝他會有點慢。(這一點我們後續會通過啟動器解決)


螞蟻前端研發最佳實踐(推薦)


做了技術棧收斂之後,我覺得對外可能夠了,但對內還遠遠不夠。

  1. 接流程,讓開發者能更順暢地跑通創建、本地開發、聯調、部署、發佈和統計
  2. 接後端框架,後端可能是 Java、Node 或者 PHP(),不同後端對於前端產物的要求會不同,在框架裡做好對接,開發者就不用費心思了
  3. 接場景,場景有很多種,在框架層也需做好對接。舉一些例子
  4. SPA 應該是目前用地最多的一種應用類型,但有時也會不滿足需求
  5. 比如運營頁面,多個頁面之間沒有一點點關係,也不需要互相跳轉,用 SPA 就沒有意義,這時候 MPA 可能更適合
  6. 比如語雀,我們的文檔平臺,他有前臺、有後臺、有 PC 端、有無線端,如果整體是一個 SPA,不僅尺寸大,公共依賴的提取是個問題,不同場景之間可能還會相互影響,這時候,多 SPA 的組合會更適合他
  7. 微前端前面已經提過
  8. SSR 和 Prerender 則是為了更好的瀏覽器性能,順便解決 SEO 的問題
  9. 接服務,比如登錄服務,統計服務,問卷服務,評論服務等等

實現方式是一“件”接入,這裡的件是插件,一個插件實現一個功能。然後,我們就有了很多插件。

螞蟻前端研發最佳實踐(推薦)


有了插件之後,我們可以篩選一些插件出來形成插件集,以滿足某個業務的需求,類似 babel 的 plugin 和 preset,或者 eslint 的 rule 和 config。

**這種方式首先可以滿足不同業務的需求。**比如無線業務,會比較關注性能,所以可能會選一個切 preact 到 react 的插件、極速版補丁插件、高清方案、fastclick 等等,形成一個插件集。

**然後還可以滿足一個技術的不同實現,**在一個業務類型豐富的大團隊中,是允許有不同的選擇的。比如數據流,大家的選擇可能不同,有些用 dva,有些用 hooks,有些用 mobx,有些自研一套;比如補丁方案,有常規版、極限版,還有終極版。

螞蟻前端研發最佳實踐(推薦)


這是 umi 的插件三態,講過好多次了,文字稿裡就不重複了。

螞蟻前端研發最佳實踐(推薦)


這是 umi 插件的示例。想提一點的是,會用 umi 和會寫 umi 插件是兩個完全不同的狀態,會寫 umi 插件,你基本可以魔改 umi 內部 70% 的功能,可以此來達到滿足需求業務需求的目的。

螞蟻前端研發最佳實踐(推薦)

螞蟻前端研發最佳實踐(推薦)

資產市場和場景市場

螞蟻前端研發最佳實踐(推薦)

螞蟻前端研發最佳實踐(推薦)


先來看下開發者的時間都去哪了。這是我諮詢了一些同事拍腦袋整理的,不太準確。

  • 20% 流程相關,從創建到發佈和發佈後統計
  • 40% 組件使用和開發,如果有合適組件,直接使用;如果沒有,花時間開發
  • 30% 交互場景,解決遇到某個交互場景如何處理,以及處理來自後臺的請求,把數據和視圖串起來
  • 10% 其他

知道了時間分配後,大家應該知道投時間去解決哪部分的問題,才能真正達到提效的目的了吧。

螞蟻前端研發最佳實踐(推薦)

資產市場用於解決 40% 的開發者時間,非常重要。分為四個概念,

  • 基礎組件,antd
  • 業務組件,基於 antd 封裝的具有業務屬性的組件,不對外
  • 區塊,組件的使用片段,區塊是為了方便地把代碼片段加到項目代碼中
  • 模板,多個區塊組成的頁面
螞蟻前端研發最佳實踐(推薦)

而資產市場要真正達到提效的目的,我覺得還需要解決一些關鍵的點,才能讓整個流程跑起來。

  • 資產質量,組件參考 antd,區塊和模板是實實在在要被添加到用戶項目的代碼,我覺得比組件更難,需要形成對什麼是好代碼的共同認識,誰都不希望自己的項目變髒
  • 打通上下游,包括組件的生產和消費。生產方是設計師和前端,需要保證組件的本地開發、文檔、打包、發佈等環節;消費方也是設計師和前端,資產市場不僅是給前端用的,設計師也得用,只有前端拿到的設計稿有大量可以對應的資產時,前端開發才能真正提效,所以,設計師是否有能力讓資產市場覆蓋 50% 甚至 80% 的場景非常重要
螞蟻前端研發最佳實踐(推薦)

這是內部的資產市場和外部開源的 antd。

螞蟻前端研發最佳實踐(推薦)

螞蟻前端研發最佳實踐(推薦)


這是資產市場通過 umi ui 的方式使用,支持區塊、模板以及佈局區塊。

螞蟻前端研發最佳實踐(推薦)

右圖來自開源庫 Friend-List,這是一個 suggestion 的實現,他可以簡單做,也可以複雜做。複雜做的話,細節點就會很多,比如:

  • 每次輸入都要做請求
  • 快速輸入的時候,要使用最後的請求,並且取消前面的請求
  • 輸入需要同步到 url
  • 輸入還需要同步到 history,支持前進後退
  • 請求加緩存
  • 請求出錯處理
  • ...

而如果每個開發者都要去關心這些細節,會很難,成本也很高。那麼如何讓開發者做到又快,產品體驗又好,我覺得可能需要場景市場,用於解決 30% 的交互場景需求。

沉澱方式可以用 hooks + 文檔的方式;覆蓋面從最簡單的 CURD 開始,到各種複雜場景。


螞蟻前端研發最佳實踐(推薦)


這裡是部分的場景舉例。

螞蟻前端研發最佳實踐(推薦)

理想的工作流圖。

強約束的垂直領域框架

螞蟻前端研發最佳實踐(推薦)


基於前面講的插件和插件集的方式,我們已經能夠滿足各種豐富的業務場景,但是仍然給予了用戶很多選擇,選擇包括選擇插件,以及 umi 自身的大量配置項。

對於一些垂直領域,其實還可以做到更好,所以我們最近一直在思考“螞蟻前端應該如何寫中臺代碼”。

螞蟻前端研發最佳實踐(推薦)


有幾個關鍵的思路,

  • 專治,不提供自由的技術棧選擇一定程度上會限制開發者的,但是效率高的,就看你要哪個了
  • 極簡,不僅僅是簡單,還要優雅;不僅要寫地少,還要寫地好

然後就強約束、配置化和約定化展開聊下。

螞蟻前端研發最佳實踐(推薦)


前面我們已經瞭解了一致性的重要性,所以何不把這一點做到底呢?

  • 只能用 TypeScript,用 JavaScript 會報錯
  • 只能用 less + css modules,用 sass、stylus、css in js 會報錯
  • 只能用內置的數據流方案,用 redux、mobx 等等會報錯
  • 等等

圖上只列了一部分。

這裡的有些約束甚至會有些反人類,但我覺得約束越強,越能保持大家的一致性,如果我們已經把這條路探地很清楚了,少給選擇或許是更好的選擇。有些限制還不確定是不是好的方式,但是第一版會盡量把規則收攏地緊一些。

螞蟻前端研發最佳實踐(推薦)


配置化不僅是框架和插件的配置,還包括 UI 。

右圖是 ant-design-pro 的圖,其中 LOGO、導航、菜單對於 90% 的每個頁面來說都是固定的,變化的只有右下的頁面區,所以我們何不把固定的部分做成配置呢?

比如:

<code>export default {
  layout: {
    logo: string;
    title: string;
    renderRender: function;
    logout: function;
  },
  routes: [
    {
      path,
      // 菜單配置
      menu: { name, icon, showBreadcrumb },
      // 權限配置
      access,
    },
  ],
}/<code>


Layout 是其中一個例子,還可以有更多 UI 的配置化。這也是在一定程度在像 low code 的模式靠,我覺得某些研究地很透的垂直場景下,low code 能讓研發更高效。

所以我們把適合做成配置的全部配置化,而不能配置的,則會走約定化。

螞蟻前端研發最佳實踐(推薦)


之前有用過 ruby on rails 框架,特別喜歡那種約定化的編碼方式,所以我們希望把他也搬到前端研發流程裡。

  • 建一個 locales 目錄,就擁有了國際化
  • 建一個 models 目錄,就擁有了數據流
  • 建一個 mock 目錄,就擁有了數據 mock
  • 建一個 access.ts 文件,就擁有了權限策略
  • ...

看起來很黑盒,按照我們約定的方式編碼,並且只能這樣編碼,然後他就能 run 起來。

螞蟻前端研發最佳實踐(推薦)


這是之前在朋友圈看到的圖,大家體會下,但這就是我們想要實現的樣子。

螞蟻前端研發最佳實踐(推薦)


極簡數據流是整體方案的其中一環。

右邊是之前做數據流調研時做的整理,發現那麼多數據流方案基本都是在這些方案上的差異,而要選哪個就看你對哪些方面比較關心。這部分展開聊比較長,之後會額外寫一篇文章介紹。

然後我們還調研了下公司內部的中臺項目,發現大部分是簡單的 CURD,並且全局數據使用較少,比如通知、登錄、當前用戶信息等。所以,我們可能是需要一個不那麼複雜的,用起來又很簡單的數據流方案。

螞蟻前端研發最佳實踐(推薦)


最終討論下來的方案有幾個特點,

  • 基於 hooks,在看到 swr 之後,我開始有點覺得在數據流裡用 hooks 可能是未來的趨勢,因為大量的交互場景都可以通過 hook 沉澱,但也有一點點擔心
  • 和框架強綁,脫離框架我們可能沒有優勢,但是有框架加持,就能做到比社區大量的 hooks 數據流都“好用”,因為中間複雜的事情可以交給框架處理,比如手寫 Provider,比如自動處理 model 依賴等等
  • 約定式 model 定義,在 models 目錄下建文件導出 hooks 就是一個 model
  • 單一 API,在組件層或者 model 層通過 useModel 來使用

總結

螞蟻前端研發最佳實踐(推薦)


文字就不復述了。

這裡和大家分享了螞蟻前端研發實踐中三個重要的點,但其實還有更多的點,比如說 UMI UI,如果感興趣,可以來聽我在 12 月 GMTC 深圳的演講。

鏈接:https://github.com/sorrycc/blog/issues/90

本文是阿里高級前端技術專家雲謙在 2019.11.15 成都全棧大會分享的文字稿,介紹了螞蟻前端研發的最佳實踐,其中提取了三個比較重要的點,每個點都是螞蟻實踐和深入思考後的結果,希望能對大家有所啟發,歡迎探討。

往期推薦:


分享到:


相關文章: