webpack: Cache breaks asset module live reloading

Bug report

What is the current behavior? Live reloading breaks for assets using asset/resource rule type when caching is enabled.

If the current behavior is a bug, please provide the steps to reproduce.

Add an asset loader rule:

      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: "asset/resource",
      },

Import an asset

import React from "react";
import ReactDOM from "react-dom";
import logoSrc from "./assets/logo.png";

import "./styles.less";

const App = (): JSX.Element => (
  <div>
    <img src={logoSrc} alt="logo" />
    <div>Hello, React!</div>
  </div>
);

ReactDOM.render(<App />, document.getElementById("root"));

The initial page load works as expected. Commenting out the img and/or import, then reverting causes the image asset to be not found.

$ curl http://localhost:9009/assets/logo-ff7cf555f3ab2107e716.png
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /assets/logo-120x120@2x-ff7cf555f3ab2107e716.png</pre>
</body>
</html>

Disabling the cache “fixes” the issue

// webpack.config.js
module.exports = {
  ...
  cache: false,
  ...
}

It’s also not an issue when using asset/inline.

webpack.config.js

What is the expected behavior? I know “it should work” is not helpful, but it seems self explanatory here.

Other relevant information: webpack version: 5.36.1 Node.js version: 10.24.1 Operating System: OS X 10.14.6 Additional tools:

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 23 (18 by maintainers)

Most upvoted comments

thanks alex - sorry I had a long work day yesterday… let me take a look 😃

to summarise the issue to ensure we are on the same page:

  • index.html is depending on './images/photo.jpg
  • ✅ HtmlWebpackPlugin is emitting everything correctly
  • ✅ the user triggers a new compile
  • ✅ webpack clean deletes all assets
  • 🕷 HtmlWebpackPlugin is emitting only .html assets
  • 💣 the image is missing

Can we move this bug to the html-webpack-plugin issue tracker?

Maybe a short note on cache:true/false - the cache option was introduced long long time ago…
back then webpack would emit files again automatically.
basically it does the folloing

  • cache:false will execute the template (think of this.importModule) for every compilation to allow accessing the latest compilation object
  • cache:true will compile and execute only if the html entry file or one of its dependencies change

Caching is a tricky topic and 7 years ago when the html-webpack-plugin was created it was very difficult to have a good performance for child compiler especially without an entry point in webpack

I am happy for better caching ideas - or even better remove them if they are no longer needed…
Could you please try to explain what you mean by “use loader for cache you need just static function by developer”?
Do you mean the templateContent feature?

new HtmlWebpackPlugin({
  templateContent: ({htmlWebpackPlugin}) => `
    <html>
      <head>
        <title>Hello World</title>
      </head>
      <body>
        <h1>Hello World</h1>
      </body>
    </html>
  `
})

one challenge for caching was that some people use the HtmlWebpackPlugin to generate many many many files out of the same template e.g.:

new HtmlWebpackPlugin({
  filename: "[name].html"
})

Do you think we could solve all those cases with an additional Module? I am very happy if we can find a better caching logic… It adds a lot of complexity to the html-webpack-plugin

Please provide reproducible test repo

https://github.com/alexilin83/webpack_test_image

This should be fixed in the latest version