指尖前端重構(React)技術調研分析

1、爲何選擇React

React是當前前端應用最普遍的框架。三大SPA框架 Angular、React、Vue比較。css

  • Angular出現最先,但其在原理上並無React創新的性能優化,且自身相對來講顯得笨重。
  • Vue出現最晚,其核心原理學習了React,只是語法形式的變化,關係上來講React是開拓者,Vue是學習者。
  • React社區有強大活力與創新能力,不斷涌現革命性的創新產品,其中包括可使用JS操做原生控件的React Native,Vue後來跟進學習出了相似的Weex,但二者成熟度差不少。

目前來看React的生態系統要比Vue大的多,在github、stackoverflow等最大的技術社區搜索二者,React的搜索結果是Vue的十倍左右,另外據近期統計使用React的站點是Vue的幾百倍以上。更大的生態意味着更多可用的資源,以及遇到問題能夠獲得更多的有效參考與幫助,這也是除了性能以外選擇React的核心緣由。html

選擇React以後,應用會在如下幾個方面有提高。前端

  • 第一,原先的html間跳轉會有短暫的白屏現象,這一點在安卓性能較差的機器上尤其明顯,而React做爲單頁應用沒有這個問題。
  • 第二,React 提供的虛擬DOM包含Diff算法,即將原dom copy一份,與改動後的dom對比,只渲染不一樣的dom節點,實現最小代價渲染,vdom創新的性能優化方式對性能的提高毋庸置疑。
  • 第三,React中核心組件化技術,更加容易的綁定事件行爲,動態更新特定的dom,代碼更加模塊化,重用代碼更容易,結構清晰易維護。

2、在移動端使用React

三大框架在移動端分別有本身的東西。Angular的ionic,React的React Native,Vue的Weex。其中ionic 是基於cordova技術,依然是瀏覽器應用。然後二者已上升到操做原生控件的層面,作出來的是原生界面,其中React Native的成熟度遠高於Weex,已經被不少公司使用,而Weex使用者不多。java

綜合來看選擇React 生態明顯最佳,由當前的cordova過渡爲cordova+Reactjs,而後能夠平滑地過渡到React Native,媲美原生性能的最優混合開發方式。之因此說平滑是由於React Native中近90%的代碼(JS)能夠在IOS和Android端使用,剩餘的涉及原生的代碼也基本能夠找到可用的資源,就像cordova 的插件同樣。畢竟若是須要同時掌握JS, OC(或swift),java(或kotlin)才能開發React Native的話,那這門技術不會有人用;固然反過來若是有原生開發知識的話會對開發React Native有必定幫助。node

直接轉型爲React native的話涉及了應用底層架構的變更,有比較大的跨度,而轉爲cordova+Reactjs相對容易,而由cordova+Reactjs到React Native一樣容易很多,由於其中大部分Reactjs代碼能夠重用。react

3、Reactjs開發工具的選擇

首先開發腳手架官方出了Create-react-app,集成了webpack-當前最流行的打包工具,babel-提升js版本兼容性的轉碼器,以及ESLint-代碼檢測工具和其它一些經常使用工具,同時對這些工具進行了比較優的配置。值得一提的是該腳手架將這些工具的配置文件進行了隱藏,本意是讓使用者專一於編碼便可,但實際使用時一般會有本身配置的需求,此時執行npm run eject便可出現被隱藏配置文件。webpack

React-router 是官方推薦的路由管理工具,因爲是單頁應用區別於原先的html界面間跳轉,跳轉實質是在組件間進行,因此須要有路由管理工具來統一化管理。這裏值得一提的是,React-router配合webpack能夠實現代碼的按需加載。css3

通常來講,webpack打包後會在生成一個壓縮的js文件,在單頁應用打開會總體加載這個文件,因爲該js文件包含以前全部的js代碼,雖然進行了壓縮,通常仍至少有幾百kb,當應用稍微複雜點,打包後文件會相應變大。而加載的時候,無論那些代碼有沒有執行到,都會下載下來並進行加載,形成性能浪費,這一點在顯然在web端很重要,而在cordova中是將js代碼直接打包在本地,等於跳過了下載步驟但仍然會有加載過程。經過在router中寫require.ensure代碼並在webpack中相應地修改配置便可將js分紅多個文件,在須要時加載對應的js文件,實現按需加載。git

Redux 是應用最普遍的第三方狀態管理工具,其做用是當應用中多數據狀態交互時,能夠更有方便且代碼結構清晰地統一管理狀態,下圖給出了形象的闡釋。因爲在實際開發中通常是分人員/分功能模塊獨立開發,考慮引入redux的成本(redux自己略複雜),能夠在沒有多數據交互的模塊不使用redux,而在相似涉及增刪改查的表單以及即時通信websocket等契合redux的模塊使用。github

爲項目選取合適UI組件庫,必定程度上簡化UI樣式的開發而且考慮使用其提供的過渡動畫效果。這方面有比較多的選擇,Google Material Design 風格的Material-UI在github上最受歡迎,但其設計語言與咱們當前APP大相徑庭,騰訊的weui和阿里的antd-mobile 較爲相近,其中antd-mobile與create-react-app腳手架配合使用時配置項比較繁雜,由於阿里本意是用來配合本身的腳手架dva(封裝了react-router和redux),所以暫時選擇weui,後期開發有特定組件需求可結合其餘ui庫使用。

至於頁面跳轉時的過渡動畫,有些UI庫給出了一些過渡樣式,好比touchstone。但該庫已再也不維護,文檔不佳,且與新版本的react-router配合使用有不兼容狀況。後來瀏覽官方文檔發現官方有動畫庫react-addons-css-transition-group,使用該庫結合css3的動畫三件套animation,transition,transform便可實現各類動畫效果包括基本的過渡效果,好比漸進平移等。

另外關於css,由於是單頁應用,因此若是不加處理,直接import css文件的話最終打包生成一個css文件會致使樣式應用到全局,形成同類名樣式相互污染影響。解決這個問題有不少種方案。Facebook積極探索css in js方式,但直接寫內聯樣式代碼可讀性太差。目前解決方案中應用最普遍的是css-modules,即在webpack配置中開啓module選項,使用styles對象來寫樣式。

解決的原理是將css類名在打包後編譯成哈希字符串,保持其惟一性。但當想要使用全局樣式時要再配置,稍顯繁雜,且它類名編寫的方式爲對象的方式,須要總體修改,另外在使用它時,發現不支持-橫線的類命名方式,支持下劃線方式,推薦駝峯式,而咱們以前html中的樣式類名大可能是橫線命名,這意味着原html和css中的類名都要對應修改,考慮到樣式類名很是多,這一方式捨棄。

另外有基於css-modules使用高階組件的react-css-modules使用人數也比較多,容許橫線命名方式且全局本地樣式區分簡單,但有benchmark測試代表其會較大程度拖累性能,因此也捨棄。解決這個問題要最大程度兼容原先css的寫法,即改動最小,由於以前的css類樣式數量龐大。

Webpack css-loader 有個屬性 :local 加上以後類會變成局部做用域,即webpack會對該類型的類進行自動哈希轉碼處理,但顯然類名一個個加:local 是有些呆板的工做,因而想到能夠利用scss的嵌套屬性將:local在一個css文件中統一加到類名前。這裏涉及到在腳手架create-react-app 添加對scss的支持,在命令行執行安裝,並在package.json的scripts中添加watch-css指令,將原css文件改成scss文件,而後在最外層添加:local,執行watch-css命令,便可在scss文件旁自動產生css文件,且類名前自動添加:local 前綴,這種方法實踐中發現並不是全部類的樣式都與:local 兼容良好,相應的可使用文件名代替:local,要作的就是保持文件名的惟一性,這一點原工程下的文件名已知足。這樣原先文件中引入css的方式,全局css引入的方式都不須要變化,作到最小代價。

scss 是 sass 3 引入新的語法,其語法徹底兼容 css3,而且繼承了 sass 的強大功能,sass和less是前端擴充css經常使用的方式,添加了嵌套,變量,繼承等語法,但須要編譯成css來最終使用(穩定性考慮)。

4、Reactjs 和cordova結合有哪些須要注意的

開發Reactjs使用官方提供的腳手架Create-react-app,最終經過npm run build生成一個單頁網頁應用,放入cordova的www目錄下便可。因爲這兩部分開發時獨立,而原先開發是在含www目錄的cordova工程目錄下直接開發,這種不一樣會產生一些問題。好比cordova中某些插件安裝後export函數或者變量供引入使用,由於一開始是分離的,在create-react-app中並找不到這些變量,就形成在build的時候產生變量undefined的錯誤,儘管最終放到cordova工程中後能夠找到變量並正常運行,但在第一步react開發時控制檯報一堆error會妨礙調試,影響開發體驗。

在github上有一些react cordova 庫,但實質上它們都須要經過npm run build來打包,因此並無解決引入插件變量的問題,且會與create-react-app 有相斥的地方。因此要想辦法使插件提供的變量在React中不報錯,這裏在不影響ESLint 檢錯機制的狀況下能夠採起迂迴的方式。Build時控制檯報錯僅針對src文件夾下的代碼,而在public文件夾下還有個index.html這個文件會最終被打包放到www目錄下,所以能夠在這個文件中deviceready時添加全局的插件變量(注意該類全局變量的惟一性,能夠添加plugin前綴或使用命名空間等方式保證),並將值傳給src目錄下的代碼中,這樣便可繞過控制檯build以及調試時的報錯。

另一個小技巧能夠將react工程直接放在cordova工程目錄下,指定最終build生成的文件放入www目錄下,省掉手動轉移文件的過程。

還有須要注意的一點是因爲React中默認配置的公共路徑是絕對路徑,當放在cordova中時須要使用file協議放本地,須要在webpack的production配置的public路徑前加".",或者在package.json 文件增長一行"homepage": "../www"或"homepage": "."改成相對路徑,不然會出現找不到文件的狀況,這裏推薦最後一種方式。

5、React項目的目錄結構

首先IDE選取webstorm,功能強大,以前項目組在用能夠沿用下來,但須要注意的一點是當目錄中包含了安裝的依賴node_modules時,因爲該文件夾下文件數量很是多,webstorm在智能創建代碼關聯時會佔用大量資源,在某些電腦上會偶爾會出現卡死現象,這一現象在我配置比較高(固態硬盤加8g運存)的電腦上一樣出現了,解決辦法是在file-setting-File types中配置ignore node_modules 文件夾。

上圖是create-react-app 項目的目錄,主要代碼放在src目錄下。Components中包含全部組件。React嚴格地執行組件技術,組件化不只方便重用,一樣能夠將一個頁面清晰地分割爲幾個部分最後放入一個父組件展現,由於jsx技術將js和html放在了一塊兒,分割後每一個部分有本身的功能邏輯與頁面展現,這樣更加清晰易維護。事實上react提出了一切皆組件的思想,只是有的組件render了部分界面,而有的沒有render。

上圖中components下有common文件用來放項目成員本身寫的公用組件好比公共請求方法等,external放外部引入的組件,work_log裏放的是我寫的工做日誌模塊的組件,各個功能模塊都各自建立一個文件夾,命名規則統一使用下劃線方式,這也是以前使用的方式。具體功能模塊的劃分與層級關係能夠參考以前的.

值得一提的,之前html的層級關係必須嚴格爲兩層(涉及到跳轉路徑的邏輯),致使最後出現沒有把一個功能模塊放到一個文件夾裏的狀況,好比上面的工做日誌以前所包含的各個文件直接和其它的一些功能模塊一塊兒放到了setting文件夾內。而如今只要在React-router統一配置好路由,實質上是往某個組件跳轉,不存在跳轉路徑的限制。

Constants文件夾下存放各類常量,好比各類接口路徑。Fonts存放字體圖標文件,images存放圖片,redux文件夾下是redux的幾個組成部分,styles下放scss/css樣式文件。Index.js是入口也是最頂層的父組件,router.js則維護了整個應用的路由關係。

上面就是本次調研的技術分析文檔,瀏覽大量技術文檔,開源社區以及技術論壇並結合實踐摸索得出的選型思路和理由,可能依然會有一些點沒有添加進去,之後會結合新知識和實踐繼續完善。

做者:梁鑫

來源:宜信技術學院

相關文章
相關標籤/搜索