vue-manage-system升级到vue3的开发总结

本文探讨了Vue.js应用从CSR转向SSR的原因,包括SEO优化和更快的内容到达时间。详细介绍了SSR的构建流程,如webpack服务端bundle的打包、SSR的实现步骤、开发环境的热更新、路由同构以及数据预取。同时,文章指出SSR的缺点,如增加开发成本和服务器负载,并提出预渲染作为折衷方案。最后,作者分享了在Vue3中实施SSR的具体实践和遇到的问题解决方案。
摘要由CSDN通过智能技术生成
什么是 CSR & SSR ?

CSR(Client Side Rendering)就是在浏览器从服务器中获取到的只是一个带有空 div 标签的 html 文件,然后执行 js 文件生成 dom 和操作 dom,日常中开发的后台管理类的系统大多都是 CSR 的模式。

SSR(Server Side Rendering)是在服务端已经完成渲染工作,浏览器从服务器获得的是完整的网页的 dom 字符串。不同于以前通过后端模板等方案生成页面,现在的 React、Vue、Svelte 等优秀框架都有 SSR 的解决方案。

为什么要使用 SSR?

关于这个问题尤大在 Vue SSR 指南中也给出了答案。

SSR 对比 CSR 的优点:

  • 更好的 SEO:对 SSR 的应用搜索引擎可以直接获取完全渲染的页面,但是在 CSR 的应用中搜索引擎获取到的只是一个空标签。
  • 更快的内容到达时间。

当然 SSR 对比 CSR 也有一些缺点:

  • 引用成本高:SSR 还需要使用 Node.js 作为服务器,对于代码构建和部署也要求更高,加大了开发成本
  • 更多的服务器负载。
  • 传统开发思路受限:在开发的时候要区分是 Node.js 环境还是浏览器环境,部分生命周期在服务器端也不会生效。

所以在选择技术栈的时候可以根据项目需求去选择,如果对 SEO 和加载速度有要求的时候就可以使用 SSR。反之如果没有 SEO 或首屏加载优化等需求,使用 SSR 也可能是一种负担。

more:

如果单纯的想对个别数据变动不频繁的页面做 SEO,可以考虑预渲染的方案,毕竟 SSR 的成本是相对较高的。

  • 预渲染:预渲染就是把页面生成静态的 html 结构,然后进行静态部署。实现方案一般是通过一个无头浏览器打开系统,等到 js 执行完毕,dom 渲染完毕后通过XMLSerializer API 进行处理最后生成静态 html 字符串。
SSR 构建流程

下图来自 Vue 官网,详细展示了 SSR 项目的构建流程,虽然 React 和 Vue 的实现方式略有不同,但是整体思路也是如此:

  • Store、Router、Components、app.js 这些模块(以下简称web模块)是公共的,在 SSR 的情况下这些模块既要在客户端使用,也要在服务端使用。
  • web 模块被 Cliententry 引用通过 webpack 打包作为静态资源使用。
  • web 模块被 Serverentry 引用通过 webpack 打包被 Node.js 服务 调用,用于请求页面的时候,进行组件渲染返回 html 字符串。
  • 最终 Node.js Server 返回的 html 字符串和 js 加载生成的 html 在浏览器端进行同构。

由上图也可以初步新建如下的文件目录:

.
├── build
│ ├── base.config.js
│ ├── client.config.js
│ └── server.config.js
├── entry
│ ├── server-entry.jsx
│ └── client-entry.jsx
├── server
│ └── app.js
└── web├── components│ └── Test.jsx├── index.jsx└── pages└── Index.jsx 
  • build:webpack 构建的目录
  • entry:入口文件的目录
  • server:Node.js 服务器的目录
  • web:前端代码和资源目录
webpack 构建服务端 bundle

webpack 构建主要是把 web 目录下的文件分别通过 client 和 server 的配置打包成两份代码,这里不再介绍客户端代码的打包,主要介绍一下服务端代码的打包。

const WebpackChain = require('webpack-chain');
const nodeExternals = require('webpack-node-externals');
const {resolvePath,isDev
} = require('./utils');
module.exports = {getServerConfig: function() {const chain = new WebpackChain();chain.entry('server').add(resolvePath('entry/server-entry.js')).end().output.path(resolvePath('dist/server')).filename('[name].js').libraryTarget('commonjs2').end().when(isDev, function(chain) {chain.watch(true);}).target('node').externals(nodeExternals({allowlist: [/.(css|less|sass|scss)$/]}));return chain.toConfig();}
} 

可以看到,服务器端打包和客户端的打包有一点区别:

  • target: ‘node’,target 设置为 node,webpack 将在类 Node.js 环境编译代码。(使用 Node.js 的 require 加载 chunk,而不加载任何内置模块,如 fspath)。每个target都包含各种 deployment(部署)/environment(环境)特定的附加项,以满足其需求。
  • output 的 libraryTarget 设置为 ‘commonjs2’ 打包输出的代码将在 Node.js 环境下运行。
  • 使用 nodeExternals 后,代码将不会被 webpack 打包,因为服务端的代码自带 node_modules,可以直接去 node_modules 中获取。
React 服务端渲染 API

在开始编写代码之前,我们需要了解react实现服务端渲染必须的几个 API,参考 ReactDOMServer

  • renderToString 把 React 元素渲染 html 字符串。
function Comp () {return (	<div>123</div>)
}
renderToString(<Comp />); // 返回 <div>123</div> 
  • renderToNodeStream 把 React 元素渲染成 html,和 renderToString 不同的是,该方法返回一个可输出 HTML 字符串的可读流
  • hydrate 如果您调用ReactDOM.hydrate()已经具有此服务器渲染标记的节点,React 将保留它并仅附加事件处理程序,从而使您获得非常出色的首次加载体验。在 SSR 应用中使用hydrate替代rend
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值