Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[contenthash] doesn't match between the assets in hooks and emitted output #1638

Open
psimk opened this issue Apr 20, 2021 · 11 comments
Open

Comments

@psimk
Copy link

psimk commented Apr 20, 2021

Current behaviour 💣

When using the assetTags from the callback of alterAssetTags or alterAssetTagGroups hooks (didn't test other hooks), the contenthash portion of the asset filename differs from the contenthash of the same asset in the emitted output.

For example:

given filename: "bundle.[contenthash].js"

In alterAssetTags hook, assetTags.scripts[0].attributes.src evaluates to:
bundle.1817f49c37ed2ca083b2.js

whereas in the final output and also the emitted index.html it is:
bundle.2e55dea7e3e197f9902d.js

Expected behaviour ☀️

The content hashes in the hooks filename and in the emitted output should be the same.

Reproduction Example 👾

https://github.com/psimk/html-plugin-contenthash-reproducible

Environment 🖥

  • Node.js v14.16.0
  • OS: linux 5.4.0-72-generic
  • NPM 6.14.11
  • Webpack 5.34.0
  • HTMLWebpackPlugin 5.3.1
@codeonquer
Copy link

codeonquer commented Apr 27, 2021

the same error

  • "html-webpack-plugin":"5.3.1"
  • "webpack": "5.31.2"

@codeonquer
Copy link

[Forget my poor English!]

Hi,I have tried to find out where is the problem. Then I find that the orders between html-webpack-plugin and webpack/optimize/RealContentHashPlugin may be the key.

html-webpack-plugin gets contenthash-A. Then html-webpack-plugin uses it to generate html, passes it by hooks (beforeAssetTagGeneration ... beforeEmit) to us. Finnaly html-webpack-plugin sends html to webpack.

After html is sent, webpack uses RealContentHashPlugin to update contenthash and gets contenthash-B. webpack updates html with new contenthash-B.

So we get contenthash-A. But html uses correct contenthash-B for assets.

@psimk @jantimon

@hamid814
Copy link

hamid814 commented May 2, 2021

@codeonquer

it seems you know the problem, what is the solution?

@codeonquer
Copy link

codeonquer commented May 3, 2021

@codeonquer

it seems you know the problem, what is the solution?

In my case, i need contenthash to generate new file for some reason, so i send my content to webpack too, like:

compilation.emitAsset(`${outputFilename}`, new webpack.sources.RawSource(`${content}`, false), {});

webpack updates correct contenthash automatically.

if i just want to know the correct contenthash, i mabye use compiler.hooks.done.

This is my solution for now. I hope it can help you.

@rodlukas
Copy link

rodlukas commented Sep 5, 2021

I also have this kind of problem with just html-webpack-plugin and html-webpack-harddisk-plugin and with webpack config output.filename: "[name].[contenthash:8].js". The contenthash in a html file that is created by the html-webpack-harddisk-plugin is different (wrong) than the final contenthash that is created by webpack. Thanks to @codeonquer I finally got what's going on.

Temporary solution for me is to disable realContentHash in webpack config:

optimization: {
        // other config ...
        realContentHash: false,
    },

See https://webpack.js.org/configuration/optimization/#optimizationrealcontenthash and https://webpack.js.org/plugins/internal-plugins/#realcontenthashplugin for more info:

Adds an additional hash compilation pass after the assets have been processed to get the correct asset content hashes. If realContentHash is set to false, internal data is used to calculate the hash and it can change when assets are identical.

@jantimon is there any chance for a fix of this behaviour please?

@nikhilnayyar002
Copy link

Hi am using:

    "html-loader": "^2.1.2",
    "html-webpack-plugin": "^5.3.2",

html file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>React Min</title>
  </head>

  <body>
    <div id="root"></div>
    <script src="script.file.js"></script>
  </body>
</html>

As one can see there is a custom script added. So it requires html-loader for parsing right! I was running in same issue : "The hash in index.html was different then that of generated file."

webpack config:

    mode: 'production',
    output: {
        filename: '[name].[contenthash].js',
        chunkFilename: '[id].[contenthash].js',
        assetModuleFilename: `assets/[name].[contenthash].[ext]`,
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                include: path.resolve(__dirname, "src"),
                use: [{
                    loader: 'babel-loader',
                }]
            },
            {
                test: /\.html$/i,
                use: [{ loader: 'html-loader' }]
            }

as mentioned by @rodlukas, setting realContentHash to false worked:

    optimization: {
        realContentHash: false,

generated index.html file

<!doctype html>
<html lang="en">
<head>
...
</head>
<body>
  <div id="root"></div>
  <script src="/assets/script.file.a4b0e773e61e7afa29f5..js"></script>
  ... /* bundles */
</body>
</html>

apepper added a commit to Scrivito/scrivito_example_app_js that referenced this issue Jan 27, 2022
Previously css changes where only visible after a manual refresh of the page - quite annoying. Now css is automatically refreshed on save - similar to js.

It looks like, that this is actually an issue of "html-webpack-plugin" with "contenthash". See jantimon/html-webpack-plugin#1638 . This is more a workaround than an actual fix.
gorgos pushed a commit to gorgos/soliditydeveloper that referenced this issue Feb 5, 2022
Previously css changes where only visible after a manual refresh of the page - quite annoying. Now css is automatically refreshed on save - similar to js.

It looks like, that this is actually an issue of "html-webpack-plugin" with "contenthash". See jantimon/html-webpack-plugin#1638 . This is more a workaround than an actual fix.
@stale
Copy link

stale bot commented Apr 16, 2022

This issue had no activity for at least half a year. It's subject to automatic issue closing if there is no activity in the next 15 days.

@stale stale bot added the wontfix label Apr 16, 2022
@apepper
Copy link

apepper commented Apr 19, 2022

If I'm not mistaken, this issue is still relevant.

@stale stale bot removed the wontfix label Apr 19, 2022
@rodlukas
Copy link

yes! the issue is still relevant since there was no commit that would fix the behaviour

@g3tr1ght
Copy link

g3tr1ght commented Dec 28, 2022

I had to wrestle with the same as we needed to create double-bundle (one for ES6-and-up browsers and one for ES5-and-down browsers) and inject in a single html file, so ended up creating my own plugin on top of html-webpack-plugin. Our use-case wasn't trivial so it won't fit your use-cases most likely.

TLDR;
There is a bit of a disconnect (from what I can see) between webpack maintaners and @jantimon, so things aren't quite as we (consumers) might expect and one would need to dig quite deep into the weeds of webpack and html-webpack-plugin implementation details to understand what's going on and rewrite pieces that don't fit into a particular use-case. While html-webpack-plugin basic use-case is trivial, it is maybe trying to do too much outside of a basic use-case, something that better to leave to webpack itself, that's what I'm personally deducing (and my opinion does not necessarily represent reality). And I must admit that it is not possible for a tool to cover all possible use-cases (something like double-bundle), but something as obvious as real content hash must be supported (in my opinion) because we don't want a change in our source files formatting/comments to result in a chunk/entrypoint removal from all caches.
See webpack/webpack#11822 for some highlights.

To improve things, webpack maintainers (@alexander-akait) suggest to move html-webpack-plugin over to webpack-contrib, which (from what I can see) @jantimon doesn't want to.
See:
webpack/webpack#16399 (comment)
webpack/webpack#16312 (comment)
webpack/webpack#13275 (comment)

Issues backlog in this repo hints me that html-webpack-plugin is not being actively maintained so I'm not sure about its future and better alternatives. We're using NX on some of our projects and next.js on others, they provide their own custom way of injecting assets into html; there's also other (than webpack) "bleeding edge (as always)" bundlers, nothing is more stable in JS world than community shift towards yet another hyped library, so it's hard to recommend anything.

My personal take - I'd rather see webpack and html-webpack-plugin evolving and community focusing on them, rather than jumping on another hype train, as they are fundamental web tools for me.

@hangaoke1
Copy link

hangaoke1 commented Jan 5, 2023

Is there any progress on this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants