V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
A2we
V2EX  ›  前端开发

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

  •  2
     
  •   A2we ·
    hilongjw · 2016-10-15 00:10:24 +08:00 · 2537 次点击
    这是一个创建于 2993 天前的主题,其中的信息可能已经有所发展或是发生改变。

    写在前面

    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
    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1380 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 17:19 · PVG 01:19 · LAX 09:19 · JFK 12:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.