html-webpack-plugin
html-webpack-plugin copied to clipboard
No documented replacement / upgrade path for `htmlWebpackPluginAlterChunks` removed in 4.0.0
Current behaviour 💣
In v4.0.0. removed a hook called htmlWebpackPluginAlterChunks
but without any reasoning or documented replacement (https://github.com/jantimon/html-webpack-plugin/commit/342867e1edb7c2a8748b0aca396f160f0b13d42e).
I've picked up an old project and I'm rying to use this hook in a plugin pulled from a (now archived) Shopify Slate theme tool. However without any documented upgrade path I've hit a dead end.
I understand that its been missing for years now, but if theres any documentaiton or thoughts on how it can replaced, I'd be greatly appreciative.
Expected behaviour ☀️
To have a documented replacement for htmlWebpackPluginAlterChunks
Reproduction Example 👾
https://github.com/Shopify/slate/blob/master/packages/slate-tools/tools/webpack/html-webpack-include-chunks.js
constructor(options) {
this.options = options;
this.files = [];
}
apply(compiler) {
compiler.hooks.compilation.tap(
'htmlWebpackIncludeChunksPlugin',
this.onCompilation.bind(this),
);
}
onCompilation(compilation) {
this.compilation = compilation;
compilation.hooks.htmlWebpackPluginAlterChunks.tap(
'htmlWebpackIncludeChunksPlugin',
this.onAlterChunks.bind(this),
);
compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration.tap(
'htmlWebpackIncludeChunksPlugin',
this.onBeforeHtmlGeneration.bind(this),
);
}
onAlterChunks(chunks) {
this.chunks = chunks;
}
onBeforeHtmlGeneration(htmlPluginData) {
const assets = htmlPluginData.assets;
const publicPath = assets.publicPath;
this.chunks.forEach((chunk) => {
const name = chunk.names[0];
const chunkFiles = []
.concat(chunk.files)
.map((chunkFile) => publicPath + chunkFile);
const css = chunkFiles
.filter((chunkFile) => /.(css|scss)\.liquid($|\?)/.test(chunkFile))
.map((chunkFile) => chunkFile.replace(/(\.css)?\.liquid$/, '.css'));
assets.chunks[name].css = css;
assets.css = assets.css.concat(css);
});
}
}
module.exports = HtmlWebpackIncludeLiquidStylesPlugin;
Environment 🖥
Node.js v16.15.0 darwin 21.5.0 8.5.5
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected] deduped
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ ├─┬ @webpack-cli/[email protected]
│ │ └── [email protected] deduped
│ └── [email protected] deduped
└── [email protected]
└── [email protected]
Commit 342867e1edb7c2a8748b0aca396f160f0b13d42e has some explanation for this.
BREAKING CHANGES: Pass the entry point names to the custom sort function instead of chunk objects. Removed the alter
htmlWebpackPluginAlterChunks
hook. Changed the structure of theassets
argument for all hooks.
I am not familiar with how html-webpack-plugin works, however if I had to guess then its because this plugin no longer processes chunks.
I am using this plugin and provided a custom sort order via chunksSortMode
, and also am using the splitChunks.cacheGroups
chunk-splitting optimization provided by Webpack:
const webpackConfig = {
...
entry: {
main: [
'babel-polyfill',
'./index.js',
],
splash: ['./web/splash/splash.js'],
},
...
plugins: [
...
new HtmlWebpackPlugin({
chunksSortMode: (chunkA, chunkB) => {
console.log('RORY_DEBUG sorting chunks:', {chunkA, chunkB});
if (chunkA === 'splash') {
return -1;
}
return chunkB - chunkA;
},
}),
...
],
...
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'initial',
},
},
},
},
};
The result I see is this:

Where the splash
entry point is correct sorted above the main
entry point, but the other chunks created by optimization.splitChunks.cacheGroups
are not sorted. This is breaking what I am trying to do i.e: move the inline splash
chunk above the other external chunks that have defer
. This in turn is causing my inline blocking chunk to not be executed until the other defer
scripts have downloaded and evaluated.
@OliverJEvans I'm not sure if it addresses your concerns, but I created a PR to address mine: https://github.com/jantimon/html-webpack-plugin/pull/1774. Feel free to test it out and see if it helps you.