vue预渲染

声明:本文部分参考了 kang_k 大神的文章 vue做seo优化 https://blog.csdn.net/kang_k/article/details/100514042

1.前言

最近要开始开发一个门户网站,此项目需要SEO优化,考虑了两种方案 SSR 服务端渲染和 预渲染;由于服务端渲染需要后端配合,而前期需求基本是静态html页面,人工成本和时间较高,所以选择了vue官方推荐的预渲染技术;

vue预渲染_第1张图片

2.项目搭建

此项目主要使用vue-cli4进行搭建,(也可以使用vue-cli3,差别不大)而预渲染技术,核心就是使用插件 prerender-spa-plugin;

  • 首先,安装依赖,建议大家是用淘宝源进行安装,下为我自己项目中使用的依赖
"dependencies": {
    "amfe-flexible": "^2.2.1", 
    "axios": "0.21.1",
    "core-js": "^3.6.5",
    "jquery": "^3.5.1",
    "lodash": "^4.15.17",
    "normalize.css": "8.0.0",
    "qs": "^6.5.1",
    "vue": "^2.6.11",
    "vue-meta-info": "^0.1.7",
    "vue-router": "^3.2.0",
    "vuex": "^3.4.0",
    "vuex-persist": "^2.2.0"
  },
 "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/eslint-config-standard": "^5.1.2",
    "babel-eslint": "^10.1.0",
    "babel-plugin-dynamic-import-node": "^2.3.3",
    "babel-plugin-import": "^1.13.3",
    "eslint": "^6.7.2",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^6.2.2",
    "postcss-pxtorem": "^4.0.1",
    "prerender-spa-plugin": "^3.4.0", // 预渲染插件
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2",
    "script-ext-html-webpack-plugin": "2.1.3",
    "script-loader": "0.7.2",
    "serve-static": "^1.13.2",
    "vue-template-compiler": "^2.6.11"
  },
  • 安装依赖完成后,要配置vue.config.js,再根目录新建vue.config.js文件,进行配置
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
// eslint-disable-next-line no-unused-vars
const webpack = require('webpack')
const path = require('path')

module.exports = {
  configureWebpack: config => {
    if (process.env.NODE_ENV !== 'production') return
    return {
      plugins: [
        new PrerenderSPAPlugin({
          // 生成文件的路径,也可以与webpakc打包的一致。
          // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
          staticDir: path.join(__dirname, 'dist'),
          // 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
          routes: ['/',  '/about'],
          // 这个很重要,如果没有配置这段,也不会进行预编译
          renderer: new Renderer({
              inject: { //默认挂在window.__PRERENDER_INJECTED对象上,可以通过window.__PRERENDER_INJECTED.foo在预渲染页面取值
            },
            headless: false,
			executablePath: "./chromium/chrome-win/chrome.exe", // windows系统下谷歌浏览器的可执行文件 
            // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
            renderAfterDocumentEvent: 'render-event'//等到事件触发去渲染,此处我理解为是Puppeteer获取页面的时机
          })
        })
      ]
    }
  },
}
showMessage(){
   if(window.__PRERENDER_INJECTED && window.__PRERENDER_INJECTED.foo =='bar') return;
   this.message = '我是测试预加载拦截';
}

renderAfterDocumentEvent 这个则很关键,这个是监听 document.dispatchEvent 事件,决定什么时候开始预渲染。

  • main.js修改
new Vue({
  router,
  store,
  render: h => h(App),
//添加到这里,这里的render-event和vue.config.js里面的renderAfterDocumentEvent配置名称一致
  mounted () {
    document.dispatchEvent(new Event('render-event'))
  }
}).$mount('#app')

router.js里面把mode要为’history’,hash模式会打包的时候生成同样的页面,所以一定要history

  • 运行npm run build

再build的过程中会遇到很多坑,其中大概率会出现 Error: Chromium revision is not downloaded. Failed to download Chromium 这条报错,这是因为prerender-spa-plugin插件中会使用puppeteer,Puppeteer 是 Chrome 开发团队在 2017 年发布的一个 Node.js 包,用来模拟 Chrome 浏览器的运行。目的是项目在打包过程中通过浏览器预渲染完成,然后输出html和其他css, js资源,而由于Chromium一般很容易安装失败,就需要下载到本地,这是Chromium的淘宝镜像地址, https://npm.taobao.org/mirrors/chromium-browser-snapshots/

  • 下载Chromium

首先查看 /node_modules/puppeteer下packag.json中所依赖的Chromium版本号,然后到镜像地址下载对应的文件,注意根据自己的开发环境区分windows 和linux的版本,下载完成后,在项目根目录新建文件夹chromium,把下载好的 chrome-win.zip 解压,放到chromium文件夹内,下载完成。
在这里插入图片描述
vue预渲染_第2张图片

之后再vue.config.js 进行配置 executablePath: “./chromium/chrome-win/chrome.exe”,指定可运行的浏览器程序,具体文件地址可根据自己的项目结构配置。

执行npm run build 后,把dist文件放到服务器上,或者本地启动一个服务器,打开网页可看到渲染结果。

  • 打包后的dist文件夹

vue预渲染_第3张图片

然后就是为这些打包的静态页面分配title和meta标签,需要用到 vue-meta-info
安装

npm install vue-meta-info --save

main.js里面引入vue-meta-info

import MetaInfo from 'vue-meta-info'

Vue.use(MetaInfo)
这样在组件页面中就可以使用了
假设你要给about.vue添加title,meta标签

about.vue

<template>
...
</template>

<script>
export default {
  metaInfo: {
    title: '我是about头', // set a title
    meta: [{             // set meta
      name: 'keyWords',
      content: '我是about关键字'
    },
    {
      name: 'description',
      content: '我是about描述'
    }],
    link: [{ // set link
      rel: 'asstes',
      href: '
    }]
  }
}
</script>

这样再结合prerender-spa-plugin,打包之后,在dist文件夹找到about文件夹下的index.html
打开你会发现就有title和meta的关键字和描述标签了

本地起服务或者发布到线上运行项目,在页面右键–查看源代码–就可以看到页面的title和meta标签了。

特别注意:
在项目中发现,build打包过程中会出现弹窗,
vue预渲染_第4张图片
这个弹窗后请立即关闭弹窗,否则会打包失败,目前原因未知,会再以后过程解决。

你可能感兴趣的:(vue,seo,javascript)