webdiscus / html-bundler-webpack-plugin

Alternative to html-webpack-plugin ✅ Renders Eta, EJS, Handlebars, Nunjucks, Pug, Twig templates "out of the box" ✅ Resolves source files of scripts, styles, images in HTML ✅ Uses a template as entry point
ISC License
146 stars 15 forks source link

Using `integrity: true` with `HtmlWebpackPlugin` _without_ an HTML entry fails #107

Closed davidmurdoch closed 3 months ago

davidmurdoch commented 3 months ago

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

Additional context

Appreciation for the useful project

webdiscus commented 3 months ago

@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.

davidmurdoch commented 3 months ago

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. ☺️

webdiscus commented 3 months ago

@davidmurdoch

Thanks for clarifying. You are right, I will add the checking for this use case.

webdiscus commented 3 months ago

@davidmurdoch the issue is fixed in the v3.17.2