V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
A2we

在 Express 应用中接入 Vue 2.0 服务端渲染

  •  2
     
  •   A2we ·
    hilongjw · Oct 15, 2016 · 3273 views
    This topic created in 3493 days ago, the information mentioned may be changed or developed.

    写在前面

    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 左右。 http://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
    // 这里的静态模板只做演示,可以查看文末的实例实例代码
    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
    No Comments Yet
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2983 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 14:53 · PVG 22:53 · LAX 07:53 · JFK 10:53
    ♥ Do have faith in what you're doing.