<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          螞蟻前端研發(fā)最佳實踐

          共 5856字,需瀏覽 12分鐘

           ·

          2019-12-08 23:29

          (給前端大學(xué)加星標,提升前端技能.

          作者:云謙

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

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

          開篇

          e0a59b0bfe5cc6817ccf615fb8ba70a3.webp

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

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

          自我介紹

          a3806d7136335400fc7f05bcfe0ffa10.webp

          目錄

          7319935bcfb808cb2a556a9e9db9e6b9.webp

          為什么要有最佳實踐?

          5a4b98d92730f762f0d7cdccf8cd10c9.webp

          cb01e2eee11eb976690780a6ee577a90.webp


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

          • 前端發(fā)展快,每次發(fā)布 Umi 版本時,除了點贊,還有人求別發(fā),表示實在學(xué)不動了。右邊這張圖是之前的朋友圈看到的,轉(zhuǎn)到公司群里,有共鳴的人不少,說明一定程度反應(yīng)了現(xiàn)在前端社區(qū)的情況。

          • 面對海量“輪子”,我應(yīng)該學(xué)哪些,不學(xué)哪個?,我的前端知識點學(xué)習(xí)列表已經(jīng)是完全學(xué)不完的狀態(tài),比如社區(qū)上光數(shù)據(jù)流方案就有幾百個,其中值得一看的也有四五十個吧。

          • 然后,大家在創(chuàng)建項目時,是否也有過選擇困難?




          607605a94d459c140e22ec0db857926a.webp


          這里舉一個具體的例子,

          • 框架

          • 基于 React 的框架

          • 語言

          • CSS 方案

          • 數(shù)據(jù)流

          • 請求庫

          • 等等

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

          ad1cfe2e261f968ffe1dc7ee02fd7d16.webp


          然后,

          • 如果每個項目都要選,我覺得會很難。當然,也有人可能會覺得是一種樂趣。

          • 而對于團隊而言,如果每個項目的選擇還都不一樣,那么團隊的研發(fā)成本和效率都會是問題。想象一下,如果一個同學(xué)換個項目組,需要接觸完全不同的技術(shù)棧。

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

          202e38375d15daf11bdb322b2bc0ad4d.webp

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

          • 文檔

          • 腳手架

          • 框架

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

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

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

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

          當然,這三者不是互斥關(guān)系,可以都用嘛。

          9432c395deee89c0542f3a89c07045c4.webp


          然后如何決定用啥方案,用 SASS 還是 LESS,要不要用 TypeScript,甚至目錄用復(fù)數(shù)還是單數(shù)這種極其無聊的事情。

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

          • STAR 數(shù),大家通常會選 STAR 數(shù)多的,社區(qū)認同感很重要,比如 DVA 在螞蟻的推廣就是先從社區(qū)做起的

          • 簡單 vs. 規(guī)范,有人會選擇概念少而簡單的,有人會選擇概念多但看起來更規(guī)范的

          • 先入為主,先占坑的往往具有優(yōu)勢

          • 老板喜歡?

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

          螞蟻前端的選擇

          1a9fc0bfaf46287568d1d2599c0183e9.webp

          e39ad657c9e4938693ed89a9099ec6a8.webp


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

          c2ea6b7f6d7980f2a448d267a1fa35dd.webp


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

          從這里可以看到幾點,

          • 選擇的內(nèi)容基本上是社區(qū)主流的,不脫離社區(qū)是基本原則

          • 很多子方向都選擇了自研或者正在考慮自研

          為啥要自研呢?

          30186d2ec506c09c49ba777139d00fc6.webp


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

          • 自主權(quán) vs. 成本,在擁有自主權(quán)的時候,需要評估其帶來的成本,以及潛在的棄坑可能

          • 定制化

          • 需求滿足,社區(qū)方案有時并不能很好地契合我們的需求,尤其當我們很深入地去使用的時候

          • 售后服務(wù),出錯是能找到 owner 的同學(xué)是非常重要的一點

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

          677a0b3118a11b2c00324506248ecb96.webp


          沉淀的方式是以框架為主,文檔、腳手架、資產(chǎn)市場為輔。

          • 框架具有更強大的約束性和迭代能力,這也是我們所需要的

          • 對外是 Umi,面向社區(qū)

          • 對內(nèi)是 Bigfish,在 Umi 的基礎(chǔ)上解決流程和業(yè)務(wù)問題

          插件和插件集

          8336d23f94a06ba8a81ec9409cd11eb2.webp

          5603e505d097e9b921f4d3461acbd797.webp


          我們把使用到的技術(shù)都沉淀到框架(Bigfish)里。框架像是一個魔法球,把各種技術(shù)棧吸到一起,加工后吐給用戶,以此來支撐業(yè)務(wù)。

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

          • 技術(shù)收斂,保持團隊開發(fā)模式的一致性

          • 無痛升級,我們既要保持對社區(qū)的技術(shù)跟進,又要讓業(yè)務(wù)項目跟上步伐,這些中間的屎只能讓框架吃掉,讓開發(fā)者盡可能地無痛升級

          • 應(yīng)用治理,相比散落的遍地開花的依賴,唯一依賴可以讓我們更好地推動用戶升級框架,因為只要管一個點即可

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


          3b37d12ebe6c48f38b1c99193b2bf301.webp


          做了技術(shù)棧收斂之后,我覺得對外可能夠了,但對內(nèi)還遠遠不夠。

          1. 接流程,讓開發(fā)者能更順暢地跑通創(chuàng)建、本地開發(fā)、聯(lián)調(diào)、部署、發(fā)布和統(tǒng)計

          2. 接后端框架,后端可能是 Java、Node 或者 PHP(?),不同后端對于前端產(chǎn)物的要求會不同,在框架里做好對接,開發(fā)者就不用費心思了

          3. 接場景,場景有很多種,在框架層也需做好對接。舉一些例子

          • SPA 應(yīng)該是目前用地最多的一種應(yīng)用類型,但有時也會不滿足需求

          • 比如運營頁面,多個頁面之間沒有一點點關(guān)系,也不需要互相跳轉(zhuǎn),用 SPA 就沒有意義,這時候 MPA 可能更適合

          • 比如語雀,我們的文檔平臺,他有前臺、有后臺、有 PC 端、有無線端,如果整體是一個 SPA,不僅尺寸大,公共依賴的提取是個問題,不同場景之間可能還會相互影響,這時候,多 SPA 的組合會更適合他

          • 微前端前面已經(jīng)提過

          • SSR 和 Prerender 則是為了更好的瀏覽器性能,順便解決 SEO 的問題

          接服務(wù),比如登錄服務(wù),統(tǒng)計服務(wù),問卷服務(wù),評論服務(wù)等等

          實現(xiàn)方式是一“件”接入,這里的件是插件,一個插件實現(xiàn)一個功能。然后,我們就有了很多插件。

          f256f920089214cac804e5a92579d3ee.webp


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

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

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

          0ac1022ddf9e321dfafcde11d6cfab60.webp


          這是 umi 的插件三態(tài),講過好多次了,文字稿里就不重復(fù)了。

          fff8dd19deb0c63de19e64915222c56d.webp


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

          836bd34759ccb56bcf8f85f05e903185.webp

          46a55030b80e37b6f0faf6a43321d79c.webp

          資產(chǎn)市場和場景市場

          1f551f73a9ad1bf088183bc59e149ccf.webp

          8e6630127e610f5069355ae11ff14a8d.webp


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

          • 20% 流程相關(guān),從創(chuàng)建到發(fā)布和發(fā)布后統(tǒng)計

          • 40% 組件使用和開發(fā),如果有合適組件,直接使用;如果沒有,花時間開發(fā)

          • 30% 交互場景,解決遇到某個交互場景如何處理,以及處理來自后臺的請求,把數(shù)據(jù)和視圖串起來

          • 10% 其他

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

          ea114f0ff6819d92f03a327e4ad6eeff.webp


          資產(chǎn)市場用于解決 40% 的開發(fā)者時間,非常重要。分為四個概念,

          • 基礎(chǔ)組件,antd

          • 業(yè)務(wù)組件,基于 antd 封裝的具有業(yè)務(wù)屬性的組件,不對外

          • 區(qū)塊,組件的使用片段,區(qū)塊是為了方便地把代碼片段加到項目代碼中

          • 模板,多個區(qū)塊組成的頁面

          655056317105b895e8377f461fbe708b.webp


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

          • 資產(chǎn)質(zhì)量,組件參考 antd,區(qū)塊和模板是實實在在要被添加到用戶項目的代碼,我覺得比組件更難,需要形成對什么是好代碼的共同認識,誰都不希望自己的項目變臟

          • 打通上下游,包括組件的生產(chǎn)和消費。生產(chǎn)方是設(shè)計師和前端,需要保證組件的本地開發(fā)、文檔、打包、發(fā)布等環(huán)節(jié);消費方也是設(shè)計師和前端,資產(chǎn)市場不僅是給前端用的,設(shè)計師也得用,只有前端拿到的設(shè)計稿有大量可以對應(yīng)的資產(chǎn)時,前端開發(fā)才能真正提效,所以,設(shè)計師是否有能力讓資產(chǎn)市場覆蓋 50% 甚至 80% 的場景非常重要

          bbf145166f2bfc453645bcf1d2ad60a9.webp


          這是內(nèi)部的資產(chǎn)市場和外部開源的 antd。

          83d8f3eeb7d7d70b1664cf79af6e82dd.webp

          91cc93a16508e122bd22332cb2bac60c.webp


          這是資產(chǎn)市場通過 umi ui 的方式使用,支持區(qū)塊、模板以及布局區(qū)塊。

          05214366ed3dcfa366ae8e7a6302bc8e.webp

          右圖來自開源庫 Friend-List,這是一個 suggestion 的實現(xiàn),他可以簡單做,也可以復(fù)雜做。復(fù)雜做的話,細節(jié)點就會很多,比如:

          • 每次輸入都要做請求

          • 快速輸入的時候,要使用最后的請求,并且取消前面的請求

          • 輸入需要同步到 url

          • 輸入還需要同步到 history,支持前進后退

          • 請求加緩存

          • 請求出錯處理

          • ...

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

          沉淀方式可以用 hooks + 文檔的方式;覆蓋面從最簡單的 CURD 開始,到各種復(fù)雜場景。


          902e4e8073862cf1453169e978c4a981.webp


          這里是部分的場景舉例。ae026d6517293d70d42e8ac75210466e.webp

          理想的工作流圖。

          強約束的垂直領(lǐng)域框架

          c1242c53c4fe0402fce222537d4c7c2d.webp


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

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

          1141c61db692e0bdc35ff6a2b12aa51c.webp


          有幾個關(guān)鍵的思路,

          • 專治,不提供自由的技術(shù)棧選擇一定程度上會限制開發(fā)者的,但是效率高的,就看你要哪個了

          • 極簡,不僅僅是簡單,還要優(yōu)雅;不僅要寫地少,還要寫地好

          然后就強約束配置化約定化展開聊下。

          5beab6ad5e088f91e0f935702448e16d.webp


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

          • 只能用 TypeScript,用 JavaScript 會報錯

          • 只能用 less + css modules,用 sass、stylus、css in js 會報錯

          • 只能用內(nèi)置的數(shù)據(jù)流方案,用 redux、mobx 等等會報錯

          • 等等

          圖上只列了一部分。

          這里的有些約束甚至?xí)行┓慈祟悾矣X得約束越強,越能保持大家的一致性,如果我們已經(jīng)把這條路探地很清楚了,少給選擇或許是更好的選擇。有些限制還不確定是不是好的方式,但是第一版會盡量把規(guī)則收攏地緊一些。

          d0ceccd32f547cdfed57c35be3cf2091.webp


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

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

          比如:

          export?default?{
          ??layout:?{
          ????logo:?string;
          ????title:?string;
          ????renderRender:?function;
          ????logout:?function;
          ??},
          ??routes:?[
          ????{
          ??????path,
          ??????//?菜單配置
          ??????menu:?{?name,?icon,?showBreadcrumb?},
          ??????//?權(quán)限配置
          ??????access,
          ????},
          ??],
          }


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

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

          4e24a6dc4705dbe8124d6845de4026eb.webp


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

          • 建一個 locales 目錄,就擁有了國際化

          • 建一個 models 目錄,就擁有了數(shù)據(jù)流

          • 建一個 mock 目錄,就擁有了數(shù)據(jù) mock

          • 建一個 access.ts 文件,就擁有了權(quán)限策略

          • ...

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

          0fdb87a600a0faca7783d19201baa6d2.webp


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

          76412b2aaf0cc861fcc0cb6a708214aa.webp


          極簡數(shù)據(jù)流是整體方案的其中一環(huán)。

          右邊是之前做數(shù)據(jù)流調(diào)研時做的整理,發(fā)現(xiàn)那么多數(shù)據(jù)流方案基本都是在這些方案上的差異,而要選哪個就看你對哪些方面比較關(guān)心。這部分展開聊比較長,之后會額外寫一篇文章介紹。

          然后我們還調(diào)研了下公司內(nèi)部的中臺項目,發(fā)現(xiàn)大部分是簡單的 CURD,并且全局數(shù)據(jù)使用較少,比如通知、登錄、當前用戶信息等。所以,我們可能是需要一個不那么復(fù)雜的,用起來又很簡單的數(shù)據(jù)流方案。

          6c4f4292530b3ed0dc4d9ac381e413cc.webp


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

          • 基于 hooks,在看到?swr?之后,我開始有點覺得在數(shù)據(jù)流里用 hooks 可能是未來的趨勢,因為大量的交互場景都可以通過 hook 沉淀,但也有一點點擔心

          • 和框架強綁,脫離框架我們可能沒有優(yōu)勢,但是有框架加持,就能做到比社區(qū)大量的 hooks 數(shù)據(jù)流都“好用”,因為中間復(fù)雜的事情可以交給框架處理,比如手寫 Provider,比如自動處理 model 依賴等等

          • 約定式 model 定義,在 models 目錄下建文件導(dǎo)出 hooks 就是一個 model

          • 單一 API,在組件層或者 model 層通過?useModel?來使用

          總結(jié)

          66525f11e3d3a47f264504bf1f9c3f60.webp


          文字就不復(fù)述了。

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

          分享前端好文,點個?在看?ecc018e75504e436eea60d591779d607.webp

          瀏覽 79
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕不卡一区 | 环亚无码 | 日本调教视频 | 啪啪啪免费网址 | 天天色天天日天天射 |