Vue 预渲染 - 踩坑集合

背景

公司有个官网项目需要对网页做seo优化。至于为啥选择预渲染没用服务端渲染主要原因是:1、方便,对已有项目基础上做预渲染相对重新弄个nuxt项目更方便;2、项目中大部分都是静态资源,服务端渲染有点小题大做。出于以上考虑就最终选择了预渲染。

结果,开发过程中遇到挺多的坑。相关的资料也不多,现在好像很少有用预渲染了,所以在这里还是比较建议直接使用服务端渲染的方式,感觉其实也没有麻烦很多。

所以写一篇文章来记录一下过程和遇到的问题,以便其他想要用预渲染的小伙伴们参考一下。

简单说下我的项目情况:项目分为移动端和web端,项目独立。通过/m/路由区分。都要做预渲染。

prerender-spa-plugin 使用

prerender-spa-plugin 具体使用就不过多介绍了,很多文章都介绍的比较清楚。 直接上使用的代码,后面主要介绍其中的坑。

vue-router必须是History模式。

js 复制代码
// vue.config.js

const PrerenderSPAPlugin = require("@dreysolano/prerender-spa-plugin"); 
// 这里为啥是"@dreysolano/prerender-spa-plugin"而不是"prerender-spa-plugin"是因为我项目是webpack5,这个库已经没更新了不支持。
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
......
new PrerenderSPAPlugin({  
    staticDir: path.join(__dirname, "dist"),  
    routes: ["/", "/home"],  
    server: {
        // 这里是因为我的页面中有些数据是接口请求回来的,所以这里加上代理。
        proxy: {  
            "/fcc": {  
                target: "https://www.fcc.com",  
                secure: false,  
            },
    },    
    renderer: new Renderer({  
        inject: {  
            foo: "bar",  
        },  
        headless: true,  
        renderAfterTime: 12000,  
        maxConcurrentRoutes: 12,  
    }),  
}),
js 复制代码
// main.js
import { createApp, onMounted } from "vue";

app.mount("#app");
onMounted(() => {  
    document.dispatchEvent(new Event("custom-render-trigger"));  
});

查看是否成功直接打包看下目录结构是否有 /home/index.html,并且这个.html的内容中,#app内是有东西的就表示成功。或者打包后运行一下,页面右击查看源代码也能看出是不是预渲染成功了。

遇到的坑

1、webpack5 使用 prerender-spa-plugin 时打包报错

打包时遇到报错:

js 复制代码
# [prerender-spa-plugin] Unable to prerender all routes!

解决方案:使用 @dreysolano/prerender-spa-plugin 而不是原版的prerender-spa-plugin

参考:[prerender-spa-plugin]无法预渲染所有路线!将 webpack 升级到 v5+ 时 ·问题 #414

2、线上环境发布时,jenkins日志报错无法启动Chrome

js 复制代码
 # Error : Failed to Launch chrome!

这是因为linux环境中没有安装Chrome。需要运维帮忙安装一下就好。

安装方法:linux安装谷歌浏览器(Chrome)

安装完之后记得启动检查一下是否缺少必要的库。

js 复制代码
cd node_modules/puppeteer/.local-chromium/[linux-579032]/[chrome-linux]
ldd chrome | grep not

如果有缺少百度安装一下就好

参考文章: 参考文章1 参考文章2 参考文章3

3、刷新路由或者通过url跳转路由后面会多个/

发布成功之后,页面内通过点击实现的路由跳转是正常的,但是刷新路由或者通过url跳转会自动加上斜杆后缀。查看控制台静态资源可以看到正常的路由/home会重定向到/home/。这种情况会影响搜索引擎爬取,不利于seo

解决方案:修改ng配置,在第二个 $uri/ 前面加上 $uri/index.html

js 复制代码
location / {
  try_files $uri $uri/index.html $uri/ /index.html;
}

参考文章:Vue Router history 模式 Nginx 配置目录文件刷新不自动添加斜杆 - 柯灰小栈 (kohai.top)

4、移动端和web端使用同一个域名的时候,会有指向问题或者页面为空的情况

先简单看下ng配置

js 复制代码
location / {
    alias /usr/nginx/fcc/;
    try_files $uri $uri/index.html $uri/ /index.html last;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
}
// 注意是/m/而不是/m,如果写/m那么如果web端中有/m开头的路由也会走到这。
location /m/ {
    alias /usr/nginx/m_fcc/;
    try_files $uri $uri/index.html $uri/ /index.html last;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
}

移动端前端项目:

js 复制代码
// router/index.ts

const router = createRouter({  
    history: createWebHistory("/m"),// 通过这种方式添加 base router
});
js 复制代码
// vue.config.js

publicPath: "/", // 预渲染环境必须使用绝对路径
assetsDir: "m/", // 打包的静态资源需要在/m目录下,否则页面访问移动端的时候,静态资源会去找web项目的路径下。添加了之后打包出来的.html文件中,可以看到静态资源的路径前面会以/m开头。

//同web一样正常配置route
new PrerenderSPAPlugin({  
    staticDir: path.join(__dirname, "dist"),  
    routes: ["/", "/home"],  
    server: {
        // 这里是因为我的页面中有些数据是接口请求回来的,所以这里加上代理。
        proxy: {  
            "/fcc": {  
                target: "https://www.fcc.com",  
                secure: false,  
            },
    },    
    renderer: new Renderer({  
        inject: {  
            foo: "bar",  
        },  
        headless: true,  
        renderAfterTime: 12000,  
        maxConcurrentRoutes: 12,  
    }),  
}),

配置后打包出来的目录结果是

markdown 复制代码
 dist
     - m
         - js
         - css
         - img
         - home
             index.html
     favicon.png
     index.html
相关推荐
DT——3 小时前
Vite项目中eslint的简单配置
前端·javascript·代码规范
学习ing小白5 小时前
JavaWeb - 5 - 前端工程化
前端·elementui·vue
一只小阿乐5 小时前
前端web端项目运行的时候没有ip访问地址
vue.js·vue·vue3·web端
计算机学姐5 小时前
基于python+django+vue的旅游网站系统
开发语言·vue.js·python·mysql·django·旅游·web3.py
真的很上进5 小时前
【Git必看系列】—— Git巨好用的神器之git stash篇
java·前端·javascript·数据结构·git·react.js
胖虎哥er5 小时前
Html&Css 基础总结(基础好了才是最能打的)三
前端·css·html
qq_278063716 小时前
css scrollbar-width: none 隐藏默认滚动条
开发语言·前端·javascript
.ccl6 小时前
web开发 之 HTML、CSS、JavaScript、以及JavaScript的高级框架Vue(学习版2)
前端·javascript·vue.js
小徐不会写代码6 小时前
vue 实现tab菜单切换
前端·javascript·vue.js
2301_765347546 小时前
Vue3 Day7-全局组件、指令以及pinia
前端·javascript·vue.js