构建同构渲染

2021-03-28  本文已影响0人  翔子丶

接上篇使用 Vue SSR 渲染一个 Vue 实例

构建流程
image-20210325083058071.png image-20210325083156083.png

源代码 --> webpack 打包 --> Node Server 服务

此时,我们应用中只有 Server entry 服务端入口,只能处理服务端渲染,想要实现服务端渲染内容拥有动态交互能力,还需要 Client entry 客户端入口,用于处理客户端渲染,接管服务端渲染内容,激活成一个动态页面

Server entry 通过 webpack 最终打包成 Server Buner,主要用于做服务端渲染(SSR)

Client entry 通过 webpack 最终打包成 Client Buner,发送给浏览器,用于接管服务端渲染好的静态页面,对他进行激活成一个动态的客户端应用

源码结构

根据这幅图实现同构应用,既要实现服务端渲染,也要实现客户端渲染能够处理客户端动态交互

一个基本项目可能像是这样:

src
├── components
│   ├── Foo.vue
│   ├── Bar.vue
│   └── Baz.vue
├── App.vue
├── app.js # 通用 entry(universal entry)
├── entry-client.js # 仅运行于浏览器
└── entry-server.js # 仅运行于服务器
  1. 使用 webpack 的源码结构重新设置代码结构

    创建 src 目录,添加 App.vue 和 app.js、entry-client.js、entry-server.js,具体请查看 webpack 的源码结构

  2. 通过 webpack 打包构建,真正完成同构应用

    安装依赖

    npm i vue vue-server-renderer express cross-env
    

    安装开发依赖

    npm i -D webpack webpack-cli webpack-merge webpack-node-externals @babel/core @babel/plugin-transform-runtime @babel/preset-env babel-loader css-loader url-loader file-loader rimraf vue-loader vue-template-compiler friendly-errors-webpack-plugin
    

    配置文件及打包命令

    • 初始化 webpack 打包配置文件,具体见github

      build
      ├── webpack.base.config.js # 公共配置
      ├── webpack.client.config.js # 客户端打包配置文件
      └── webpack.server.config.js # 服务端打包配置文件
      
    • 在 npm scripts 中配置打包命令

      "scripts": {
      "build:client": "cross-env NODE_ENV=production webpack --config build/webpack.client.config.js",
      "build:server": "cross-env NODE_ENV=production webpack --config build/webpack.server.config.js",
      "build": "rimraf dist && npm run build:client && npm run build:server"
      },
      
启动服务
  1. 通过yarn build打包生成客户端和服务端文件

  2. 具体实现参考Bundle Renderer 指引

  3. 替换 server.js 中 createRender 为 createBundleRenderer,接收 serverBundle、template 和 clientManifest 为参数,启动服务

    ...
    const serverBundle = require('./dist/vue-ssr-server-bundle.json')
    const template = fs.readFileSync('./index.template.html', 'utf-8')
    const clientManifest = require('./dist/vue-ssr-client-manifest.json')
    
    renderer = require('vue-server-renderer').createBundleRenderer(serverBundle, {
        template,
        clientManifest,
    })
    ...
    

    此时在浏览器端获取不到 dist 下的 js 文件,是因为没有在服务器当中有 dist 中的资源传递给客户端,挂载中间件 server.use('/dist')

    image-20210326082507311.png
  1. 挂载处理静态资源中间件

    const express = require('express')
    // 得到express实例
    const server = express()
    // 挂载处理静态资源中间件
    //dist应该和客户端打包的出口的publicPath保持一致 使用express.static处理静态资源
    // 当请求到/dist开头的资源时,使用express.static尝试在./dist目录下查找并返回
    server.use('/dist', express.static('./dist'))
    

    此时重新刷新浏览器,js 文件正常加载,客户端交互功能正常

解析渲染流程

服务端渲染如何输出

客户端渲染如何接管并激活

上一篇 下一篇

猜你喜欢

热点阅读