15分钟学会vue项目改造成SSR
Ps:网上看了好多服务器渲染的例子,基本都是从0开始的,用Nuxt或者vue官网推荐的ssr方案(vue-server-renderer),但是我们在开发过程中基本上是已经有了现有的项目了,我们所要做的是对现有项目的SSR改造。那么这里,跟我一起对一个vue-cil2.0生成的项目进行SSR改造
关于这篇文章的案例源代码我放在我的github上面,有兴趣的同学,也可以去我的github查看我之前写的博客。博客
一、改造技术的分析对比。
一般来说,我们做seo有两种方式:
1、预渲染
我在性能优化的博客中说过,预渲染的问题,预渲染是一个方案,使用爬虫技术。由于我们打包过后的都是一些js文件,使用一些技术(puppeteer)可以爬取到项目在chrome浏览器展示的页面,然后把它写入js,和打包文件一起。
类似prerender-spa-plugin 。最大的特点就是,所有获取的数据都是静态的,比如说你的页面首页有新闻,是通过接口获取的,当你在2019-11-30打包之后,不管用户在2020年也是看到的2019-11-30的新闻,当然的爬虫爬到的也是。
如果你只需要改善少数页面(例如 /, /about, /contact 等)的 SEO,那么你可能需要预渲染
2、服务端渲染
服务端渲染是将完整的 html 输出到客户端,又被认为是‘同构'或‘通用',如果你的项目有大量的detail页面,相互特别频繁,建议选择服务端渲染。
**服务端渲染除了SEO还有很多时候用作首屏优化,加快首屏速度,提高用户体验。**但是对服务器有要求,网络传输数据量大,占用部分服务器运算资源。
由于三大框架的兴起,SPA项目到处都是,所以涌现了一批nuxt.js、next.js这些服务器渲染的框架。但是这些框架构建出来的项目可能文件夹和我们现有的项目很大不一样,所以本文章主要是用vue-server-renderer来对现有项目进行改造,而不是去用框架。
ps:(划重点)单页面项目的ssr改造的原理:
vue项目是通过虚拟 DOM来挂载到html的,所以对spa项目,爬虫才会只看到初始结构。虚拟 DOM,最终要通过一定的方法将其转换为真实 DOM。虚拟 DOM 也就是 JS 对象,整个服务端的渲染流程就是通过虚拟 DOM 的编译成完整的html来完成的。
我们通过服务端渲染解析虚拟 DOM成html之后,你会发现页面的事件,都没法触发。那是因为服务端渲染vue-server-renderer插件并没有做这方面的处理,所以我们需要客户端再渲染一遍,简称同构。所以Vue服务端渲染其实是渲染了两遍。下面给出一个官方的图:
二、改造前后目录文件对比
黄线部分是改造后新增的文件,怎么样,是不是觉得差别不大,总体架构上只有6个文件的差别。(#.#) 我们来理一理这些新增的文件。
server.dev.conf.js 本地调试和热更新需要的配置文件
webpack.client.conf.js 客户端打包配置文件,ssr打包是生成分为客户端和服务端的两部分打包文件
webpack.server.conf.js 服务端打包配置文件,ssr打包是生成分为客户端和服务端的两部分打包文件
entry-client.js 客户端入口文件。spa的入口是main.js,ssr就分为两个入口(服务端和客户端)
entry-server.js 服务端入口文件。spa的入口是main.js,ssr就分为两个入口(服务端和客户端)
index.template.html 模板文件,因为服务端渲染是通过服务器把页面丢出来,所以我们需要一个模板,作为页面初始载体,然后往里面添加内容。
server.js 启动文件,服务端渲染我们需要启动一个node服务器,主要配置在这个文件里面。
三、webpack添加客户端与服务端配置
1.webpack客户端配置
const webpack = require('webpack') const merge = require('webpack-merge') const baseConfig = require('./webpack.base.conf.js') const HtmlWebpackPlugin = require('html-webpack-plugin') const path = require('path') const VueSSRClientPlugin = require('vue-server-renderer/client-plugin') module.exports = merge(baseConfig, { entry: './src/entry-client.js', plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: "manifest", minChunks: Infinity }), // 此插件在输出目录中 // 生成 `vue-ssr-client-manifest.json`。 new VueSSRClientPlugin(), new HtmlWebpackPlugin({ template: path.resolve(__dirname, './../src/index.template.html'), filename: 'index.template.html' }) ] })
这里面和spa项目有两点不同,第一是入口变了,变为了entry-client.js。第二是VueSSRClientPlugin,这个是生成一个vue-ssr-client-manifest.json客户端入口文件。
2.webpack服务端配置