Skip to content
New issue

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

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

Already on GitHub? # to your account

Missing assets after recompilation in development #1709

Closed
vhiairrassary opened this issue Dec 4, 2021 · 12 comments
Closed

Missing assets after recompilation in development #1709

vhiairrassary opened this issue Dec 4, 2021 · 12 comments

Comments

@vhiairrassary
Copy link

vhiairrassary commented Dec 4, 2021

Current behaviour 💣

I am writting a plugin to process assets produced by webpack:

class TestPlugin {
    apply(compiler) {
        compiler.hooks.thisCompilation.tap({ name: this.constructor.name }, (compilation) => {
            return compilation.hooks.processAssets.tap(
                { name: this.constructor.name, stage: Compilation.PROCESS_ASSETS_STAGE_ANALYSE, },
                (assets) => {
                    console.log(`******Assets: ${JSON.stringify(Object.keys(assets))}`)
                }
            );
        });
    }
}

My index.ejs requires external resources (such as an image for the favicon). When compiling in production mode I have the correct list of assets. Same for the first compilation in development using webpack-dev-server. But when recompiling due to a change in a file outside of index.ejs and associated required resources then this resources are not part of the assets list.

It is expected? (I am observing similar issue with webpack-manifest-plugin, instead of my own custom plugin, which makes me think issue is in html-webpack-plugin. Also, reproduction example shows the bug is present for both file-loader and asset/resource methods.

Reproduction Example 👾

https://github.com/vhiairrassary/html-webpack-plugin-asset-bug

Launch webpack with ./node_modules/.bin/webpack serve --mode development (all files are correctly emitted):

<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:8080/
<i> [webpack-dev-server] On Your Network (IPv4): http://192.168.1.13:8080/
<i> [webpack-dev-server] On Your Network (IPv6): http://[fe80::1]:8080/
<i> [webpack-dev-server] Content not from webpack is served from '/vhiairrassary/html-webpack-plugin-asset-bug/public' directory
******Assets: ["2.aaa","2.bbb","1.aaa","main.js","1.bbb","index.html"]
assets by path *.aaa 10 bytes
  asset 1.aaa 5 bytes [emitted] [from: src/1.aaa] (auxiliary name: main)
  asset 2.aaa 5 bytes [emitted] [from: src/2.aaa]
assets by path *.bbb 10 bytes
  asset 1.bbb 5 bytes [emitted] [from: src/1.bbb] (auxiliary name: main)
  asset 2.bbb 5 bytes [emitted] [from: src/2.bbb]
asset main.js 288 KiB [emitted] (name: main)
asset index.html 197 bytes [emitted]
webpack 5.64.4 compiled successfully in 362 ms

Modify string in console.log from src/index.js to trigger re-compilation (index.html is part of emitted assets but
not the files required inside
index.ejs: 2.aaa and 2.bbb):

******Assets: ["1.aaa","main.js","1.bbb","main.0d89c78503f6f63d1cb3.hot-update.js","main.0d89c78503f6f63d1cb3.hot-update.json","index.html"]
assets by status 10 bytes [cached] 2 assets
assets by status 289 KiB [emitted]
  assets by path *.js 289 KiB
    asset main.js 288 KiB [emitted] (name: main)
    asset main.0d89c78503f6f63d1cb3.hot-update.js 1.25 KiB [emitted] [immutable] [hmr] (name: main)
  asset index.html 197 bytes [emitted]
  asset main.0d89c78503f6f63d1cb3.hot-update.json 28 bytes [emitted] [immutable] [hmr]
Entrypoint main 289 KiB (10 bytes) = main.js 288 KiB main.0d89c78503f6f63d1cb3.hot-update.js 1.25 KiB 2 auxiliary assets
webpack 5.64.4 compiled successfully in 37 ms

Modify index.ejs (this time all files are correctly emitted):

******Assets: ["2.aaa","2.bbb","1.aaa","main.js","1.bbb","main.b2aa31b3b119299d831d.hot-update.js","main.b2aa31b3b119299d831d.hot-update.json","index.html"]
assets by status 20 bytes [cached] 4 assets
assets by status 289 KiB [emitted]
  assets by path *.js 288 KiB
    asset main.js 288 KiB [emitted] (name: main)
    asset main.b2aa31b3b119299d831d.hot-update.js 872 bytes [emitted] [immutable] [hmr] (name: main)
  asset index.html 201 bytes [emitted]
  asset main.b2aa31b3b119299d831d.hot-update.json 28 bytes [emitted] [immutable] [hmr]
Entrypoint main 288 KiB (10 bytes) = main.js 288 KiB main.b2aa31b3b119299d831d.hot-update.js 872 bytes 2 auxiliary assets
webpack 5.64.4 compiled successfully in 52 ms
@vhiairrassary
Copy link
Author

Changing CachedChildCompilation.isCacheValid implementation to return Promise.resolve(false); fixes the issue. Could you tell me if you consider the bug report to valid valid, i.e. it is valid to call require in html template? If yes, I could have a try to fix the issue.

Example of template (with the following rule: { test: /\.aaa$/i, use: 'file-loader' }):

<!DOCTYPE HTML>
<html lang="en">
  <body>
    <%= require('./2.aaa').default %>
  </body>
</html>

Also, I am not using the favicon option (always emitted in getFaviconPublicPath, see below) as I have other resources than favicon listed in my template (such as Web app manifests and other images).

function getFaviconPublicPath (faviconFilePath, compilation, publicPath) {
if (!faviconFilePath) {
return Promise.resolve(undefined);
}
return addFileToAssets(faviconFilePath, compilation)
.then((faviconName) => {
const faviconPath = publicPath + faviconName;
if (options.hash) {
return appendHash(faviconPath, compilation.hash);
}
return faviconPath;
});
}

@vhiairrassary
Copy link
Author

Monkey patch:

diff --git a/lib/cached-child-compiler.js b/lib/cached-child-compiler.js
index ad5b67e0b21b26cf64aaf831ff9df05d4e3392a8..aea5d0bb0ffa0ca78c315dc2169b49d483d930dc 100644
--- a/lib/cached-child-compiler.js
+++ b/lib/cached-child-compiler.js
@@ -313,22 +313,8 @@ class PersistentChildCompilerSingletonPlugin {
    * @returns {Promise<boolean>}
    */
   isCacheValid (snapshot, mainCompilation) {
-    if (!this.compilationState.isVerifyingCache) {
-      return Promise.reject(new Error('Cache validation can only be done right before the compilation starts'));
-    }
-    // If there are no entries we don't need a new child compilation
-    if (this.compilationState.entries.length === 0) {
-      return Promise.resolve(true);
-    }
-    // If there are new entries the cache is invalid
-    if (this.compilationState.entries !== this.compilationState.previousEntries) {
-      return Promise.resolve(false);
-    }
-    // Mark the cache as invalid if there is no snapshot
-    if (!snapshot) {
-      return Promise.resolve(false);
-    }
-    return fileWatcherApi.isSnapShotValid(snapshot, mainCompilation);
+    // https://github.com/jantimon/html-webpack-plugin/issues/1709
+    return Promise.resolve(false);
   }

   /**

@fretfan
Copy link

fretfan commented Jan 23, 2022

I have similar problem with image assets used in index.html via HtmlWebpackPlugin. Production build and first execution of watch is OK, but as soon as I modify any JS file - images disapper from dist folder. If I modify index.html - images reappear in dist folder again. Tried on both windows 10 and ubuntu 20.04 with node@14.16.

To reproduce try this: https://github.com/fretfan/image-watch-bug

It was happening occasionlaly with older versions of webpack and HtmlWebpackPlugin. I was assuming, I was accesing resources faster then rebuild was complete. Changing some random JS file was nudging webpack to generate missing image asset and it was fine for some time.

Now with the newest version of webpack and HtmlWebpackPlugin - this bug became consistent on second watch/reload.
Adding dummy import './images/one.png' ,without actual use, is a workaround

@fretfan
Copy link

fretfan commented Feb 11, 2022

@jantimon, any news?

@Ashley2014
Copy link

@fretfan I have this issue exectly like you discribe, with "webpack": "^5.65.0","webpack-dev-server": "^4.7.2", "html-webpack-plugin": "^5.5.0",

@spreadpando
Copy link

Same
"webpack": "^5.70.0",
"webpack-dev-server": "^4.6.0",
"html-webpack-plugin": "^5.5.0",

@spl33t
Copy link

spl33t commented Jun 22, 2022

i have this bug on:
"html-webpack-plugin": "^5.5.0",
"webpack": "^5.73.0",

@buneeIsSlo
Copy link

Looks like this is still the case.
"html-webpack-plugin": "^5.5.0",
"webpack": "^5.74.0"

@scorbiclife
Copy link

For those who came here from a google search, setting up ouptut.clean: true is one of the workarounds.

Credit goes to https://stackoverflow.com/questions/72498866/webpack-images-disappear-after-browser-refresh-using-webpack-dev-server

@Kitketovsky
Copy link

For those who came here from a google search, setting up ouptut.clean: true is one of the workarounds.

Credit goes to https://stackoverflow.com/questions/72498866/webpack-images-disappear-after-browser-refresh-using-webpack-dev-server

But after changes and recompilations hashed js files stack too much which is unnessary. clear: false works, but it just for some time.

@alexander-akait
Copy link
Collaborator

Yeah, it is a bug, we want to fix it, let's close in favor of #1639, because it is the same, sorry for long answer

Repository owner deleted a comment from webdiscus Jun 19, 2023
@alexander-akait
Copy link
Collaborator

Fixed in main, release will be soon

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

No branches or pull requests

9 participants