预渲染的原理:在webpack打包结束并生成文件后(after-emit hook),启动一个server模拟网站的运行,用puppeteer(google官方的headless chrome浏览器)访问指定的页面route,得到相应的html结构,并将结果输出到指定目录,过程类似于爬虫。

这里直接记录尝试过程中的坑:

webpack.prod.conf.js中配置插件:

上面的预渲染路由配置要注意/ 和/home是同一个路径,就会出现预渲染两次,因此应该去掉一个。

 

这部分经测试可以去掉。

prerender-spa-plugin插件安装的时候已经安装puppeteer,所以不用重复安装。

npm run build完成以后,根目录会出现

配置了路由的页面会出现文件夹,文件夹内是index.html。

配合metainfo插件

注意申明组件ComponentOptions属性,因为原生没有metainfo对象。

预渲染事件触发配置:

main.ts中

 

在实现过程中遇到了很多坑

0.路由模式必须是history,nginx服务器上需要配置

也就是不带#号的路由。

1.根目录index.html中如果设置了SEO,标题描述内容三元素,在预渲染后不会替换根页面的属性,也就是会出现两次这样的属性。

如果页面中存在2个meta信息,第一个有效,第二是无效的。但是如果删除掉index.html中设置的meta,就会出现预渲染以外的页面,没有title和meta信息,也不合理。
解决方案: 增加一个模板入口文件index2.html,那么会有两个模板文件index.html和index2.html,预编译indexPath指定使用index2.html,在index2.html中不设置meta和title。正常渲染使用index.html,在index.html中正常设置meta和title。
这样预渲染的页面就会有1个meta,预渲染以外的页面也可以正常有meta。
同样这个也需要nginx设置,主页面请求index2.html,其他页面请求index.html.

2.生成的静态页面,只有a标签,才能跳进预渲染页面,router-link或者$router.push跳转会被js代理渲染

当然也有解决方案,在nginx中配置:

3.puppeteer在docker环境部署环境缺少,需要另外安装环境库。

centos:

unbantu:

我基于第一个安装上传了具备puppeteer运行环境的基础node镜像


ok,线上部署是可以完成了,我遇到了新的问题。

4.第三方插件无法在index.html中加载出来,CDS资源无法加载

原因:

以百度商桥的插件为例,加载时间超时或者非常的久,久到页面无法刷出,预渲染的页面,会等到所有js加载完以后才能刷新出来

而SPA模型页面不会受影响。

百度商桥这个客服系统竟然是个轮询,一个轮询要20s,这样我们预渲染首页就得等20S的js加载时间,目前解决方案首页不预渲染-  -。

而百度商桥插件作为一个js方法单独引入首页组件内,在生命周期中创建和销毁。

在uitl文件夹下创建BaiduBridge.js

在home组件中引入百度商桥

 

5.打包完后会报 vue项目报错webpackJsonp is not defined

解决方案就是修改webpack打包js的顺序

找到build→webpack.prod.conf.js→找到HtmlWebpackPlugin插件,添加如下配置即可

6.忘记说了,调转路由必须是80端口,除非nginx里面配置调转- -。不配置的情况下,假如页面是通过8080端口打开的,那调转到预渲染页面会默认变成80端口的,也可以说成是端口丢失了吧。

ps:有时候看起来简单易实现的东西,坑却更多。

实际效果参考官网:火石创造罗基官网