vue搭建的spa项目有各种优点,易维护、代码简洁、开发体验好等。但是vue单页面却有一个很致命的问题就是seo优化的问题。谷歌引擎已经很好的支持但页面爬去数据,但是国内用户都是在用百度搜索引擎,而百度是不能对单页面应用进行数据采集的。
一、开发一个官网,页面不多,使用vue开发,本文讲述的是使用prerender-spa-plugin 和 vue-meta-info 达到seo优化的效果
问题
- 单页面应用无法被SEO,被搜索引擎收录页面少,较少产品曝光、访问
- 不能对不同页面设置title,keywords,description,不利于网络爬虫爬取
解决方案
- 使用Nuxt.js实现服务端预渲染(SSR)服务端渲染
- 使用prerender-spa-plugin插件实现 prerender-spa-plugin
原理
在webpack打包结束并生成文件后(after-emit hook),会启动一个server模拟网站的运行,用puppeteer(google官方的headless 无头浏览器)访问指定的页面route,发出请求拿回数据获得相应的html结构,并将结果输出到指定目录,过程类似于爬虫。
二、详述
- @vue/cli 4.5.11
- Vue2
- vue-meta-info ^0.1.7
- prerender-spa-plugin ^3.2.1
1、安装 prerender-spa-plugin
npm install prerender-spa-plugin --save
// 如果安装失败,请使用cnpm淘宝镜像
cnpm install prerender-spa-plugin --save
// main.js配置
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import MetaInfo from "vue-meta-info"
Vue.use(MetaInfo)
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App),
mounted: () => document.dispatchEvent(new Event('custom-render-event')),
}).$mount('#app')
2、安装vue-meta-info插件
// 安装vue-meta-info插件
npm install vue-meta-info --save
// main.js配置
import MetaInfo from "vue-meta-info"
Vue.use(MetaInfo)
// 页面中使用
export default {
metaInfo:{
meta:[
{ name:'keywords', content:'' },
{ name:'discription', content:'' }
]
},
data() {
return {}
}
}
3.vue.config.js配置
直接上代码,在项目中做了判断,只在生产环境打包成需要seo优化的,其他环境依旧是spa单页面。在修改配置时候注意路径的变换。
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? "/" : "./",
outputDir: process.env.NODE_ENV === 'production' ? "dist/" : "dist",
assetsDir: "static",
lintOnSave: false,
runtimeCompiler: false,
productionSourceMap: false,
devServer: {
open: true,
port: process.env.port,
proxy: null,
},
configureWebpack: config => {
if (process.env.NODE_ENV !== 'production') return
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const path = require('path');
return {
plugins: [
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'), // 读取vue-cli已打包文件的根目录 prerender-spa-plugin会在这里开启一个服务
outputDir: path.join(__dirname, '/dist/'), //经过prerender-spa-plugin处理的文件最终保存的地方
indexPath: path.join(__dirname, 'dist/index.html'), // 指定入口html
routes: ['/', '/home', '/about', '/salon', '/faculty', '/partner'], // 需要预渲染的路由,比如a有参数,就需要写成 /a/param1(带参数的没有试过,未验证)
minify: {
minifyCSS: true, // css压缩
removeComments: true // 移除注释
},
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
renderAfterTime: 10000,
renderAfterDocumentEvent: 'custom-render-event',
args: ['--no-sandbox', '--disable-setuid-sandbox']
})
})
]
}
}
}
4.router.js配置
在router.js中,要将路由模式修改为history模式
const router = new VueRouter({
mode: 'history',
base: process.env.NODE_ENV === 'development' ? '' : '/',
scrollBehavior: () => ({
y: 0
}),
routes
})
注意:
-
电脑必须安装google 浏览器,才可以打包成功
-
如遇到正式打包出错,请将谷歌浏览器关闭重新打开,或者重开一个终端