从零开始搭建一个vue-ssr(下)

栏目: JavaScript · 发布时间: 7年前

内容简介:上次我们已经实现了从零开始,搭建一个简单的vue-ssr的demo:与上一次不同,这次我们基于vue-cli进行改建,已经有了很多依赖库了,但我们任需要补充一个核心:修改webpack.dev.conf.js文件,添加插件

从零开始搭建一个vue-ssr

前言

上次我们已经实现了从零开始,搭建一个简单的vue-ssr的demo: 从零开始搭建一个vue-ssr(上) 。那么这次呢,我们基于vue-cli,进行webpack的改造,实现vue-cli版本的vue-ssr。

开始改建

补充安装依赖

与上一次不同,这次我们基于vue-cli进行改建,已经有了很多依赖库了,但我们任需要补充一个核心:

npm install vue-server-renderer

修改客户端的webpack配置

修改webpack.dev.conf.js文件,添加插件

const vueSSRClientPlugin = require("vue-server-renderer/client-plugin");

const devWebpackConfig = merge(baseWebpackConfig,{
    plugins:[
        new vueSSRClientPlugin()
    ] 
});

添加了这个配置以后,重新启动项目通过地址就可以访问到vue-ssr-client-manifest.json( http://localhost :8082/vue-ssr-client-manifest.json),页面中出现的内容就是所需要的client-bundle。

修改vue的相关文件

此步骤跟 从零开始搭建一个vue-ssr(上) 大有相似,不重复描述,直接上代码:

修改 router/index.js

import vueRouter from "vue-router";
import Vue from "vue";
import HelloWorld from "@/components/HelloWorld";
import About from "@/components/About";

Vue.use(vueRouter);
export default () => {
  return new vueRouter({
    mode:"history",
    routes:[
      {
        path:"/",
        component:HelloWorld,
        name:"HelloWorld"
      },
      {
        path:"/about",
        component:About,
        name:"About"
      }
    ]
  })
}

修改app.js

import Vue from "vue";
import createRouter from "./router";
import App from "./App.vue";

export default (context) => {
  const router = createRouter();
  const app = new Vue({
    router,
    components: { App },
    template: '<App/>'
  });
  return {
    app,
    router
  }
}

修改entry-server.js

import createApp from "./app.js";

export default (context) => {
    return new Promise((reslove,reject) => {
        let {url} = context;
        let {app,router} = createApp(context);
        router.push(url);
        router.onReady(() => {
            let matchedComponents = router.getMatchedComponents();
            if(!matchedComponents.length){
                return reject();
            }
            reslove(app);
        },reject)
    })
}

修改entry-client.js

import createApp from "./app.js";
let {app,router} = createApp();

router.onReady(() => {
    app.$mount("#app");
});

修改webpack客户端入口以及输出

修改webpack.base.conf.js

module.exports = {
    entry:{
        app:"./src/entry-client.js"
    },
    output:{
        publicPath:"http://localhost:8080/"
    }
};

创建服务端webpakc配置文件

创建build/webpack.server.conf.js文件,目的将插件vue-server-renderer/server-plugin引入server端执行。

const webpack = require("webpack");
const merge = require("webpack-merge");
const base = require("./webpack.base.conf");
//  手动安装
//  在服务端渲染中,所需要的文件都是使用require引入,不需要把node_modules文件打包
const webapckNodeExternals = require("webpack-node-externals");


const vueSSRServerPlugin = require("vue-server-renderer/server-plugin");

module.exports = merge(base,{
    //  告知webpack,需要在node端运行
    target:"node",
    entry:"./src/entry-server.js",
    devtool:"source-map",
    output:{
        filename:'server-buldle.js',
        libraryTarget: "commonjs2"
    },
    externals:[
        webapckNodeExternals()
    ],
    plugins:[
        new webpack.DefinePlugin({
            'process.env.NODE_ENV':'"development"',
            'process.ent.VUE_ENV': '"server"'
        }),
        new vueSSRServerPlugin()
    ]
});

创建build/dev-server.js,拿到客户端和服务端的bundle文件以及读取到index.html中的模板用作渲染。

const serverConf = require("./webpack.server.conf");
const webpack = require("webpack");
const fs = require("fs");
const path = require("path");
//  读取内存中的.json文件
//  这个模块需要手动安装
const Mfs = require("memory-fs");
const axios = require("axios");

module.exports = (cb) => {
    const webpackComplier = webpack(serverConf);
    var mfs = new Mfs();
    
    webpackComplier.outputFileSystem = mfs;
    
    webpackComplier.watch({},async (error,stats) => {
        if(error) return console.log(error);
        stats = stats.toJson();
        stats.errors.forEach(error => console.log(error));
        stats.warnings.forEach(warning => console.log(warning));
        //  获取server bundle的json文件
        let serverBundlePath = path.join(serverConf.output.path,'vue-ssr-server-bundle.json');
        let serverBundle = JSON.parse(mfs.readFileSync(serverBundlePath,"utf-8"));
        //  获取client bundle的json文件
        let clientBundle = await axios.get("http://localhost:8082/vue-ssr-client-manifest.json");
        //  获取模板
        let template = fs.readFileSync(path.join(__dirname,"..","index.html"),"utf-8");
        cb && cb(serverBundle,clientBundle,template);
    })
};

在根目录下创建server.js文件,用于启动服务,并利用createBundleRenderer将两个Bundle和html模板渲染出来。

const devServer = require("./build/dev-server.js");
const express = require("express");
const app = express();
const vueRender = require("vue-server-renderer");

app.get('*',(request,respones) => {
    respones.status(200);
    respones.setHeader("Content-Type","text/html;charset-utf-8;");
    devServer((serverBundle,clientBundle,template) => {
        let render = vueRender.createBundleRenderer(serverBundle,{
            template,
            clientManifest:clientBundle.data,
            //  每次创建一个独立的上下文
            renInNewContext:false
        }); 
        render.renderToString({
            url:request.url
        }).then((html) => {
            respones.end(html);
        }).catch(error => {
          respones.end(JSON.stringify(error));
        });
    });
})

app.listen(5001,() => {
    console.log("服务已开启")
});

补充一个html模板

根目录下创建index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vue_cli_ssr</title>
  </head>
  <body>
    <div id="app">
      <!--vue-ssr-outlet-->
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>

最后在package.json中添加一个启动服务端的命令:

"server": "node server.js"

大功告成,开启两个终端,分别输入

npm run dev
npm run server

浏览器打开localhost:8082,我们便可以看到由vue-cli改造而成的vue-ssr。

总结

本文是直接基于vue-cli进行改造的一个ssr版本,若想从零开始手撕vue-ssr,可以看上一篇文章 从零开始搭建一个vue-ssr(上)

项目源码

https://github.com/TheWalking...


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Build Your Own Web Site the Right Way Using HTML & CSS

Build Your Own Web Site the Right Way Using HTML & CSS

Ian Lloyd / SitePoint / 2006-05-02 / USD 29.95

Build Your Own Website The Right Way Using HTML & CSS teaches web development from scratch, without assuming any previous knowledge of HTML, CSS or web development techniques. This book introduces you......一起来看看 《Build Your Own Web Site the Right Way Using HTML & CSS》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

SHA 加密
SHA 加密

SHA 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具