这里使用 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;
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 中,报错消失