Control HTML Emit stage
serkanyersen opened this issue · 5 comments
Hi,
I have a plugin that generates a custom manifest about the assets generated by webpack, I also need to embed the finalized manifest into the html.
My problem right now is that contents of the assets are not finalized until the PROCESS_ASSETS_STAGE_OPTIMIZE_HASH
stage is done, because some chunks might be altered with the updated hashes. However, html-webpack-plugin
is emitting the final HTML at PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE
stage.
Which is very early and there is no way to go back to update the HTML generated.
It would be nice if there is a way to control the stage when the HTML is emitted here
Lines 216 to 223 in 9c9786a
If I set this to PROCESS_ASSETS_STAGE_REPORT
everything works as expected for me.
is there a way to achieve this without this change? if not can we make stage configurable?
if I locally patch the package to run at PROCESS_ASSETS_STAGE_REPORT
or intercept like this
compilation.hooks.processAssets.intercept({
register: (tap) => {
if (tap.name === 'HtmlWebpackPlugin') {
tap.stage = webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT;
}
return tap;
},
})
would it cause any issues?
We have a similar issue with our plugin that uses HtmlWebpackPlugin as well.
@jantimon, would the fix suggested by @serkanyersen cause any issues?
Thank you!
There was a long discussion about this topic here:
in the end @sokra told us to use PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE
maybe we can ask him for advice
I did use the intercept for a while and it worked fine but later on I replaced that logic with the following.
compiler.hooks.compilation.tap(this.constructor.name, compilation => {
const hooks = this.options.htmlWebpackPlugin.getHooks(compilation);
hooks.beforeEmit.tap(this.constructor.name, data => {
// modify HTML
return data;
});
});
compiler.hooks.thisCompilation.tap(this.constructor.name, compilation => {
if (compilation.hooks.processAssets) {
compilation.hooks.processAssets.tap(
{
name: this.constructor.name,
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ANALYSE,
additionalAssets: true,
},
assets => {
// correct hashes here including modified HTML
},
);
}
});
Which gave me better results without intercepting. hope this helps.
Edit: I made this change because I no longer needed to embed the manifest into the HTML. which resolved my conflict.
Close due webpack/webpack#11822, most often the problem is in other plugins and they use the wrong stage, anyway feel free to feedback