從工程化角度討論如何快速構建可靠React組件

前言

React 的開發也已經有2年時間了,先從QQ的家校羣,轉成作互動直播,主要是花樣直播這一塊。切換過來的時候,業務很是繁忙,接手過來的業務比較凌亂,也沒有任何組件複用可言。javascript

爲了提升開發效率,去年10月份也開始有意識地私下封裝一些組件,而且於今年年初在項目組裏發起了百日效率提高計劃,其中就包含組件化開發這一塊。css

本文並非要談如何去寫一個 React 組件,這一塊已經有很多精彩的文章。例如像這篇《從新設計 React 組件庫》,裏面涉及一個組件設計的各方面,如粒度控制、接口設計、數據處理等等(不排除後續也寫一篇介紹組件設計理念哈)。html

本文關鍵詞是三個,工程化、快速和可靠。咱們是但願利用工程化手段去保障快速地開發可靠的組件,工程化是手段和工具,快速和可靠,是咱們但願達到的目標。前端

前端工程化不外乎兩點,規範和自動化。java

讀文先看此圖,能先有個大致概念:
defaultnode

 

規範

目錄與命令規範

規範,主要就是目錄規範和代碼規範。跟同事合做,通過將近20個的組件開發後,咱們大概造成了必定的目錄規範,如下是咱們大體的目錄約定。哪裏放源碼,哪裏放生產代碼,哪裏是構建工具,哪裏是例子等。有了這些的約定,往後開發和使用並一目瞭然。react

命令咱們也進行了規範,以下,webpack

代碼規範

代碼規範,主要是寫 js,css 和 html 的規範,基本咱們都是沿用團隊以前制定好的規範,若是以前並無制定,例如 React 的 jsx 的寫法,那麼咱們就參考業界比較優秀的標準,並進行微調,例如 airbnb 的 JavaScript 規範,是不錯的參考。git

自動化

開發與發佈自動化

規範是比較人性的東西,憑着人對之的熟悉就能夠提升效率了,至於那些工做繁複的流程,單憑人的熟悉也會達到極限,那麼咱們就須要藉助自動化的工具去突破這重極限。es6

例如代碼規範,單憑人的肉眼難以識別全部不合規範的代碼,並且效率低下,藉助代碼檢測工具就可以讓人卸下這個重擔。如 css ,咱們推薦使用 stylelint ,js 則是 eslint。有這種自動化的工具協助開發者進行檢查,能更好地保障咱們的代碼質量。

自動化最爲重要的任務是,去保證開發過程良好的體驗還有發佈生產代碼。實際上,開發和發佈組件的整個過程跟平時開發一個任務很像,但卻又略有差別。

首先是開發過程當中,咱們但願一邊開發的時候,咱們開發的功能可以顯示出來,這時最好能搭建一個demo,咱們把 demo 放到了 example 目錄下,這點對 UI 組件(像toast, tips等組件) 尤其重要,邏輯組件(像ajax, utils等組件),能夠有 demo,也能夠採起測試驅動開發的方式,先制定部份測試用例,而後邊開發邊進行測試驗證。

開發過程當中的這個 demo, 跟平時開發項目基本一致,咱們就是經過配置,把 html,js, css 都搭建好,並且咱們是開發 React 組件,引入熱替換的功能令整個開發流程很是流暢。這裏分別是 webpack 和配合 `webpack 開發的靜態資源服務器的兩份配置: webpack & server

可是發佈組件的這個過程跟開發項目卻又很不一樣。開發項目,咱們須要把全部的依賴都打包好,而後一併發佈。但對於組件來講,咱們只須要單獨將它的功能發佈就行了,它的相關依賴能夠在實際開發項目中引用時一併再打包。所以這裏的 package.json 寫的時候也要有所區分。跟只跟開發流程、構建、測試相關的,咱們一概放在 devDependencies 中,組件實際依賴的庫,則主要放在 dependencies 中。

鑑於咱們項目通常採用 webpack 打包,所以咱們通常只須要 es6 import 的引入方式,那咱們直接用 babel 幫咱們的項目進行生產代碼的編譯打包就能夠了,這樣能有效減小冗餘代碼。配置好 .babelrc,而後配置 package.json 的打包命令便可。要注意的是,你的組件可能含有樣式文件,配置命令的時候要記得將樣式文件也複製過去,像下面的命令,–copy-files 參數就是爲了將樣式文件直接拷貝到 dist 目錄下。

但有時候,你也想組件能兼容多種引用方式,即 umd,那 babel 的這種打包就不夠了。這時你能夠藉助 webpack 打包 library 的能力。可參考此 配置。主要是配置 output.library 和 output.libraryTarget

另外一點要注意的是,咱們只需打包組件的邏輯就行了,那些依賴,能夠等實際生產項目的時候再進行解析。但 webpack 默認會將依賴也打包進行,爲了不這點,你須要將這些依賴一一配置成爲 external,這就告訴了 webpack 它們是外部引用的,能夠不用打包進來。

打包完成以後,根據指引進行 npm publish 就能夠了。這裏大致總結了一下咱們開發組件的一些流程和注意事項

測試自動化

上述講的都跟如何提高開發效率有關的,即知足 「快速」 這個目標,對 」可靠「 有必定幫助,如穩定的流程和良好的代碼規範,但並無很是好地保證組件地穩定可靠。須要 」可靠「的組件,還須要測試來保證。

很多開發者作測試會使用 mocha,若是是 UI 組件可能會配置上 karma。而 React 組件測試還有一個更好的選擇,就是官方推薦的 jest + enzyme

jest 跟 jasmine 有點相似,將一個測試庫的功能大部份集成好了(如斷言等工具),一鍵安裝 babel-jest 能夠用 es6 直接寫測試用例,搭配 jest-environment-jsdom 和 jsdom 可以模擬瀏覽器環境,結合 airbnb 寫的 react 測試庫 enzyme, 基本能知足大部份的 React 測試需求。確實符合官方的宣傳語 painless,這是一個無痛的測試工具。

測試邏輯組件問題倒不大,UI組件對於大部份的狀況均可以,許多事件均可以經過enzyme 模擬事件進行測試。但這裏舉的例子, react-list-scroll 組件,一個 React 的滾動列表組件,碰巧遇到一種比較難模擬的狀況,就是對 scroll 事件的模擬。這裏想展開說一下。

對於 React 的 scroll 事件而言,必需要綁定在某個元素裏才能進行模擬,不巧,對於安卓手機來講,大部份 scroll 事件都是綁定在 window 對象下的。這就很是尷尬了,須要藉助到 jsdom 的功能。經過 jest-environment-jsdom,它可以將 jsdom 注入到 node 運行環境中,所以你能夠在測試文件中直接使用 window 對象進行模擬。例以下面代碼,模擬滾動到最底部:

細心的你會發現,上圖還有一些定時器的邏輯。緣由是在組件中會有一些截流的邏輯,滾動時間隔一段時間纔去檢測滾動的位置,避免性能問題,所以加一個定時器,等待數據的返回,而 jest.runAllTimers(); 則是用於告訴定時器立刻跑完。

除此以外,定時器裏還有個 try catch 的邏輯,主要是若是 expect 驗證不經過,jest 會報告錯誤,這時需用錯誤捕獲的辦法將錯誤傳給 done (異步測試的回調),這樣才能正常退出這一個測試用例,不然會返回超時錯誤。

安卓測完了,那iPhone呢?iPhone 的 scroll 事件是綁定在具體某個元素裏的,但我這裏又不是經過 React 的 onScroll 來綁定。首先咱們得經過 window.navigator.userAgent 來區分手機類型。但因爲 userAgent 只有 getter 函數,直接設置值會報錯,所以咱們要添加一個 setter 函數給它,用這段示例代碼:

而後,去找到這個綁定的元素,進行事件監聽和分發就行了:

總結

本文主要是提取了開發組件工程化的一些關鍵要點,具體的開發腳手架能夠參考 steamer-react-component,裏面主要舉了pure-render-deepCompare-decorator 和 react-list-scroll,一個邏輯組件,一個UI組件,共兩個示例,對照着腳手架的文檔,從目錄規範、開發流程、發佈都寫得較爲清楚,你們開發組件的時候,能夠根據狀況作些調整。

若有謬誤,懇請斧正。

原創文章轉載請註明:

轉載自AlloyTeam:http://www.alloyteam.com/2017/03/from-an-engineering-point-of-view-discusses-how-to-construct-reliable-components-react/

相關文章
相關標籤/搜索