vue/vue2.0/ssr

98 阅读2分钟

如何构建vue的ssr

参考资料

  1. vue的ssr渲染指南

从0到1构建ssr

原理

image.png

笔记

  1. 服务端渲染vue的时候要避免状态单例,对于http网站请求,应该暴露一个可以重复执行的工厂函数,为每个请求创建新的应用程序实例:同理vue-router、vue-store、event-bus
  2. 由webpack构建的项目,从一个入口分成三个入口,分别是entry-client.js仅运行于浏览器,是entry-server.js仅运行于服务端,app.js两端都通用配置。
  3. 客户端的vue能够通过div上的这个特殊属性data-server-rendered从而激活组件,而不是重新渲染组件。

项目地址

github地址

// 先编译
npm i
npm run build
// 后启动服务器运行
npm run dev

遇到的问题

1.打包后,静态资源访问不到。

原因:1个是静态资源服务器没有开通,
另外一个是vue-ssr-client-manifest.json文件publicPath默认为auto。
解决:需要在express里面添加static静态资源的引用。
const express = require('express');
const app = express();
app.use('/auto',express.static(path.resolve(__dirname,'../dist/')));

2.打包后,客户端的vue没有激活。

原因:服务端渲染的元素没有属性id
解决:在app.vue里面添加id即可。
<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

3.打包后,服务器为node环境,是否能像csr一样丢个dist文件包不用考虑服务器环境就行了呢?

结论:不行,因为你的sso资源是动态的,动态的渲染是在node环境上执行的。
当然你可以使用不同语言的环境,但是需要对应的sdk支持。
也就是说前端还需要懂一些服务端的基本知识。
解决:不同的服务环境,执行不同的sdk支持。

4.ssr渲染中,node环境下使用了浏览器的api

原因:有三个配置文件,你将css资源配置在了
webpack.base.config.js或者webpack.server.config.js里面了。
解决:将资源配置在webpack.client.config.js
//webpack.client.config.js
module.exports = merge(baseConfig, {
...
  module: {
  ...
    rules: [
      {
          test: /\.css$/i,
          use: ['style-loader', 'css-loader'],
      },
    ],
   ...
  },
... 

5.ssr渲染中,webpack5引用不了extract-text-webpack-plugin,对于css资源提取报错。

解决:改用mini-css-extract-plugin
//webpack.client.config.js,注意只能在此文件进行提取,否则会注入到node环境,导致node使用了浏览器的api报错。
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = merge(baseConfig, {
...
  module: {
  ...
    rules: [
      {
          test: /\.css$/i,
          use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
    ],
   ...
  },
  plugins: [
  ...
    new MiniCssExtractPlugin({
      filename: '[name].css'
   }),
  ...  
  ]
...  
})
//webpack.server.config.js
module.exports = merge(baseConfig, {
...
  module: {
  ...
    rules: [
      {
        test: /\.css$/i,
        use: [
          'vue-style-loader',
          'css-loader'
        ],
      },
    ],
   ...
  },
...  
})