美文网首页
VUE - prerender-spa-plugin预渲染

VUE - prerender-spa-plugin预渲染

作者: coderfl | 来源:发表于2020-03-31 22:40 被阅读0次
prerender-spa-plugin预渲染原理
  • prerender-spa-plugin 利用了 Puppeteer 的爬取页面的功能。 Puppeteer 是一个 Chrome官方出品的 headlessChromenode 库。它提供了一系列的 API, 可以在无 UI 的情况下调用 Chrome 的功能, 适用于爬虫、自动化处理等各种场景。它很强大,所以很简单就能将运行时的 HTML 打包到文件中。原理是在 Webpack 构建阶段的最后,在本地启动一个 Puppeteer 的服务,访问配置了预渲染的路由,然后将 Puppeteer 中渲染的页面输出到 HTML 文件中,并建立路由对应的目录。
简介与使用场景
  1. 我们知道SPA有很多优点,不过一个缺点就是对(不是Google的)愚蠢的搜索引擎的SEO不友好,为了照顾这些引擎,目前主要有两个方案:服务端渲染(Server Side Rendering)、预渲染(Prerending)。
  2. 如果你只需要改善少数页面(例如 /, /about, /contact 等)的 SEO,那么你可能需要预渲染。无需使用 web 服务器实时动态编译 HTML (服务端渲染, SSR),而是使用预渲染方式,在构建时(build time)简单地生成针对特定路由的静态 HTML 文件。它主要使用 prerender-spa-plugin 插件,其与SSR一样都可以加快页面的加载速度,并且侵入性更小,在已上线的项目稍加改动也可以轻松引入预渲染机制,而SSR方案则需要将整个项目结构推翻;
  3. 访问预渲染出来的页面在访问时与SSR一样快,并且它将服务端编译HTML的时机提前到了构建时,因此也降低了服务端的压力,如果你的服务器跟我的一样买的 1M1G1核 的小水管服务器 ( 穷 ),那么预渲染可能更适合你。不过SSR和预渲染的使用场景还是有较明显的区别的。预渲染的使用场景更多是简单的静态页面。服务端渲染适用于复杂、较大型、与服务端交互频繁的功能型网站,比如电商网站。
配置(参考https://github.com/chrisvfritz/prerender-spa-plugin)下的demoVue.js 2 Router
  1. 文件列表(项目src同级目录创建 favicon.icoindex.htmlwebpack.config.js
  • ico 和 html 直接复制public中的,html 中的 BASE_URL 删掉,否则打包会失败,会提示:ReferenceError: BASE_URL is not defined
  • 安装依赖包 npm i -D prerender-spa-plugin webpack webpack-cli cross-env
    image.png
  1. ./webpack.config.js
var path = require('path')
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  mode: process.env.NODE_ENV,
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/',
    filename: 'build.js'
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      },
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ]
      }
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
  devServer: {
    historyApiFallback: true,
    noInfo: false,
  },
  devtool: '#eval-source-map',
  plugins: [
    new VueLoaderPlugin(),
  ]
}
if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new HtmlWebpackPlugin({
      title: 'PRODUCTION prerender-spa-plugin',
      template: 'index.html',
      filename: path.resolve(__dirname, 'dist/index.html'),
      favicon: 'favicon.ico'
    }),
    new PrerenderSPAPlugin({
      staticDir: path.join(__dirname, 'dist'),
      routes: [ '/', '/about', '/contact' ],  // 路由这块根据自己的路由改写

      renderer: new Renderer({
        inject: {
          foo: 'bar'
        },
        headless: true,
        renderAfterDocumentEvent: 'render-event'
      })
    })
  ])
} else {
  // NODE_ENV === 'development'
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"development"'
      }
    }),
    new HtmlWebpackPlugin({
      title: 'DEVELOPMENT prerender-spa-plugin',
      template: 'index.html',
      filename: 'index.html',
      favicon: 'favicon.ico'
    }),
  ])
}
  1. ./src/main.js,挂载方法重写
new Vue({
  el: '#app',
  router,
  render: h => h(App),
  mounted () {
    document.dispatchEvent(new Event('render-event'))
  }
})
  1. ./package.json 中添加预渲染打包命令
    "prerender-build": "cross-env NODE_ENV=production webpack --progress --hide-modules"

相关文章

网友评论

      本文标题:VUE - prerender-spa-plugin预渲染

      本文链接:https://www.haomeiwen.com/subject/pwlnuhtx.html