乐趣区

关于前端:基于prerenderspaplugin的Vuejs预渲染实践

应用背景

最近公司基于 vue-cli3.0 搭建的老我的项目要做 SEO 优化,并且路由是 hash 模式;服务端渲染革新老本很大,看了一些文章后决定试一下预渲染,搭配 vue-meta-info 定制 meta 信息达到预期成果。

革新内容

1. 路由模式

  • 路由模式切换为 history 模式,去除 URL 中的 #
const router = new VueRouter({
  mode: 'history',
  routes: [...]
})
  • 路由懒加载,配合预渲染更好做到按需加载
{
    path: "/about",
    name: "About",
    component: () =>
      import(/* webpackChunkName: "about" */ "../views/About.vue")
}
js
├── about.95b9e039.js   <-- 打包输入后,路由懒加载拜访对应 js
├── app.7be39401.js
└── chunk-vendors.9cd40e36.js
  • 服务端配置笼罩无动态资源状况下返回的页面,防止间接拜访或刷新 404
 预渲染页面拜访门路指向其对应目录下的 index.html,其余状况间接指向打包输入根目录下的主入口 index.html。
/**
 * 创立本地服务
 */
http
  .createServer((req, res) => {const filePath = getFilePath(req);
    const indexFilePath = path.join(__dirname, "/dist/index.html");
    const exists = fs.existsSync(filePath);
    const data = fs.readFileSync(exists ? filePath : indexFilePath);
    writeHead(res, filePath);
    res.end(data);
  })
  .listen(port, hostname, () => {console.log(`Server running at http://${hostname}:${port}/`);
  });
dist
├── favicon.ico
├── home             
│   └── index.html  <-- http://localhost:8080/home 返回此预渲染页面
├── index.html      <-- http://localhost:8080/about 返回此候选资源
└── static

2.prerender-spa-plugin 应用

  • 装置依赖
 npm install prerender-spa-plugin --save-dev
 or
 --registry https://registry.npm.taobao.org  应用镜像装置  
 or
 cnpm 
  • 增加 vue.config.js 配置
const path = require("path");
const PrerenderSpaPlugin = require("prerender-spa-plugin");
const isProduction = process.env.NODE_ENV === "production";

module.exports = {
  publicPath: "/",
  outputDir: "dist",
  assetsDir: "static",
  productionSourceMap: false,
  configureWebpack: config => {if (isProduction) {
      config.plugins.push(
        // 预渲染插件配置
        new PrerenderSpaPlugin({
          // 动态资源门路
          staticDir: path.join(__dirname, "dist"),
          // 预渲染路由
          routes: ["/home"]
        })
      );
    }
  }
};
  • build 后生成 dist 目录,构造如下:
dist
├── favicon.ico
├── home     
│   └── index.html   <-- 预渲染页面   
├── index.html       <-- 主入口页面
└── static
    ├── css
    ├── img
    └── js

3.vue-meta-info 应用

  • 装置依赖
 npm install vue-meta-info --save-dev
  • 全局注册
import Vue from 'vue'
import MetaInfo from 'vue-meta-info'

Vue.use(MetaInfo)
  • 组件中动态用法,定制的 meta 信息在预渲染时也会写入页面
<template>
  ...
</template>

<script>
  export default {
    metaInfo: {
      // set a title
      title: 'Home',
      // set meta
      meta: [{                
        name: 'keyword',
        content: 'My Example Keyword'
      }],
      // set link
      link: [{                 
        rel: 'asstes',
        href: 'https://xxx.com/'
      }]
    }
  }
</script>

4. 试试成果

残缺示例地址

示例工程中内置了命令,打包输入 dist 目录后主动运行本地服务进行预览。

总结

  • 比照服务端渲染,简略易上手
  • 实用于页面数量少且偏动态的页面
  • 预渲染页面数据异步加载会有空白期,先加载预渲染局部;此时能够适当退出加载状态或骨架屏防止难堪
退出移动版