1. 程式人生 > >自己動手搭建react-ssr伺服器端渲染專案架構

自己動手搭建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
版權說明:歡迎轉載,但必須註明出處,並在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利