zoukankan      html  css  js  c++  java
  • Vue-cli使用prerender-spa-plugin插件预渲染和配置cdn

    参考:https://www.jianshu.com/p/6a4c0b281e7f

    使用vue-cli打包项目一般为spa项目,众所周知单页面应用不利于SEO,有ssr和预渲染两种解决方案,这里我们只讨论预渲染。

    此教程使用的prerender-spa-plugin版本和vue版本

    vue-cli有2.0和3.0版本,解决方法是不一样的,这里我们要分开讨论。

    vue-cli3.0版本

    3.0的cli看上去简洁多了,去掉了2.0 build和config等目录,那我们怎么去修改webpack的配置呢?
    在根目录下创建vue.config.js,进行你的配置。

    1.安装

     cnpm install prerender-spa-plugin --save
    

    2.vue-config.js中增加

    const PrerenderSPAPlugin = require('prerender-spa-plugin');
    const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
    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: ['/', '/product','/about'],
                        // 这个很重要,如果没有配置这段,也不会进行预编译
                        renderer: new Renderer({
                            inject: {
                                foo: 'bar'
                            },
                            headless: false,
                            // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
                            renderAfterDocumentEvent: 'render-event'
                        })
                    }),
                ],
            };
        }
    }
    

    3.在main.js中增加

    new Vue({
      router,
      store,
      render: h => h(App),
      mounted () {
        document.dispatchEvent(new Event('render-event'))
      }
    }).$mount('#app')
    

    4.router.js 中设置mode: “history”

    5.运行npm run build,看一下生成的 dist 的目录里是不是有每个路由名称对应的文件夹。然后找个 目录里 的 index.html 用IDE打开,看文件内容里是否有该文件应该有的内容。有的话,就设置成功了,如果没成功,照着上面的步骤再来一次!!!

    vue-cli2.0版本
    1.安装

     cnpm install prerender-spa-plugin --save
    

    2.webpack.prod.conf.js增加部分代码

    const path = require('path')
    const PrerenderSPAPlugin = require('prerender-spa-plugin')   //引用插件
    const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
    const webpackConfig = merge(baseWebpackConfig, {
        plugins: [
            // vue-cli生成的配置中就已有这个了,不要动
            new HtmlWebpackPlugin({
                filename: config.build.index,
                template: 'index.html',
                inject: true,
                minify: {
                    removeComments: true,
                    collapseWhitespace: true,
                    removeAttributeQuotes: true
                },
                chunksSortMode: 'dependency'
            }),
            // 配置PrerenderSPAPlugin
            new PrerenderSPAPlugin({
                // 生成文件的路径,也可以与webpakc打包的一致。
                staticDir: path.join(__dirname, '../dist'),
                
                // 对应自己的路由文件,比如index有参数,就需要写成 /index/param1。
                routes: ['/', '/product','/about','/contact','/join','/jzjh'],
               
                // 这个很重要,如果没有配置这段,也不会进行预编译
                renderer: new Renderer({
                    inject: {
                      foo: 'bar'
                    },
                    headless: false,
                    // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
                    renderAfterDocumentEvent: 'render-event'
                })
            })
        ]
    })
    

    3.在main.js中增加

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

    4.router.js 中设置mode: “history”

    5.运行npm run build,看一下生成的 dist 的目录里是不是有每个路由名称对应的文件夹。然后找个 目录里 的 index.html 用IDE打开,看文件内容里是否有该文件应该有的内容。有的话,就设置成功了,如果没成功,照着上面的步骤再来一次!!!

    特别提醒

    1.vue-cli2.0和3.0的设置大致一致,但有一个很不同
    在3.0中,设置staticDir: path.join(__dirname,'dist'),
    在2.0中,设置staticDir: path.join(__dirname,'../dist'),
    如果你把3.0的staticDir设置为path.join(__dirname,'../dist')或者把2.0的staticDir设置为path.join(__dirname,'dist'),运行npm run build 都会报错,这要特别注意!!!

    2.细心的小伙伴会发现,不管2.0还是3.0都需要设置 history 模式,那这一步是否是必须的呢?经过测试,如果不设置history模式,其实也能运行和生成文件的,但查看每个index.html文件的内容都会是一样的。所以这一步是必须的

    如果你想修改每个页面的meta 信息,这里推荐使用 vue-meta

    如何再静态生成的如:indexl.html的html文件图片等使用我们配置的cdn环境呢?

    1.src目录下增加文件public-path.js

    /**
     * CDN
     */
    
    const isPrerender = window.__PRERENDER_INJECTED__ === 'prerender'
    
    __webpack_public_path__ = isPrerender ? '' : process.env.CDN_PATH

    2.main.js引入public-path.js,注意要在最开头的地方添加

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import './public-path'
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import VueMeta from 'vue-meta'
    import $ from 'jquery'
    import 'babel-polyfill'
    import 'bootstrap/dist/css/bootstrap.min.css'
    import 'bootstrap/dist/js/bootstrap.min.js'
    import 'swiper/dist/css/swiper.css';
    Vue.config.productionTip = false
    Vue.use(VueMeta)
    new Vue({
      el: '#app',
      router,
      render: h => h(App),
      mounted() {
        document.dispatchEvent(new Event('render-event'))
      }
    })

    3.修改webpack.pro.conf.js文件

    // 配置PrerenderSPAPlugin
        new PrerenderSPAPlugin({
          staticDir: config.build.assetsRoot,
          routes: [ '/' ],
          outputDir: path.join(config.build.assetsRoot, config.build.assetsPublicPath),
          indexPath: path.join(config.build.assetsRoot, 'index.html'),
          postProcess (renderedRoute) {
            // add CDN
            let cdnPath = JSON.parse(env.CDN_PATH);
            renderedRoute.html = renderedRoute.html.replace(
              /(<script[^<>]*src=")((?!http|https)[^<>"]*)("[^<>]*>[^<>]*</script>)/ig,
             `$1${cdnPath}$2$3`
            ).replace(
              /(<link[^<>]*href=")((?!http|https)[^<>"]*)("[^<>]*>)/ig,
             `$1${cdnPath}$2$3`
            ).replace(/(<img[^<>]*src=")((?!http|https|data:image)[^<>"]*)("[^<>]*>)/ig,
            `$1${cdnPath}$2$3`)
    
            return renderedRoute
          },
    
          renderer: new Renderer({
            injectProperty: '__PRERENDER_INJECTED__',
            inject: 'prerender',
            renderAfterDocumentEvent: 'render-event',
          })
        }),

    注意红色字体的,把相对路径的img和js加上我们的cdn路径

     
  • 相关阅读:
    高级程序设计语言学习2
    程序设计语言学习
    基于Android,对硬件、框架、API、操作系统、应用程序的理解
    Python_code_使用OpenCV库对图片实现数据增强
    Python_code_使用ImageFilter库对图片实现数据增强
    Python_code_实现贴图功能
    Python_code_使用OpenCV库实现对图像的_平移_旋转_缩放
    Python_code_七段数码管绘制实现_happy-new-year
    3_一幅图像,经过傅里叶变换后,将高频部分删除,再进行反变换,设想一下将会得到什么结果?
    2_图像处理中正交变换的目的是什么?图像变换主要用于那些方面?
  • 原文地址:https://www.cnblogs.com/dehuachenyunfei/p/vue_seo.html
Copyright © 2011-2022 走看看