4、如何做到前端路由和後端路由同步;
說到前後端路由同步,有個問題就又拋出來了,什麼是前後端路由同步?爲什麼要前後端路由同步?
讓我們看看react-router
中的hashhistory
和browserHistory
;
hashHistory:
http://noah.dabanma.com/#/index
browserHistory:
http://noah.dabanma.com/index
這裏我們選擇browserHistory來做前端路由;這樣更容易跟後端路由匹配;
好了,言歸正傳,那麼什麼是前後端路由同步,爲什麼要前後端路由同步?我總結下來就是:
意思是讓前後端路由保持一致或存在某一對應關係,訪問一個地址之後,前端路由和後端路由能夠相對應上,保證渲染的組件一致,保證數據一致。
詳細的說一下:
這就是打開一個網頁的路由流程圖。
前後端路由的匹配方法react-router
已經給出,match
方法。
import React from 'react';
import { match, RouterContext } from 'react-router';
function clientRouter(ctx, next) {
let _renderProps;
match({routes:Root(), location:ctx.url}, (err, redirectLocation, renderProps) => {
_renderProps = renderProps
})
if(_renderProps) {
ctx.render = (props, router) => {
return stringToHtml(<Provider store={props}><RouterContext {..._renderProps} /></Provider>, props, router);
}
}
next();
}
這是一箇中間件,每次對後端的請求都會走這個中間件,那麼每次都會走match
方法來匹配路由,渲染相應的組件。
5、如何拆分js和css,並且在切換頁面的時候加載相對應的js和css;
我用webpack
拆分了js和css,將公用的js代碼打包到vendor.js
中,然後以頁面爲單位拆分相應的js文件和css文件,根據頁面的路由命名。
這樣做的目的是減輕首屏加載的負擔,頁面只需要加載自己的js和css就可以。切換頁面的時候,再根據路由請求相應的js和css文件即可。
這裏拋出個問題,如何在切換頁面的時候,異步請求響應的js和css文件?
我的思路是:
- 首先用
webpack
的pluginassets-webpack-plugin
是可以生成一個json文件的,這個json文件中包含打包的情況:
{
"index": {
"js": "/js/index-d4727d0c.js",
"css": "/css/index.css"
},
"test": {
"js": "/js/test-d4727d0c.js"
},
"vendor": {
"js": "/js/vendor-d4727d0c.js"
}
···
}
- 既然webpack生成了這個json文件,那麼在後端我們可以用fs模塊讀取這個json內容,就可以在後端路由中找到對應的js和css文件,添加到字符串模板中,讓瀏覽器去渲染;
這裏有個點可以優化,每次切換頁面的時候,我們不一定非得去請求後端,請求後端只是爲了SEO,那麼不需要做SEO的頁面我們可以不請求後端,只要加載對應頁面的js和css就好,然後用瀏覽器去解析js文件中的react代碼,做到存前端渲染。這樣提升了速度。
這樣的優化,又拋出兩個問題:
1.前面介紹過,數據是從後端通過字符串模板傳給前端的,那麼純前端渲染就拿不到數據;
2.js和css也是通過後端路由匹配,獲取到相應的js和css,通過字符串模板傳給前端的,純前端渲染也是拿不到對應頁面的js和css文件的;
問題1的解決方案是在react生命週期componentDidMount
中發起與在後端路由中同樣的請求,這樣由前端發起請求得到數據。
問題2的解決方案是將webpack生成的json也寫入字符串模板中,可在前端獲取。
6、如何做到服務端渲染和前端渲染隨意切換
服務端渲染和前端渲染的切換,歸根結底在路由上的切換;
前端渲染跳轉的方式:
import {Link, browserHistory} from 'react-router';
browserHistory.push('/index')
或者
<Link to='/index' >跳轉</Link>
後端渲染跳轉方式:
location.href = '/index';
7、做到服務端渲染和前端渲染可隨意切換後,如何保證服務端和前端數據保持同步;
這個問題在上面的優化中提到過,若想做到前後端渲染隨意切換,那麼服務端和前端必須都具有各自獨立獲取數據的能力,並且兩端數據要求統一。
我的思路是:
- 既然前後端的請求是一樣的,數據會一致,數據接口也相同,那麼將首屏渲染的請求提取出來是一個可行的辦法;
- 根據webpack生成的json數據,查找組件和後端路由的對應關係,可將組件的請求同步到後端路由中;
- 這樣,就可以實現跳轉頁面的時候,前後端渲染隨意切換;
到這裏將react服務端渲染基本介紹完了,當然還有很多細節沒有寫進來,如果有更好的方案和意見建議,請在評論區留言。