一 對同構的大體理解
將瀏覽器的dom載入和資料載入分開執行。
複製程式碼
二 為什麼要同構
- 便於web應用的SEO
- 提升使用者體驗(渲染快嘛
- 前後端一些程式碼統一(後面的通過redux實現前後資料互通可略微代表一哈)
三 怎麼同構
客戶端
最終效果是使用者看到我們的web應用和訪問其他web應用一樣,開啟瀏覽器輸入網址 回車出現web應用首頁的樣子。那沒什麼難的 搭個react專案 EZ是吧 (太多腳手架 網上demo 好壞都有 照葫蘆畫瓢都能搭出來是吧)
基本用到的技術棧: react react-router 4.x react-redux redux webpack4.x
客戶端結構
簡單解釋下
actions
存放actioncreator的目錄componets
存放用到的自己編寫的元件類config
存放webpack的dev和prod的配置 且含一個用於本地跑webpack-devserver的服務檔案 具體配置就不貼了dist
webpack打包生成的目錄reducers
存放處理各種action的reducerstore
建立store目錄app.js
專案入口 reactDOM.render那個地方routes.js
專案路由
伺服器端
坑1:關於express
路由和react-router
統一的問題
網上大多數demo的例子是比較老的所以用到的是老版本的react-router
的方式做的
用到了match方法 但是對於4.0以後的版本不適用 所以看了下官方api 是用了staticRouter
來代替原來的 browser/hash
按照官方的demo改了下 就跑通了
renderToString
是同構的核心。其實很簡單,列印下html就是字串是吧。然後伺服器呼叫res.write
返回給瀏覽器就完成了同構的第一步。
坑2:忽略伺服器渲染導致元件生命週期未走全的問題
回到客戶端想給一個元件繫結事件及獲取繫結ref
的節點獲取不到
查了下是由於 伺服器渲染只會走render前的生命週期 那麼當我們的節點還未掛在到dom上 給他繫結事件和獲取都肯定是不行的。這就說通了是吧
那麼按我的理解是還需要在rendertostring
的模板html(可通過設定其他模板改為ejs都行 不衝突)裡 新增我們通過webpack
打包生成的bundle.js(webpack
用到SplitChunks
的話生成的其他類似ventor的檔案塊也要引入)
因為什麼呢? 我的理解是使用者開啟瀏覽器後載入bundle.js然後 去將伺服器渲染時候未走過的生命週期 走一遍 。(未繫結成功的事件和獲取節點就變得可行了)
然後就是通過配置線上和測試環境(忘說了伺服器這邊用到的是express nodemon mongodb
)
以上的內容僅是2天的嘗試搭建後的心得體悟 對於剛接觸同構的兄弟們具有一些提示作用。其實想要伺服器渲染完全可以用下next.js
我自己也是在2天的搭建後 嘗試了用下next.js
進行同構 感覺實在太方便了 而且用pm2進行伺服器的部署及Nginx
配置都有詳細的文章可參考。感興趣的可以嘗試下。