vue使用prerender-spa-plugin+html-webpack-plugin预渲染打包后,出现webpackJsonp is not defined

欧渝
2023-12-01

出现 webpackJsonp is not defined 是因为 manifest.js 加载在vendor文件后面了,下面我们调整manifest.js文件在头部加载


这里使用 html-webpack-plugin 的事件:html-webpack-plugin-alter-asset-tags ,修改manifest.js到头部加载

在webpack.prod.conf.js同级目录中,新建一个my-plugin.js文件,内容如下:

function MyPlugin(options) {
    this.options = options;
}
MyPlugin.prototype.apply = function(compiler) {
    compiler.plugin('compilation', function(compilation) {
        /*
        出现 webpackJsonp is not defined 是因为 manifest.js 加载在vendor文件后面了,下面我们调整manifest.js文件在头部加载
        这里使用插件:html-webpack-plugin-alter-asset-tags
        来修改manifest.js到顶部加载
        */
        compilation.plugin('html-webpack-plugin-alter-asset-tags', function(htmlPluginData, callback) {
            console.log(33333333333)
            console.log(htmlPluginData.head)
            console.log(htmlPluginData.body)
            //**********************修改manifest开始*********
            //因为manifest存在于htmlPluginData.body里
            //先获取manifest.js
            let manifest = '';
            if (htmlPluginData.body && htmlPluginData.body.length) {
                let index = 0;
                let manifestindex = 0;
                htmlPluginData.body.forEach(item => {
                    if (item.attributes) {
                        let src = item.attributes.src;
                        if(src.indexOf('manifest') !== -1){
                            manifest = item
                            manifestindex = index;
                        }
                    }
                    index++;
                });
                if(manifest){
                    htmlPluginData.body.splice(manifestindex,1)
                }
            }
            //修改头部数据
            //把每个 href 带有 css/ 字符串的标签加上 id
            if (htmlPluginData.head && htmlPluginData.head.length) {
                htmlPluginData.head.forEach(item => {
                    if (item.attributes) {
                        let href = item.attributes.href;
                        item.attributes.id = href.substring(href.indexOf('css/') + 4, href.indexOf('.'));
                    }
                });
            }
            //把 manifest.js 插入到头部中去
            htmlPluginData.head.unshift(manifest)
            console.log(htmlPluginData.head)
            console.log(htmlPluginData.body)
            //**********************修改manifest结束*********

            callback(null, htmlPluginData);
        });
    });
};
module.exports = MyPlugin;

修改webpack.prod.conf.js,加载 my-plugin.js,修改内容如下:

const baseWebpackConfig = require('./webpack.base.conf')
const MyPlugin = require('./my-plugin.js')

const webpackConfig = merge(baseWebpackConfig, {
    plugins: [

        // 在 plugins 增加一个 new MyPlugin
        new MyPlugin({options: ''}),

        new HtmlWebpackPlugin({
            filename: process.env.NODE_ENV === 'testing'
                ? 'index.html'
                : config.build.index,
            template: 'index.html',
            inject: true,
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
            },
            chunks: ['manifest','vendor', 'app'],
            chunksSortMode: 'manual'

        }),

        new webpack.HashedModuleIdsPlugin(),

        new webpack.optimize.ModuleConcatenationPlugin(),

        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            minChunks(module) {
                // any required modules inside node_modules are extracted to vendor
                return (
                    module.resource &&
                    /\.js$/.test(module.resource) &&
                    module.resource.indexOf(
                        path.join(__dirname, '../node_modules')
                    ) === 0
                )
            }
        }),

        //从vendor里 提取 manifest 到一个独立 js 文件中
        new webpack.optimize.CommonsChunkPlugin({
            name: 'manifest',
            chunks: ['vendor']
        }),

        new webpack.optimize.CommonsChunkPlugin({
            name: 'app',
            async: 'vendor-async',
            children: true,
            minChunks: 3
        }),

        // copy custom static assets
        new CopyWebpackPlugin([
            {
                from: path.resolve(__dirname, '../static'),
                to: config.build.assetsSubDirectory,
                ignore: ['.*']
            }
        ]),

        // 配置PrerenderSPAPlugin
        new PrerenderSPAPlugin({
            // 生成文件的路径,也可以与webpack打包的一致。
            staticDir: path.join(__dirname, '../dist'),

            // 对应自己的路由文件,比如index有参数,就需要写成 /index/param1。
            routes: ['' ,'/', '/goodsinfo'],

            // 这个很重要,如果没有配置这段,也不会进行预编译
            renderer: new Renderer({//这样写renderAfterTime生效了
                inject: {
                    foo: 'bar'
                },
                headless: false,
                // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
                renderAfterDocumentEvent: 'render-event',
                captureAfterTime: 5, //单位秒
            })
        })
    ]

});

module.exports = webpackConfig;

再次打包后,manifest.js 将会出现在 header 中,报错消失

参考:https://juejin.im/post/5c8c61f7e51d451cef61c92b

参考:https://www.cnblogs.com/haogj/p/5649670.html

 类似资料: