博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Vue项目预渲染机制引入实践
阅读量:6037 次
发布时间:2019-06-20

本文共 3946 字,大约阅读时间需要 13 分钟。

周末想顺便把已经做好静态页面的webApp项目做一下SEO优化,由于不想写蹩脚的代码,所以准备采用预渲染,本来想着网上有这么多的文章,随便找个来跟着做不就完了嘛,结果年轻的我付出了整个周末..... 这篇文章就记录一下最后是怎么配置的 T.T

声明:

  1. 以下配置只保留有必要的
  2. 生成目录这里使用base代替,请自行修改
  3. vue-cli模板使用webpack,其他模板类推

1. 简介与使用场景

我们知道SPA有很多优点,不过一个缺点就是对(不是Google的)愚蠢的搜索引擎的SEO不友好,为了照顾这些引擎,目前主要有两个方案:服务端渲染(Server Side Rendering)、预渲染(Prerending)。

如果你只需要改善少数页面(例如 /, /about, /contact 等)的 SEO,那么你可能需要预渲染。无需使用 web 服务器实时动态编译 HTML (服务端渲染, SSR),而是使用预渲染方式,在构建时(build time)简单地生成针对特定路由的静态 HTML 文件。它主要使用 插件,其与SSR一样都可以加快页面的加载速度,并且侵入性更小,在已上线的项目稍加改动也可以轻松引入预渲染机制,而SSR方案则需要将整个项目结构推翻;

访问预渲染出来的页面在访问时与SSR一样快,并且它将服务端编译HTML的时机提前到了构建时,因此也降低了服务端的压力,如果你的服务器跟我的一样买的 1M1G1核 的小水管服务器 ( 穷 ),那么预渲染可能更适合你。不过SSR和预渲染的使用场景还是有较明显的区别的。预渲染的使用场景更多是简单的静态页面。服务端渲染适用于复杂、较大型、与服务端交互频繁的功能型网站,比如电商网站。

2. 安装配置

首先来看看相关技术栈:vue^2.5.2、vue-router^3.0.1、vue-cli^2.9.6、webpack^3.6.0、prerender-spa-plugin^3.3.0

2.1 安装

安装跟其他库一样

# Yarn$ yarn add prerender-spa-plugin -D# or NPM$ npm install prerender-spa-plugin --save-dev

2.2 前端配置

首先看看文件结构,用的是vue-cli2的webpack模板生成的文件结构

│  .babelrc│  index.html│  package.json│  README.md├─build│      build.js│      check-versions.js│      utils.js│      vue-loader.conf.js│      webpack.base.conf.js│      webpack.dev.conf.js│      webpack.prod.conf.js├─config│      dev.env.js│      index.js│      prod.env.js├─src│  │  App.vue│  │  main.js│  │ │  ├─assets│  ├─components│  ├─router│  │      index.js│  ├─styles│  ├─utils│  └─views│          BigData.vue│          CompanyHonor.vue

然后是router/index.js的配置,预渲染要求是histroy模式,有的文章说不需要history模式,这是错的,否则生成的页面都是同一个html。另外注意加上base否则如果你希望跳转到二级页面的localhost/base/home时候,在页面中点击<router-link to="/home">home</router-link>的时候会跳转localhost/home

// src/router/index.js

import Vue from 'vue'import Router from 'vue-router'  Vue.use(Router)  export default new Router({  mode: 'history',  base: '/base/',  routes: [...]})

然后是config,这里注意assetsPublicPath不是./,

// config/index.js

const path = require("path")  module.exports = {  build: {    index: path.resolve(__dirname, "../base/index.html"),    assetsRoot: path.resolve(__dirname, ".."),    assetsSubDirectory: "base/static",    assetsPublicPath: "/",  }}

然后是插件的配置,是放在prod中的,因为只有build的时候会用

// build/webpack.prod.conf.js

const path = require('path')const config = require('../config')const PrerenderSPAPlugin = require('prerender-spa-plugin')const Renderer = PrerenderSPAPlugin.PuppeteerRenderer  const webpackConfig = merge(baseWebpackConfig, {  new PrerenderSPAPlugin({   staticDir: config.build.assetsRoot,   outputDir: path.join(config.build.assetsRoot, 'base'),   indexPath: config.build.index,    // 对应路由文件的path   routes: [     '/',     '/BigData',     '/CompanyHonor'   ],    renderer: new Renderer({     headless: false,            // 无桌面系统去掉     renderAfterDocumentEvent: 'render-event'   })  })})

注意了,如果你的项目是部署在linux/centOS之类没有桌面的系统,需要把headless: false去掉,如果centOS报没有找到lib的错,请参考 的解决办法。

另外注意上面一个renderAfterDocumentEvent: 'render-event'了么,这个意思是在render-event事件触发之后执行prerender,这个事件我们在main.js中mounted钩子触发

// src/main.js

import Vue from 'vue'import App from './App'  new Vue({  el: '#app',  render: h => h(App),  mounted() {    document.dispatchEvent(new Event('render-event'))  }})

还有个配置要注意下在 build/utils.js 中的 ExtractTextPlugin.extractpublicPath ,否则一些vue中引用的资源会找不到

// build/utils.js

ExtractTextPlugin.extract({  use: loaders,  fallback: 'vue-style-loader',  // publicPath: '../../'})

这时候执行npm run build就可以生成刚刚配置在PrerenderSPAPlugin插件中routes中的页面html了,这过程中会一闪而过的短暂打开chromium浏览器,不用管。

最后生成的目录树:

│  index.html├─BigData│      index.html├─CompanyHonor│      index.html└─static    ├─css    ├─fonts    ├─img    └─js

最后如果希望进一步优化生成出来页面的SEO,可以配合 这个网上有很多文章,就不赘述了

2.3 nginx配置

顺便贴一下nginx配置

server {        listen 80;        server_name localhost;        root /nginx-1.14.0/html;        error_page 500 502 503 504 /50x.html;                location ~ ^/base/ {          try_files $uri $uri/ /base/index.html;        }        location = /50x.html {            root html;        }}

网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢迎留言指出~

参考:

转载地址:http://rslhx.baihongyu.com/

你可能感兴趣的文章
利用传入的Type类型来调用范型方法的解决方案
查看>>
Top命令内存占用剖析
查看>>
转 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
查看>>
求带分数(蓝桥杯)
查看>>
Bootstrap系列 -- 11. 基础表单
查看>>
格拉西安《智慧书》中最有价值的23条法则
查看>>
7款经典炫酷的HTML5/jQuery动画应用示例及源码
查看>>
那些年我们一起追过的缓存写法(四)
查看>>
mssql手工注入
查看>>
zoj 3203 Light Bulb,三分之二的基本问题
查看>>
Oracle如何删除表中重复记录
查看>>
洛谷八月月赛Round1凄惨记
查看>>
Retrofit 入门学习
查看>>
【树莓派】树莓派网络配置:静态IP、无线网络、服务等
查看>>
JavaScript——双向链表实现
查看>>
抽象类和借口的区别
查看>>
nginx的location root 指令
查看>>
zDiaLog弹出层
查看>>
linux不常用但很有用的命令(持续完善)
查看>>
NFine常见错误
查看>>