寫在前面
離 Vue 2.0
釋出快有兩週了,最近兩天終於有空做了服務端渲染和同構的一些嘗試,並實現了一個對 Vue Server Renderer
的封裝,可以用更精簡的程式碼來實現在目前的 Node.js
應用中引入 Vue 服務端渲染。
Vue 的服務端渲染支援流式輸出,可以做元件級的快取,這使得它的渲染速度也是非常快速。通過搭配新版的 vue-router
和 vuex
( Vue 全家桶 大霧 ),可以實現一個既可以滿足SEO需求 ,也如SPA一樣互動體驗流暢的前後端同構應用。
vue-hackernews-2.0 是 Vue 2.0 的同構示例專案,使用 firebase 作為資料層,實現了完全實時的 hackernews 資訊流,同時還能被搜尋引擎當做靜態內容抓取。
vue-ssr
Use Vue 2.0 server-side rendering with Express
專案地址: vue-ssr
先上demo
還沒有做優化,只是基礎使用了 lru 做了元件的快取,伺服器平均渲染時間在 40ms 左右。
ssr.bood.in/
安裝
npm i vue-ssr --save複製程式碼
用法
const express = require(`express`)
const router = express.Router()
const vueRender = require(`vue-ssr`)
// webpack server-side bundle config
const serverConfig = require(`path to webpack.server.js`)
// create a project renderer
const indexRenderer = vueRender({
projectName: `index`,
rendererOptions: {
cache: require(`lru-cache`)({
max: 1000,
maxAge: 1000 * 60 * 15
})
},
webpackServer: serverConfig
})
// handler
// 這裡的靜態模板只做演示,可以檢視文末的例項例項程式碼
// 貌似在掘金 App 看著 < >全是字元編碼
function indexView (req, res) => {
indexRenderer(req, res, `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Cov-X</title>
{{ STYLE }}
</head>
<body>
{{ APP }}
<script src="/dist/client-bundle.js"></script>
</body>
</html>
`)
}
router.get(`/`, indexView)
router.get(`/home`, indexView)
router.get(`/article`, indexView)
router.get(`/tag`, indexView)複製程式碼
API
projectName
project name of webpack entries that you want to server side rendering
// webpack config
...
entry: {
index: [`../path to app client entry`],
dashboard: [`../path to dashboard project client entry`]
},
...複製程式碼
const indexRenderer = vueRender({
projectName: `index`,
webpackServer: serverConfig
})
const dashRenderer = vueRender({
projectName: `dashboard`,
webpackServer: serverConfig
})複製程式碼
rendererOptions
rendererOptions 即 Vue server renderer 的配置項
指令( directives )
宣告一些自定義指令的服務端實現:
const indexRenderer = vueRender(`index`, {
directives: {
example (vnode, directiveMeta) {
// transform vnode based on directive binding metadata
}
}
}, serverConfig)複製程式碼
快取( cache )
const indexRenderer = vueRender(`index`, {
cache: require(`lru-cache`)({
max: 1000,
maxAge: 1000 * 60 * 15
})
}, serverConfig)複製程式碼
更多資訊可以參考:Why Use bundleRenderer?
webpack 服務端打包配置( webpackServer )
將 webpack 服務端打包配置引入到 webpackServer 就完成了。
const serverConfig = require(`path to webpack.server.js`)
const indexRenderer = vueRender({
projectName: `index`,
webpackServer: serverConfig
})複製程式碼
示例程式碼
vue-ssr-hmr-template是一個使用了 vue-ssr 的專案腳手架,既可以使用前後端同構,也可以使用普通的spa模式(node 渲染靜態頁)。
- Vue 2.0
- Webpack 2.1.0
- HotModuleReplacement
- Server Side Render
- Express