概述
最近研究了一下服務端渲染,有一些心得,記錄下來供以后開發時參考,相信對其他人也有用。
參考資料:
服務端渲染介紹
服務端渲染簡單來說,就是分別對項目用webpack打包2次,一次生成vue-ssr-server-bundle.json,一次生成vue-ssr-client-manifest.json和其它靜態文件,最后用node搭一個服務器接收這2個json文件進行組裝,並發送給用戶。其中有以下幾點需要注意:
1.工廠函數
我們需要對vue, vue-router, vuex用一個工廠函數包裹起來,進行延遲執行。原因是node server每次會接受很多http請求,而vue卻只有一個示例,如果在打包前把實例先初始化的話,以后的每次請求就會發送同一個實例,造成交叉請求狀態污染 (cross-request state pollution)。示例如下:
// app.js
const Vue = require('vue')
module.exports = function createApp (context) {
return new Vue({
data: {
url: context.url
},
template: `<div>訪問的 URL 是: {{ url }}</div>`
})
}
2.服務端渲染的生命周期
在所有vue的生命周期鈎子函數中,beforeCreate 和 created 會在服務端渲染的時候被調用,其它生命周期會在客戶端執行。
所以我們在 beforeCreate 和 created 這2個生命周期內不能訪問this,也不能訪問window,更不能訪問組件實例等。一般我們在 beforeCreate 和 created 中會做的事情有:發送http請求事先填充store,鑒權,發送http請求初始化組件data等。我們在客戶端進行初始化的http請求都需要移動到 mounted 或者 beforeMount 生命周期中。
3.axios
我們發送http請求的庫推薦使用axios。又因為axios不僅會用在客戶端發送http請求,還會用在服務端發送http請求,所以在給axios設置攔截器的時候需要小心使用和window或者dom相關的方法。
4.HTML結構
因為vue的服務端渲染主要是由vue-server-renderer庫完成的,它在解析html標簽的時候會有一些坑,就是html結構需要很嚴格的書寫,至少要做到以下2點:
- 不要漏寫結束標簽。
- p標簽里面不能使用塊級標簽,如果非要使用的話,需要把p標簽換成div標簽。
5.緩存
我們一般給node server使用 micro-caching 緩存策略:讓 node server 把動態內容儲存1秒,也就是說無論這一秒有多少請求,node server 只會生成一次動態內容。這個是通過LRU庫來實現的。另外還有組件級別的緩存,這里就不多說了。
nuxt.js
1.yarn
雖然nuxt項目可以用npm運行,但是仍然推薦使用yarn來運行此項目,步驟如下:
先檢查電腦中是否有homebrew:
$ brew -v
如果有homebrew的話跳過此步,沒有的話使用以下命令安裝:
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
最后使用homebrew安裝yarn:
$ brew install yarn
這里是npm和yarn的對照:
npm install===yarnnpm run dev===yarn run devnpm init===yarn initnpm install <package>===yarn add <package>npm uninstall <package>===yarn remove <package>npm update <package>===yarn upgrade <package>
2.指令
# 安裝所有依賴包
$ yarn
# 安裝某個依賴包
$ yarn add <package>
# 打開開發環境
$ yarn dev
# 正式環境
$ yarn build
$ yarn start
# 開發環境下重啟服務(很重要)
$ 輸入rs 再按回車鍵
# 自動修復eslint錯誤
$ yarn lint
# 生成可視化依賴圖(相當於vue-cli3的vue inspect指令)
$ yarn analyze
3.在開發的時候需要注意如下幾點:
- eslint在一些方面比其它項目更加嚴格,按報錯提示修改就可以了。(這些方面我沒有改成和其它項目一樣是因為我覺得這些習慣很好)
- 靜態資源放在static文件夾里面,svg雪碧圖放在
assets/sprite/文件夾里面。 - 文件夾名字不能改。(nuxt.js本身要求)
- 其它比如pages文件夾里面每個文件就是一個路由,可以看nuxt.js官方文檔。
