本身動手搭建react-ssr服務器端渲染項目架構

最近折騰了下React的ssr項目的搭建,以前折騰過一次沒有太多的進展。此次從新開始搭建react的項目架構。項目源碼:https://github.com/rt-zhangxuefei/react-ssr-templatecss

特別感謝:慕課網的Delllee的課程。這裏我使用了saga代替thunk,中間也遇到了一些坑,中間層代理使用了http-proxy-middleware。文章記錄我搭建過程當中遇到的一些問題:html

 

 

ssr的過程前端

1)訪問首屏時(任何url首次經過瀏覽器打開),請求到達node服務端node

2)node服務根據訪問的url匹配路由表(routte目錄下的index.js)react

3)匹配到的路由裏面調用組件的loadData(本身定義的,用來獲取數據),有須要獲取數據的組件才添加一個loadData方法,這裏匹配的路由多是多個,因此會有多個loadData的方法,並且這些方法都是異步的(sagas)。ios

4)待全部異步操做完成,調用renderToString方法渲染出html字符串git

5)express服務發送html字符串給瀏覽器(包含數據)和已經渲染好的dom字符串github

6)瀏覽器獲取到html字符串解析展現網頁內容(ttfp)ajax

7)瀏覽器根據script標籤裏面的src地址請求服務器,下載包含react客戶端js文件express

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 版權說明:歡迎轉載,但必須註明出處,並在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。
相關文章
相關標籤/搜索