出現 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 中,報錯消失