前端笔记 - Vue SPA SEO方案 - 使用预渲染插件prerender-spa-plugin

前言

SPA、SEO、SSR 介绍

已经有大佬总结的够详细,够简单易懂了。参考阅读:https://www.jianshu.com/p/fcb98533bc18?tdsourcetag=s_pctim_aiomsg

预渲染插件使用

版本要求
"vue": "^2.6.10",
"prerender-spa-plugin": "^3.4.0",
"@vue/cli-service": "^3.8.0",
安装
 cnpm install prerender-spa-plugin --save
配置文件更改

vue.config.js

const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const path = require('path');

module.exports = {
  // 生产环境是否生成 sourceMap 文件
  productionSourceMap: false,
  // 基础路径
  // 比如部署在https://www.my-app.com/my-app/,则设置 publicPath 为 /my-app/
  publicPath: '/',
  // 输出文件目录
  outputDir: 'dist',
  // 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录
  assetsDir: 'static',
  // 是否使用包含运行时编译器的 Vue 构建版本
  runtimeCompiler: false,
  // 是否为 Babel 或 TypeScript 使用 thread-loader。
  // 该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产
  // 构建,在适当的时候开启几个子进程去并发的执行压缩
  parallel: require('os').cpus().length > 1,
  
  // 以上是打包基本配置,根据项目需求更改
  configureWebpack: config => {
  	if (process.env.NODE_ENV !== 'production') return;
  	return {
  		plugins: [
  			new PrerenderSPAPlugin({
  				// 生成文件的路径,也可以与webpakc打包的一致。
  				staticDir: path.join(__dirname,'dist'),
  				// 对应自己的路由文件。
  				routes: ['/','/app','/open','/about','/contact'],
  				renderer: new Renderer({
  					inject: {
  						foo: 'bar'
  					},
  					headless: false,
  					// 对应 main.js 中 
					// document.dispatchEvent(new Event('render-event')),
					// 两者的事件名称要对应上。
  					renderAfterDocumentEvent: 'render-event'
  				})
  			}),
  		],
  	};
  }
  
}

更多 Vue CLI 参考 https://cli.vuejs.org/zh/guide/

调整 webpack 配置最简单的方式就是在 vue.config.js 中的 configureWebpack 选项提供一个对象。参考 https://cli.vuejs.org/zh/guide/webpack.html#简单的配置方式

项目入口文件配置

main.js

new Vue({
	router,
	store,
	render: h => h(App),
	mounted () {
		document.dispatchEvent(new Event('render-event'))
	}
}).$mount('#app')
路由配置文件设置mode 为 history
省略
打包
npm run build

查看 dist 目录是否生成每个路由名称对应的文件夹。

打包出错或未生成
  1. 按照以上步骤进行排错,很大概率 插件安装问题,请使用 cnpm 或 淘宝镜像地址安装, 不要使用 npmvue ui 来安装。我在使用过程中就遇到这么一些问题,可能是本地网络环境问题,或者其他问题。有兴趣自己测试下吧。
  2. 同时注意下 Vue CLI 版本,这是基于 3.0+。

meta 信息修改方案

这里有很多种方案来解决问题。其实对于静态宣传页面,可直接写入路由配置文件,项目入口文件中 使用导航守卫 beforeEach 进行写入渲染。

路由配置文件
export default new Router({
    mode: 'history',
    routes: [
		{
		{
			path: '/collect', 
			name: 'collect', 
			component: collect, 
			meta: {
				title: '高考信息', 
				keywords: '汉水河畔 高考信息检索服务 点击对应省份查看该省份 高校列表 高校统计 历年录取分数线',
				description: '汉水河畔,各省高校数量统计图,点击对应省份查看该省份高校列表,高校统计,历年录取分数线。数据来源于 中华人民共和国教育部(数据截止2019-06-17)'
			},
		},
		{
			path: '/app', 
			name: 'app', 
			component: app, 
			meta: {
				title: '长安驿APP', 
				keywords: '长安驿APP 产品介绍 答疑 下载',
				description: '长安驿APP,致力于打造本地一体化生活平台,各种方案解决综合向Demo,精选本地生活相关资讯文章视频,房产房源信息及分析统计报告,导流类型商城,电视直播以及电影点播,朋友圈动态等。'
			},
		},
    ]

})
项目入口文件
router.beforeEach((to, from, next) => {
	if (to.meta.title) {
		document.title = to.meta.title;
	}
	// 此处选择 id 元素对应模板页面中定义 id
	if (to.meta.keywords) {
		document.querySelector("#keywords").setAttribute("content", to.meta.keywords);
		document.querySelector("#description").setAttribute("content", to.meta.description);
	}
	next();
})
模板页面 index.html
<meta id="keywords" 
	name="keywords" 
	content="汉水河畔的博客网站,致力于全栈开发,提供丰富的信息检索服务。" />
<meta id="description" 
	name="description" 
	content="汉水河畔的博客网站,提供开放接口服务,影视检索,疾病信息检索,高考信息检索服务,更多内容请下载长安驿APP。" />

那对于动态赋值的呢?还有方案!使用 vue-meta 插件,当然还可有很多方法。以下是使用 vue-meta 插件来修改 meta 信息。

插件安装
npm install vue-meta --save
项目入口文件
import VueMeta from 'vue-meta'
 
Vue.use(VueMeta, {
  // optional pluginOptions
  refreshOnceOnNavigation: true
})
组件中使用
export default{
	data(){
		return{
		    title: '',
			meta: {},
		}
	},
	metaInfo () {
	  return {
		title: this.title,
		meta: [
		  { vmid: 'keywords', name: 'keywords', content: this.meta.keywords },
		  { vmid: 'description', name: 'description', content: this.meta.description }
		]
	  }
	},
	// 后端接口请求赋值就省略了
}

参考资料

浅谈SPA、SEO、SSR

webpack 相关 | Vue CLI

Vue-cli使用prerender-spa-plugin插件预渲染

基于Vue SEO的四种方案

Webpack Simple Template - Prerender SPA Example

你可能感兴趣的:(vue,vue,vue.js)