自己動手搭建react-ssr伺服器端渲染專案架構
最近折騰了下React的ssr專案的搭建,之前折騰過一次沒有太多的進展。這次重新開始搭建react的專案架構。專案原始碼:https://github.com/rt-zhangxuefei/react-ssr-template
特別感謝:慕課網的Delllee的課程。這裡我使用了saga代替thunk,中間也遇到了一些坑,中間層代理使用了http-proxy-middleware。文章記錄我搭建過程中遇到的一些問題:
ssr的過程
1)訪問首屏時(任何url首次通過瀏覽器開啟),請求到達node服務端
2)node服務根據訪問的url匹配路由表(routte目錄下的index.js)
3)匹配到的路由裡面呼叫元件的loadData(自己定義的,用來獲取資料),有需要獲取資料的元件才新增一個loadData方法,這裡匹配的路由可能是多個,所以會有多個loadData的方法,而且這些方法都是非同步的(sagas)。
4)待所有非同步操作完成,呼叫renderToString方法渲染出html字串
5)express服務傳送html字串給瀏覽器(包含資料)和已經渲染好的dom字串
6)瀏覽器獲取到html字串解析展示網頁內容(ttfp)
7)瀏覽器根據script標籤裡面的src地址請求伺服器,下載包含react客戶端js檔案
8)解析js,react執行,接管了整個頁面的互動控制以及渲染
9)結束
專案結構如圖
專案簡介
自己模擬了幾個介面(登入,判斷登入,獲取文章列表,評論列表),登入以後才能檢視評論
支援less,css module
什麼是注水和脫水
伺服器端通過路由匹配出的元件的loadData方法(sagas)填充store,通過html字串裡面注入script標籤引入變數的方式把store傳給了瀏覽器,這個就是脫水。瀏覽器載入了包含reactjs的程式碼以後,把伺服器注入過來的js物件的資料作為預設state傳入createStore方法完成脫水過程。
伺服器端渲染時react-router使用StaticRouter無狀態路由
這裡有個很重要的屬性context,如下:
這個context引數會貫穿到瀏覽器和伺服器端,成為一個數據互動的橋樑。比如判斷前端路由重定向,404跳轉等都是通過context作為判斷來實現的。
css渲染
在具有樣式的元件需要通過生命週期鉤子注入css,讓伺服器端獲取到並且渲染出來,這裡就是一個應用(context作為資料橋樑)
元件的loadData(方法名稱自己定義)
sagas就是store目錄下的sagas
node作為中間層
所有的ajax請求都是通過node作為中間層來轉發,這裡使用了
http-proxy-middleware來實現,凡是url裡面帶有api的都進行轉發。這樣就會導致另外一個問題出來,那就是這個轉發是針對瀏覽器的ajax請求。伺服器端也會發同樣的請求給後臺api介面,差別只是url地址帶沒帶host。axios物件的createInstance方法
伺服器端使用的axios例項和瀏覽器端使用的axios例項不一樣,作為引數傳遞給sagas,這裡需要注意傳參的方式:
伺服器端使用:
客戶端使用:
之所以能夠這樣做是因為watch sagas都是在瀏覽器端呼叫的(比如通過生命週期鉤子,或者點選事件等),而loadData是伺服器端呼叫獲取資料用來填充store的。
造輪子?
雖然有了next.js,但有時自己造輪子有時是需要的。當然next.js是非常受歡迎的,值得用來開發實際的專案
結尾
再次感謝DellLee老師的課程。花了2周的時間,完成了一個react-ssr專案架構,專案裡面還有2個未解決的問題,一個是css在伺服器和客戶端都渲染了一次,另外一個就是code splitting或按需載入的問題。希望在後續的學習過程中能夠解決遺留的問題。如果你解決,請留言告訴我!
作者:張雪飛
出處:https://zhangxuefei.site/p/2166
版權說明:歡迎轉載,但必須註明出處,並在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利