摘要:之前做的一個應(yīng)用,最近把首頁改成了服務(wù)端渲染的形式,過程還是很周折的,踩到了不少坑,記錄一些重點,希望有所幫助前端使用的技術(shù)棧升級到升級到服務(wù)項目地址喜歡的給個,感謝。。。。。。。
之前react做的一個應(yīng)用,最近把首頁改成了服務(wù)端渲染的形式,過程還是很周折的,踩到了不少坑,記錄一些重點,希望有所幫助前端使用的技術(shù)棧
react、react-dom 升級到 v16
react-router-dom v4
redux red-sage
antd-mobile 升級到 v2
ssr服務(wù) express
項目地址,喜歡的給個star,感謝。。。。。。。
訪問地址(手機模式) 非服務(wù)端渲染 服務(wù)端渲染 效果對比 前后處理流程對比 react下ssr的實現(xiàn)方式React下同構(gòu)的解決方案有next.js、react-server等,這里,因為這個項目之前已經(jīng)采用create-react-app、redux做完了,只是想在現(xiàn)有系統(tǒng)基礎(chǔ)上把首頁改成服務(wù)端直出的方式,就選擇了webpack-isomorphic-tools這個模塊
webpack-isomorphic-tools介紹如果我們想在現(xiàn)有React系統(tǒng)中引入同構(gòu),首先要解決的一個重要問題是:代碼中我們import了圖片,svg,css等非js資源,在客戶端webpack的各種loader幫我們處理了這些資源,在node環(huán)境中單純的依靠babel-regisiter是不行的,執(zhí)行renderToString(
而webpack-isomorphic-tools就幫助我們處理了這些非js資源,在客戶端webpack構(gòu)建過程中,webpack-isomorphic-tools作為一個插件,生成了一份json文件,形如:
有了這份映射文件,在同構(gòu)的服務(wù)端,renderToString(
比如我們有一個組件:
const App =()=>{ return ),就生成正確的 ) //得到填滿數(shù)據(jù)的標(biāo)簽
拼接html
注意,上面說的webpack-isomorphic-tools中生成的json文件中有js,css的對應(yīng)關(guān)系,這里我訪問那個json文件得到j(luò)s、css的路徑,拼到html中
還要返回store中保存的狀態(tài),供客戶端js createStore使用
在客戶端js中
const sagaMiddleware = createSagaMiddleware() const store = createStore( reducer, window.__INITIAL_STATE__, applyMiddleware(sagaMiddleware) ) sagaMiddleware.run(rootSaga)路由
在做同構(gòu)的時候不能用BrowserRouter,要使用無狀態(tài)的StaticRouter,并結(jié)合location和context兩個屬性
有這樣的路由結(jié)構(gòu)
//默認(rèn)跳到/home,其他的該到哪到哪}>
server端的代碼要這樣
const context = {} const html = renderToString() // 中訪問/,重定向到/home路由時 if (context.url) { res.redirect("/home") return }
StaticRouter可以根據(jù)request來的url來指定渲染哪個組件,context.url指定重定向到的那個路由
也就是說,要是訪問 /,StaticRouter會給我們重定向到/home,并且StaticRouter自動給context對象加了url,context.url就是重定向的/home,當(dāng)不是重定向時,context.url是undefined
我們還可以自己寫邏輯 通過context來處理302、404等。但這里我不需要。。。。。,為什么呢?
我沒做全棧的同構(gòu),只服務(wù)端渲染了主頁,渲染一個和多個差不多,全都渲染的話就是在服務(wù)端要根據(jù)當(dāng)前請求的路由來決定要發(fā)那些請求來填充Store
我對路由的處理流程上面的思維導(dǎo)圖有說明,就是在nginx中多配一個代理。
對于訪問/、/home這兩個路由,代理到ssr服務(wù),來吐首頁內(nèi)容,api代理到后端服務(wù),其他的直接返回(也就是說如果在detail頁面或user頁面刷新了頁面還是之前客戶端渲染那套)
對登錄操作的處理上面說server端初始化數(shù)據(jù)的時候還有一個登陸問題沒說。
用戶初始訪問了服務(wù)端渲染的首頁,然后在客戶端轉(zhuǎn)到登錄頁面登陸了,重新回到首頁刷新了頁面,喔,又去請求了ssr服務(wù),但服務(wù)端不知道當(dāng)前用戶登錄了啊,還是原來的流程,返回的__INITIAL_STATE__中還是沒有用戶的個人信息和已登錄狀態(tài)
所以,在客戶端登陸后,要將用戶的token存到cookie中,這樣,在首頁就算用戶刷新了頁面,重新請求頁面請求中也會帶上cookie,在服務(wù)端,根據(jù)request.cookies中是否有token來決定發(fā)哪些請求填充store
if (auth) { //要是有token就去查用戶信息和是否登錄狀態(tài)(還查是否登錄是因為token有可能是被篡改過的) promises = [ getMoviesList(store, auth), getCategory(store), checkLogin(store, auth), getUinfo(store, auth) ] } else { promises = [ getMoviesList(store), getCategory(store), ] } Promise.all(promises).then(x=>{ renderToString(避免客戶端js中初始請求的觸發(fā)) })
到這一步,訪問域名,就能夠正確展示服務(wù)端渲染的頁面,跳到別的路由,客戶端的js也能正常處理接下來的事,但是,服務(wù)端渲染頁面展示后,首頁那幾個ajax請求還是觸發(fā)了,這是沒必要的。
原以為這是react renderToString()生成的標(biāo)簽和客戶端js hydrate()的有差異導(dǎo)致的,然而,實際上,js執(zhí)行了,組件的生命周期該觸發(fā)還是會觸發(fā)的,不只是 attach event listeners to the existing markup
所以要手動避免
在App組件中 componentDidMount() { if (!window.__INITIAL_STATE__) { this.props.checkLogin() this.props.loadCategory() } } //當(dāng)當(dāng)前頁面是服務(wù)端返回的(因為window.__INITIAL_STATE__有初始狀態(tài)),初始的ajax就不觸發(fā)了總結(jié)
服務(wù)端渲染的坑還是挺多的,這一個星期就搞它了。。。。這里記錄一些比較重要的東西,具體細(xì)節(jié)有興趣的可以看下代碼.最后,最重要的,喜歡的給個star,感謝。。。。。。。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/92464.html
摘要:所以,這次就來聊聊組件的服務(wù)器端渲染。這種模式下,后端只提供接口,傳統(tǒng)的服務(wù)器端路由模板渲染則都有層接管。這樣,前端開發(fā)人員可以自由的決定哪些組件需要在服務(wù)器端渲染,哪些組件可以放在客戶端渲染,前后端完全解耦,但又保留了服務(wù)器端渲染的功能。 細(xì)說 Vue 組件的服務(wù)器端渲染 聲明:需要讀者對 NodeJs、Vue 服務(wù)器端渲染有一定的了解 現(xiàn)在,前后端分離與客戶端渲染已經(jīng)成為前端開發(fā)的...
摘要:前言本文主要是有關(guān)前端方面知識按照目前的認(rèn)知進(jìn)行的收集歸類概括和整理,涵蓋前端理論與前端實踐兩方面。 前言:本文主要是有關(guān)前端方面知識按照 XX 目前的認(rèn)知進(jìn)行的收集、歸類、概括和整理,涵蓋『前端理論』與『前端實踐』兩方面。本文會告訴你前端需要了解的知識大致有什么,看上去有很多,但具體你要學(xué)什么,還是要 follow your heart & follow your BOSS。 初衷...
摘要:前言本文主要是有關(guān)前端方面知識按照目前的認(rèn)知進(jìn)行的收集歸類概括和整理,涵蓋前端理論與前端實踐兩方面。 前言:本文主要是有關(guān)前端方面知識按照 XX 目前的認(rèn)知進(jìn)行的收集、歸類、概括和整理,涵蓋『前端理論』與『前端實踐』兩方面。本文會告訴你前端需要了解的知識大致有什么,看上去有很多,但具體你要學(xué)什么,還是要 follow your heart & follow your BOSS。 初衷...
摘要:前言本文主要是有關(guān)前端方面知識按照目前的認(rèn)知進(jìn)行的收集歸類概括和整理,涵蓋前端理論與前端實踐兩方面。 前言:本文主要是有關(guān)前端方面知識按照 XX 目前的認(rèn)知進(jìn)行的收集、歸類、概括和整理,涵蓋『前端理論』與『前端實踐』兩方面。本文會告訴你前端需要了解的知識大致有什么,看上去有很多,但具體你要學(xué)什么,還是要 follow your heart & follow your BOSS。 初衷...
摘要:服務(wù)端任需要進(jìn)行校驗來達(dá)到數(shù)據(jù)的可靠性前端的路由可能在服務(wù)端并不存在等等這一系列重用性的問題。串行并行,大幅縮短請求時間。關(guān)于作者本人主頁本文部分圖片段落參考文章淘寶前后端分離實踐微信公眾號會不定期推送前端技術(shù)文章,歡迎關(guān)注 一、背景 書接上文,淺談前后端分離與實踐(一) 我們用mock服務(wù)器搭建起來了自己的前端數(shù)據(jù)模擬服務(wù),前后端開發(fā)過程中只需定義好接口規(guī)范,便可以相互進(jìn)行各自的開發(fā)...
閱讀 1134·2021-11-22 15:33
閱讀 3441·2021-11-08 13:20
閱讀 1481·2021-09-22 10:55
閱讀 2114·2019-08-29 11:08
閱讀 844·2019-08-26 12:24
閱讀 3145·2019-08-23 17:15
閱讀 2302·2019-08-23 16:12
閱讀 2012·2019-08-23 16:09