vue使用prerender-spa-plugin+html-webpack-plugin預渲染打包後,出現webpackJsonp is not defined

出現 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

發佈了160 篇原創文章 · 獲贊 45 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章