javascript

vue基于vue实现SSR渲染

2019-03-29  本文已影响0人  ysp123

与传统的spa渲染,服务器端渲染可以有更好的seo,更快的内容到达时间(time to content)。但是服务器端渲染并不是必须的,是否使用,需要细细斟酌。本文是一个完整的服务器渲染的实现,结合一个例子实现。同时假如是仅仅几个静态页面,完全可以使用预渲染实现,没必要完全使用服务器实时动态编译html。

在学习以下内容时请先观看下官方的文档
基本用法:(vue-server-renderer)注意一下几点
1、推荐使用 Node.js 版本 6+。
2、vue-server-renderer 和 vue 必须匹配版本。
3、vue-server-renderer 依赖一些 Node.js 原生模块,因此只能在 Node.js 中使用。我们可能会提供一个更简单的构建,可以在将来在其他「JavaScript 运行时(runtime)」运行
基本环境为 vue2.X+koa2,vue2.X和koa2的环境请自行搭建

npm install  vue-server-render --save
const Koa = require('koa');
const Vue = require('vue');

const renderer= require('vue-server-renderer').createRenderer({
        template: require('fs').readFileSync('./temp.html', 'utf-8')
});

const server= new Koa();
server.use(async ctx=>{
          const app = new Vue({
                    data:{
                                msg:'hello  vue+node ssr'
                            },
                    template:'<h4>{{msg}}</h4>'
          });
          renderer.renderToString(app, (err, html)=>{
                  if(err){
                            ctx.status = 500;
                    }
                    ctx.body = html;
          })
});
server.listen(5000, ()=>{
        console.log('server is start.........');
})

渲染模板(temp.html)

<!DOCTYPE html>
<html lang="en">
    <head>
      <title>title</title>
    </head>
  <body>
    <!--vue-ssr-outlet-->
  </body>
</html>

以上我们就实现了一个简单的ssr渲染。但是以上内容还不能应用于生产环境,我们以下进一步深入。
避免状态单列:我们为用户每次请求创建vue实例,如果我们在多个请求之间使用一个共享的实例,很容易导致交叉请求状态污染(cross-request state pollution)。
因此,我们不应该直接创建一个应用程序实例,而是应该暴露一个可以重复执行的工厂函数,为每个请求创建新的应用程序实例:

//app.js
import Vue from 'vue';
import App from './app.vue';
export function createApp(){
        const app = new Vue({
                render:h=>h(App)
          });
      return app;
}

//app.vue
<template>
    <div>
        <div class="demo">
            <h1>Simple-webpack demo</h1>
            <p>这是一个简单的  Vue demo</p>
        </div>
    </div>
</template>

创建client入口文件和server入口文件,并创建对应的webpack文件

//entry-client.js
import  { createApp } from  './app.js';
const app = createApp();
app.$mount("#app");

//entry-server.js
import { createApp }  from './app.js';
const app = createApp();
return app;

webpack配置:

//webpack.client.js
............
const  VueSSRClientPluguin  = require('vue-server-renderer/client-plugin');
..............
plugins:[
        new VueSSRClientPluguin()
]

//webpack.server.js
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin');
...............
      entry:{
            main:'./entry-server.js'
      },
     output:{
          filename:'server-bundle.js',
          libraryTarget:'commonjs2'
      },
............
      plugins:[
           new  VueSSRServerPlugin ()
      ]

执行 webpack.client.js 和 webpack.server.js 文件,会生成 vue-ssr-server-bundle.json 和 vue-ssr-client-manifest.json 两个文件。服务端使用这两个文件解析文件。

const  Koa = require('koa');
const Server = new Koa();

const { createBundleRenderer } = require('vue-server-renderer');

const path = require('path');
const fs = require('fs');
const template = fs.readFileSync(path.resolve(__dirname, '/temp.html'), 'UTF-8');

const serverBundle = require('./dist/vue-ssr-server-bundle.json');
const clientMainfest = require('./dist/vue-ssr-client-manifest.json');

const renderer = createBundleRenderer(serverBundle,{
    basedir: path.resolve(__dirname, './dist'),
    runInNewContext: false,
    template,
    clientMainfest
 });

const renderToString = function(context){
        return new Promise((resolve, reject) => {
                renderer.renderToString(context, (err, html)=>{
                      if(err){
                              reject(err);
                            }
                    resolve(html);
                });
        });
}

Server.use(async ctx =>{
           let html = '';
           try{
                html  = await renderToString({});
          }catch(err){
                ctx.throw(500, err)
          }
          ctx.body = html;
});

Server.listen(5000, ()=>{
            console.log('server is start.........');
});

这样就完成了vue+node的ssr渲染。

附上demo的git地址:https://github.com/yspwf/ssr-vue-node-

上一篇 下一篇

猜你喜欢

热点阅读