3 分鐘搞定 Vue 2.0 服務端渲染

Awe發表於2019-03-03

寫在前面

Vue 2.0 釋出快有兩週了,最近兩天終於有空做了服務端渲染和同構的一些嘗試,並實現了一個對 Vue Server Renderer 的封裝,可以用更精簡的程式碼來實現在目前的 Node.js 應用中引入 Vue 服務端渲染。

Vue 的服務端渲染支援流式輸出,可以做元件級的快取,這使得它的渲染速度也是非常快速。通過搭配新版的 vue-routervuex( 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.server.js

將 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

相關文章