您的位置:首頁>科技>正文

React 技術棧在螞蟻金服的實踐

更多深度文章, 請關注雲計算頻道:https://yq.aliyun.com/cloud

在2017線上技術峰會“阿裡開源專案最佳實踐”上, 螞蟻金服前端工程師崔曉斌為大家帶來了“React 技術棧在螞蟻金服的實踐”的演講。 主要從研發的模式變遷開始說起, 著重說明React元件庫antd相關技術及其應用, 接著分析了dva, 最後闡述了開源的意義。

3月1號下午, 雲棲社區將迎來2017線上技術峰會——“阿裡開源專案最佳實踐”。 來自淘寶、天貓、阿裡雲、螞蟻金服的8位專案核心成員將現場剖析阿裡開源專案背後的技術實踐, 分享開源經驗。 其中, 螞蟻金服前端工程師崔曉斌為大家帶來了“React 技術棧在螞蟻金服的實踐”的演講。

主要從研發的模式變遷開始說起, 著重說明React元件庫antd相關技術及其應用, 接著分析了dva, 最後闡述了開源的意義。

以下是精彩內容整理:

螞蟻金服於 2015 年發佈並開源了基於 Ant Design 設計規範的 React 元件庫 antd, 從那時起, antd 就持續地得到社區的關注和幫助。 經過近兩年的發展, antd 在 GitHub 上面已經擁有超過一萬的 Star, 在內部也落地了超過 400 個項目。 但其實, antd 只是我們推動 React 技術棧落地的一個切入點而已, 為了進一步的提高開發效率同時也需要保證代碼品質和專案的可維護性等, 我們還需要提供 antd 的相關配套工具以及統一的應用架構。

研發模式變遷

傳統研發模式中, 一個專案中會有相應的後端、前端、設計師、產品經理和測試,

每一部分都有專業的人來做。 其中, 只有後端、產品經理和測試是與業務強綁定的, 前端和設計師更多地是作為流動性的資源進行投放。

我們當時面臨著前端和設計資源缺乏的問題, 而我們內部有著大量的中後臺系統, 在資源缺乏的前提下不可能保證每一個系統都有足夠的前端和設計資源。 這些缺乏前端和設計資源的專案的用戶體驗自然不會特別好, 開發效率也不會高。 而且, 前端分散在各個業務線, 對其職業發展也是非常不利的。

因此, 我們的痛點是前端與設計人員緊缺而導致的老系統難以維護、新系統研發效率不高, 大量產品特別是企業平臺類產品的使用者體驗還停留在初級階段, 用戶體驗亟待提升等。

那麼, 如何在資源緊缺的情況下支援大量中後臺產品同時還要兼顧研發效率和用戶體驗?

為了解決這個問題, 我們進行了一次研發模式的變遷, 從傳統研發模式轉變成全棧研發模式。 每一個項目裡面只會會分配相應的全棧開發和產品經理,

前端和設計不再作為資源投入, 僅提供前端或者設計的基礎設施, 也就意味著我們需要從一個資源型團隊向服務型團隊轉變。

在這個過程中, 我們推出了Ant Design中台設計語言。 但 Ant Design只是一個切入點, 為了進一步提高研發效率, 而且還要保證代碼品質和可維護性, 還需要提供一些相關配套。

antd 相關配套

如果只是個人或者小團隊使用antd元件, antd 自身已經能滿足其使用場景。 但像螞蟻金服這樣大規模使用時, 僅僅提供元件庫遠遠是不夠的, 還要提供相關的配套。 目前提供的配套包括Riddle、Themer和腳手架市場。

Riddle

圖為antd在螞蟻金服內部落地的資料, antd在內部大概有四百多個系統在使用, 這些系統還分散在各個業務線, 不同的業務線都有使用antd的UI元件庫。 所以如果全棧開發在使用antd的過程中碰到一些bug, 或是對某些場景有疑問時, 我們就只能進行線上交流。 為了提高溝通效率, 我們需要一個工具來輔助交流。

關注了 ant-design 這個倉庫的同學會知道,如果外部用戶給我們提了一個 bug, 我們會要求他使用 CodePen 提供可重現的線上demo以排查問題,其實 Riddle也起到類似的作用。但之所以會開發Riddle而不是直接使用CodePen,是因為:首先,國內訪問CodePen會面臨網路問題;其次,CodePen的用戶體驗並不怎麼好;第三,螞蟻金服作為一個商業機構,並不是所有的代碼都能開放出去,所以我們需要有一個自己私有的服務。

Riddle 的功能與 CodePen 相似,在左邊編輯代碼,右邊即可即時預覽。

Riddle在用戶體驗上的提升在於:使用Riddle時可以不需要任何配置就能直接使用ES2015和 JSX 的語法,還支援css-modules,同時,Riddle也做了優化,如果檢測到代碼使用了import語句,就會自動載入相應依賴,並且可以指定依賴的版本。

Riddle首頁左側有一些標籤,右邊是相應標籤下的示例。通過打標籤的方式將Riddle的示例整理起來,可以起到Cookbook的作用,給全棧開發提供不同場景下的參考實現。

同時,示例也會按業務線進行劃分,比如在同一條業務線,會有一些通用的代碼,我們就可以將這些代碼沉澱在Riddle上面作為一個示例,然後全棧開發就可根據需要參考這些示例的實現,或直接拷貝使用。之所以是把公共代碼寫成 Riddle 的示例而非業務組件,是因為並不是所有業務代碼都具備抽象成業務元件的價值,所以只能作為Riddle示例存在。

Themer

使用過 antd的同學應該會知道,其實 antd的主題是可以配置的,通過配置變數表裡的變數可以修改 antd的主題。但這個配置方法並不特別友好,因為它需要使用到構建工具,所以我們提供了Themer這個主題配置平臺。

進入主題配置頁面,就可以在左邊配置相關變數,右邊即時預覽效果。最後可以將變數表匯出。現在已經提供了不少可配置的變數,包括顏色、邊框、按鈕、字體、表單控制項和圓角等等。

同時,Themer還是一個主題共用平臺,當我們配置好主題後,可以保存到Themer上,其他人可以通過Themer找到他需要的主題直接使用,或基於該主題再進行配置。

腳手架市場

新建一個項目時,首先要新建相關的目錄結構,然後要配置專案依賴和工具,這是一個繁瑣並重複的勞動;其次,現在前端構建流程越來越複雜,我們不可能一開始就把環境配置好。為了解決前面兩個問題,我們可以提供腳手架工具。

通過dva-cli,我們可以生成通用的腳手架。但往往還需要對腳手架進行進一步的配置,才能符合自己所開發專案的需求。所以,全棧開發人員為了方便,可能會選擇直接拷貝同一條業務線裡的其它項目作為腳手架使用。但拷貝過來的專案會有大量不需要的代碼,配置也不一定是需要的,甚至依賴都是舊版本。所以我們要針對不同的使用場景,有針對性地提供符合其特點的腳手架。

所以我們提供了antd自己專用的腳手架市場,以便我們的用戶通過它分享或者查找腳手架。與 Yeoman的 generator相比,腳手架市場的腳手架開發難度相對較低。

目前腳手架市場已經開放到外部,可以通過GitHub帳號登錄,並且可以在登錄後以PR的形式將整理出的腳手架提交到腳手架市場。

同時腳手架市場也支持線上上預覽腳手架運行起來之後的效果。

應用架構 dva

由於前端的業務邏輯和資料層都在變得越來越複雜,我們在使用React時不可能僅僅使用React原生提供的資料通信方案,或直接用React元件管理業務邏輯,所以需要框架説明處理這些問題。同時,我們內部有近500個系統在使用React技術棧,不可能讓每一個項目自己去折騰一套自己資料通信等方案。所以我們要提供一個統一的應用架構,也就是dva。

在談 dva 之前,需要先瞭解一下螞蟻金服 React 應用架構的歷史。其實與antd同期,我們就開始探索自己的應用架構Roof,並且Roof@0.4就開始在內部大規模推廣,但由於Roof本身概念比較多,難於理解,所以在Roof@0.5中簡化了一些概念,並引進了Redux裡面的概念,然後在反覆運算的過程中,Roof 變得越來越像 Redux,最後甚至直接用Redux作為核心。

Redux

在 Roof 變得和 Redux相差無幾後,不少專案就開始直接使用Redux了,直接使用 Refux可以享受到很多好處:

羽量級資料流程方案,解決從 state 到 component 的單向資料流程轉問題

借助 Action 和 Reducer 實現可預測的 state 變更

社區活躍,豐富的擴展、調試方案

但 Redux 的使用也帶來了新的問題:

項目中遇到的每個問題都有非常多的庫以供選擇,給專案帶來了技術選型的成本;

Redux作為一個類庫,並沒有對代碼作過多的約束,這是靈活性,但對於螞蟻金服這種規模的使用而言,就會變得不可控;

開發功能時,一個功能的代碼分散在 reducers actions sagas 等目錄下面,需要來回切換,影響專注力;

使用者發起非同步請求時頁面或部分 UI 需要進入 loading 狀態,這需要通過一遍遍重複地寫 showLoading 和 hideLoading來實現;

出錯處理太繁瑣,每個非同步 saga 都要 try .. catch;

專案太大了,需要動態載入方案。

Dva

所以我們推出了自己的應用架構dva,就是為了解決上面的問題。dva開放以來,已經得到了廣泛的認可,現在在github上已經有2600個star,並且得到了大V的支持和推廣。現在dva已經是我們內部主推的應用架構,有接近20%系統在使用dva。

那麼。dva到底是什麼呢?

dva是一個框架而非類庫,它會對代碼的寫法和組織方式有比較多的約束以保證不同團隊寫出的代碼盡可能相似;其次,它是基於 redux, react-router, redux-saga 的羽量級封裝;最後,它借鑒 elm 的概念,包括Reducer, Effect 和 Subscription等。

dva僅有5個API,支持HMR,支持 SSR (ServerSideRender),支持 Mobile/ReactNative,支援 TypeScript,支援路由和 Model 的動態載入,並提供了完善的語法分析庫 dva-ast。

圖為dva寫的相對簡單的應用程式,新建應用,並註冊相關的model和路由後,就可以給 React 元件訂閱一些資料,最後啟動就可以把應用渲染到頁面了。

關於開源

開源不僅僅是開放源碼。

對專案而言:

開源是一塊試金石。解決一個問題有多種方案,每種方案也會有多種實現,那麼哪種方案是最好的呢?我們可以通過把項目開源開放到社區上,讓社區篩選出相對優秀的方案。

開源是一種軟體發展模式。同一個項目如果僅僅在內部使用,很多時候我們只會滿足於可用。但開放到社區後,社區就會根據自己的使用場景去評估並實踐這個專案,對於其中不合理的地方提出建議。

開源專案需要經營。antd就有許多地方需要經營,包括貢獻氛圍、語言氛圍和互助氛圍,有利於社區健康發展。

對個人而言:

開源是一種學習方式,開源可以展示個人能力。

崔曉斌:螞蟻金服前端工程師,目前主要負責 React 元件(如:antd、react-component)及配套工具(如:bisheng)的開發。

關注了 ant-design 這個倉庫的同學會知道,如果外部用戶給我們提了一個 bug, 我們會要求他使用 CodePen 提供可重現的線上demo以排查問題,其實 Riddle也起到類似的作用。但之所以會開發Riddle而不是直接使用CodePen,是因為:首先,國內訪問CodePen會面臨網路問題;其次,CodePen的用戶體驗並不怎麼好;第三,螞蟻金服作為一個商業機構,並不是所有的代碼都能開放出去,所以我們需要有一個自己私有的服務。

Riddle 的功能與 CodePen 相似,在左邊編輯代碼,右邊即可即時預覽。

Riddle在用戶體驗上的提升在於:使用Riddle時可以不需要任何配置就能直接使用ES2015和 JSX 的語法,還支援css-modules,同時,Riddle也做了優化,如果檢測到代碼使用了import語句,就會自動載入相應依賴,並且可以指定依賴的版本。

Riddle首頁左側有一些標籤,右邊是相應標籤下的示例。通過打標籤的方式將Riddle的示例整理起來,可以起到Cookbook的作用,給全棧開發提供不同場景下的參考實現。

同時,示例也會按業務線進行劃分,比如在同一條業務線,會有一些通用的代碼,我們就可以將這些代碼沉澱在Riddle上面作為一個示例,然後全棧開發就可根據需要參考這些示例的實現,或直接拷貝使用。之所以是把公共代碼寫成 Riddle 的示例而非業務組件,是因為並不是所有業務代碼都具備抽象成業務元件的價值,所以只能作為Riddle示例存在。

Themer

使用過 antd的同學應該會知道,其實 antd的主題是可以配置的,通過配置變數表裡的變數可以修改 antd的主題。但這個配置方法並不特別友好,因為它需要使用到構建工具,所以我們提供了Themer這個主題配置平臺。

進入主題配置頁面,就可以在左邊配置相關變數,右邊即時預覽效果。最後可以將變數表匯出。現在已經提供了不少可配置的變數,包括顏色、邊框、按鈕、字體、表單控制項和圓角等等。

同時,Themer還是一個主題共用平臺,當我們配置好主題後,可以保存到Themer上,其他人可以通過Themer找到他需要的主題直接使用,或基於該主題再進行配置。

腳手架市場

新建一個項目時,首先要新建相關的目錄結構,然後要配置專案依賴和工具,這是一個繁瑣並重複的勞動;其次,現在前端構建流程越來越複雜,我們不可能一開始就把環境配置好。為了解決前面兩個問題,我們可以提供腳手架工具。

通過dva-cli,我們可以生成通用的腳手架。但往往還需要對腳手架進行進一步的配置,才能符合自己所開發專案的需求。所以,全棧開發人員為了方便,可能會選擇直接拷貝同一條業務線裡的其它項目作為腳手架使用。但拷貝過來的專案會有大量不需要的代碼,配置也不一定是需要的,甚至依賴都是舊版本。所以我們要針對不同的使用場景,有針對性地提供符合其特點的腳手架。

所以我們提供了antd自己專用的腳手架市場,以便我們的用戶通過它分享或者查找腳手架。與 Yeoman的 generator相比,腳手架市場的腳手架開發難度相對較低。

目前腳手架市場已經開放到外部,可以通過GitHub帳號登錄,並且可以在登錄後以PR的形式將整理出的腳手架提交到腳手架市場。

同時腳手架市場也支持線上上預覽腳手架運行起來之後的效果。

應用架構 dva

由於前端的業務邏輯和資料層都在變得越來越複雜,我們在使用React時不可能僅僅使用React原生提供的資料通信方案,或直接用React元件管理業務邏輯,所以需要框架説明處理這些問題。同時,我們內部有近500個系統在使用React技術棧,不可能讓每一個項目自己去折騰一套自己資料通信等方案。所以我們要提供一個統一的應用架構,也就是dva。

在談 dva 之前,需要先瞭解一下螞蟻金服 React 應用架構的歷史。其實與antd同期,我們就開始探索自己的應用架構Roof,並且Roof@0.4就開始在內部大規模推廣,但由於Roof本身概念比較多,難於理解,所以在Roof@0.5中簡化了一些概念,並引進了Redux裡面的概念,然後在反覆運算的過程中,Roof 變得越來越像 Redux,最後甚至直接用Redux作為核心。

Redux

在 Roof 變得和 Redux相差無幾後,不少專案就開始直接使用Redux了,直接使用 Refux可以享受到很多好處:

羽量級資料流程方案,解決從 state 到 component 的單向資料流程轉問題

借助 Action 和 Reducer 實現可預測的 state 變更

社區活躍,豐富的擴展、調試方案

但 Redux 的使用也帶來了新的問題:

項目中遇到的每個問題都有非常多的庫以供選擇,給專案帶來了技術選型的成本;

Redux作為一個類庫,並沒有對代碼作過多的約束,這是靈活性,但對於螞蟻金服這種規模的使用而言,就會變得不可控;

開發功能時,一個功能的代碼分散在 reducers actions sagas 等目錄下面,需要來回切換,影響專注力;

使用者發起非同步請求時頁面或部分 UI 需要進入 loading 狀態,這需要通過一遍遍重複地寫 showLoading 和 hideLoading來實現;

出錯處理太繁瑣,每個非同步 saga 都要 try .. catch;

專案太大了,需要動態載入方案。

Dva

所以我們推出了自己的應用架構dva,就是為了解決上面的問題。dva開放以來,已經得到了廣泛的認可,現在在github上已經有2600個star,並且得到了大V的支持和推廣。現在dva已經是我們內部主推的應用架構,有接近20%系統在使用dva。

那麼。dva到底是什麼呢?

dva是一個框架而非類庫,它會對代碼的寫法和組織方式有比較多的約束以保證不同團隊寫出的代碼盡可能相似;其次,它是基於 redux, react-router, redux-saga 的羽量級封裝;最後,它借鑒 elm 的概念,包括Reducer, Effect 和 Subscription等。

dva僅有5個API,支持HMR,支持 SSR (ServerSideRender),支持 Mobile/ReactNative,支援 TypeScript,支援路由和 Model 的動態載入,並提供了完善的語法分析庫 dva-ast。

圖為dva寫的相對簡單的應用程式,新建應用,並註冊相關的model和路由後,就可以給 React 元件訂閱一些資料,最後啟動就可以把應用渲染到頁面了。

關於開源

開源不僅僅是開放源碼。

對專案而言:

開源是一塊試金石。解決一個問題有多種方案,每種方案也會有多種實現,那麼哪種方案是最好的呢?我們可以通過把項目開源開放到社區上,讓社區篩選出相對優秀的方案。

開源是一種軟體發展模式。同一個項目如果僅僅在內部使用,很多時候我們只會滿足於可用。但開放到社區後,社區就會根據自己的使用場景去評估並實踐這個專案,對於其中不合理的地方提出建議。

開源專案需要經營。antd就有許多地方需要經營,包括貢獻氛圍、語言氛圍和互助氛圍,有利於社區健康發展。

對個人而言:

開源是一種學習方式,開源可以展示個人能力。

崔曉斌:螞蟻金服前端工程師,目前主要負責 React 元件(如:antd、react-component)及配套工具(如:bisheng)的開發。

Next Article
喜欢就按个赞吧!!!
点击关闭提示