解析vue-ssr構(gòu)建流程

來(lái)先看一眼官方構(gòu)建圖:

1、app.js / main.js入口文件
app.js是我們的通用entry,它的作用就是構(gòu)建一個(gè)Vue的實(shí)例以供服務(wù)端和客戶端使用,注意一下,在純客戶端的程序中我們的app.js將會(huì)掛載實(shí)例到dom中,而在ssr中這一部分的功能放到了Client entry中去做了。
2、兩部分入口entry.js
我們來(lái)看Client entry和Server entry,這兩者分別是客戶端的入口和服務(wù)端的入口。Client entry的功能很簡(jiǎn)單,就是掛載我們的Vue實(shí)例到指定的dom元素上;Server entry是一個(gè)使用export導(dǎo)出的函數(shù)。主要負(fù)責(zé)調(diào)用組件內(nèi)定義的獲取數(shù)據(jù)的方法,獲取到SSR渲染所需數(shù)據(jù),并存儲(chǔ)到上下文環(huán)境中。這個(gè)函數(shù)會(huì)在每一次的渲染中重復(fù)的調(diào)用。
3、webpack打包構(gòu)建
我們的服務(wù)端代碼和客戶端代碼通過(guò)webpack分別打包,生成Server Bundle和Client Bundle,前者會(huì)運(yùn)行在服務(wù)器上通過(guò)node生成預(yù)渲染的HTML字符串,發(fā)送到我們的客戶端以便完成初始化渲染;而客戶端bundle就自由了,初始化渲染完全不依賴(lài)它了??蛻舳四玫椒?wù)端返回的HTML字符串后,會(huì)去“激活”這些靜態(tài)HTML,使其變成由Vue動(dòng)態(tài)管理的DOM,以便響應(yīng)后續(xù)數(shù)據(jù)的變化。
4、解析運(yùn)行流程
這里我們?cè)撜務(wù)剆sr的程序是怎么跑起來(lái)的了。首先我們得去構(gòu)建一個(gè)vue的實(shí)例,也就是我們前面構(gòu)建流程中說(shuō)到的app.js做的事情,但是這里不同于傳統(tǒng)的客戶端渲染的程序,我們需要用一個(gè)工廠函數(shù)去封裝它,以便每一個(gè)用戶的請(qǐng)求都能夠返回一個(gè)新的實(shí)例,也就是官網(wǎng)說(shuō)到的避免交叉污染了。
然后我們可以暫時(shí)移步到服務(wù)端的entry中了,這里要做的就是拿到當(dāng)前路由匹配的組件,調(diào)用組件里定義的一個(gè)方法(官網(wǎng)取名叫asyncData)拿到初始化渲染的數(shù)據(jù),而這個(gè)方法要做的也很簡(jiǎn)單,就是去調(diào)用我們vuex store中的方法去異步獲取數(shù)據(jù)。
接下來(lái)node服務(wù)器如期啟動(dòng)了,跑的是我們剛寫(xiě)好的服務(wù)端entry里的函數(shù)。在這里還要做的就是將我們剛剛構(gòu)建好的Vue實(shí)例渲染成HTML字符串,然后將拿到的數(shù)據(jù)混入我們的HTML字符串中,最后發(fā)送到我們客戶端。
打開(kāi)瀏覽器的network,我們看到了初始化渲染的HTML,并且是我們想要初始化的結(jié)構(gòu),且完全不依賴(lài)于客戶端的js文件了。再仔細(xì)研究研究,里面有初始化的dom結(jié)構(gòu),有css,還有一個(gè)script標(biāo)簽。script標(biāo)簽里把我們?cè)诜?wù)端entry拿到的數(shù)據(jù)掛載了window上。原來(lái)只是一個(gè)純靜態(tài)的HTML頁(yè)面啊,沒(méi)有任何的交互邏輯,所以啊,現(xiàn)在知道為啥子需要服務(wù)端跑一個(gè)vue客戶端再跑一個(gè)vue了,服務(wù)端的vue只是混入了個(gè)數(shù)據(jù)渲染了個(gè)靜態(tài)頁(yè)面,客戶端的vue才是去實(shí)現(xiàn)交互的!
SSR服務(wù)端渲染注意點(diǎn)
在SSR中,創(chuàng)建Vue實(shí)例、創(chuàng)建store和創(chuàng)建router都是套了一層工廠函數(shù)的,目的就是避免數(shù)據(jù)的交叉污染。
注意點(diǎn)一
在服務(wù)端只能執(zhí)行生命周期中的created和beforeCreate,原因是在服務(wù)端是無(wú)法操縱dom的,所以可想而知其他的周期也就是不能執(zhí)行的了。
注意點(diǎn)二
服務(wù)端渲染和客戶端渲染不同,需要?jiǎng)?chuàng)建兩個(gè)entry分別跑在服務(wù)端和客戶端,并且需要webpack對(duì)其分別打包;
注意點(diǎn)三
SSR服務(wù)端請(qǐng)求不帶cookie,需要手動(dòng)拿到瀏覽器的cookie傳給服務(wù)端的請(qǐng)求。
