Vue预渲染之prerender-spa-plugin

262 阅读1分钟

简介与使用场景

vue由于是单页面应用,因此会有首屏加载比较慢,以及对SEO不友好的缺点。针对这些缺点,我们会采用:服务端SSR和预加载来分别解决

预加载的使用场景仅在例如:/about,/contact,/index等静态界面试用,无需服务器实时动态编辑html,而是在构建时,简单的针对特定的路由生成html文件

预渲染插件

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

本次文章适用版本

  "vue": "^2.6.1",
 "prerender-spa-plugin": "^3.4.0",

build/utils.js配置

exports.cssLoaders = function(options) {
    ...
    // generate loader string to be used with extract text plugin
    function generateLoaders(loader, loaderOptions) {
        const loaders = options.usePostCSS ?
            [cssLoader, postcssLoader] :
            [cssLoader];

        if (loader) {
            loaders.push({
                loader: loader + "-loader",
                options: Object.assign({}, loaderOptions, {
                    sourceMap: options.sourceMap
                })
            });
        }

        // Extract CSS when that option is specified
        // (which is the case during production build)
        if (options.extract) {
            return ExtractTextPlugin.extract({
                use: loaders,
                fallback: "vue-style-loader",
                //warn:注意此处,需要添加publicPath
                publicPath: "../../"
            });
        } else {
            return ["vue-style-loader"].concat(loaders);
        }
    }
    ...
};

build/webpack.prod.conf.js配置

const webpackConfig = merge(baseWebpackConfig, {
  ...
    plugins: [
     ...
     //增加此处代码
        new PrerenderSPAPlugin({
            staticDir: path.join(__dirname, "../dist"),
            // 对应路由文件的path
            routes: ["/", "/css", "/pagesize"],
            renderer: new Renderer({
                inject: {
                    foo: "bar"
                },
                // headless: false,
                // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
                renderAfterDocumentEvent: "render-event",
                // 可选-等待渲染,直到经过一定的时间。
                // 不推荐
                renderAfterTime: 5000,
                // 可选-默认为0,无限制。
                // 路由是异步呈现的。
                // 使用它来限制并行渲染的路由数量
                maxConcurrentRoutes: 4
            })
        })
        ...
    ]
    ...
});

main.js配置


new Vue({
    el: "#app",
    store,
    router,
    components: { App },
    template: "<App/>",
    //此处一定要加
    mounted() {
        document.dispatchEvent(new Event("render-event"));
    }
});

引用链接:

juejin.cn/post/686261…

juejin.cn/post/684490…