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