Using `integrity: true` with `HtmlWebpackPlugin` _without_ an HTML entry fails
Current behaviour
This is a weird issue because it's not really a use case for this plugin. I only discovered it while try to debug an issue when using the cache (might open another issue for that later).
If integrity: true is set , and there are no HTML entries (with a script tag to add integrity to, I think), the plugin throws an error.
The following config causes a failure:
// webpack.config.js
const HtmlBundlerWebpackPlugin = require('html-bundler-webpack-plugin');
module.exports = {
entry: 'script.js', // this file should exist, contents don't matter
plugins: [
new HtmlBundlerWebpackPlugin({
integrity: true,
})
],
output: {
crossOriginLoading: 'anonymous'
}
}
The error message when running npx -y webpack:
for (const [hash, value] of hashes) {
^
TypeError: hashes is not iterable
at Integrity.getAssetHashes (/home/david/code/test/undefbug/node_modules/html-bundler-webpack-plugin/src/Plugin/Extras/Integrity.js:302:35)
at /home/david/code/test/undefbug/node_modules/html-bundler-webpack-plugin/src/Plugin/Extras/Integrity.js:47:41
at Hook.eval [as call] (eval at create (/home/david/code/test/undefbug/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:1)
at Hook.CALL_DELEGATE [as _call] (/home/david/code/test/undefbug/node_modules/tapable/lib/Hook.js:14:14)
at Compilation.createStatsFactory (/home/david/code/test/undefbug/node_modules/webpack/lib/Compilation.js:1150:27)
at Stats.toString (/home/david/code/test/undefbug/node_modules/webpack/lib/Stats.js:80:41)
at callback (/home/david/code/test/undefbug/node_modules/webpack-cli/lib/webpack-cli.js:1863:44)
at /home/david/code/test/undefbug/node_modules/webpack-cli/lib/webpack-cli.js:1791:21
at /home/david/code/test/undefbug/node_modules/webpack/lib/webpack.js:168:8
at /home/david/code/test/undefbug/node_modules/webpack/lib/HookWebpackError.js:68:3
Expected behaviour
It shouldn't error :-)
I think you just need to check that hashes exists before trying to iterate.
Reproduction
// script.js
console.log("hello");
// webpack.config.js
const HtmlBundlerWebpackPlugin = require('html-bundler-webpack-plugin');
module.exports = {
entry: 'script.js',
plugins: [
new HtmlBundlerWebpackPlugin({
integrity: true,
})
],
output: {
crossOriginLoading: 'anonymous'
}
}
// also fails with passing the option `entry: { "script.js": "script.js" }` to HtmlBundlerWebpackPlugin directly.
Environment
- OS: [macOS, Linux, Windows] linux
- version of Node.js: v20.11.1
- version of Webpack: 5.93.0
- version of the Plugin: 3.17.0
Additional context
Appreciation for the useful project
- [x] After the problem is resolved, do not forget to give a star ⭐
@davidmurdoch
This is not a bug, this is the feature.
The html bundler can handeln only script tags defined in a template.
The JS files defined in entry will be ignored or may works unexpected.
The integrity option makes a seance only for a generated HTML with script tags.
If you add a check to ensure hashes is not undefined it seems to work fine. If it's not supported at all the plugin should throw a specific error saying so.
Since a webpack config can be created to conditionally include entry points based on conditions/flags a user provides, I could see cases where someone would end up with a config that doesn't have an HTML files to compile, like in debugging (me, today), partial compilation (common in large projects and microservices), or an empty entry point directory specified via the directory feature (maybe it's generated from a boilerplate project and no HTML files have been created/needed).
Anyway, I think you should reconsider this plugin's lack of ability to be a complete "No Op" when it doesn't need to do any work. I don't think it should have errored in this case. ☺️
@davidmurdoch
Thanks for clarifying. You are right, I will add the checking for this use case.
@davidmurdoch the issue is fixed in the v3.17.2