webpack-contrib / copy-webpack-plugin

Copy files and directories with webpack
MIT License
2.84k stars 283 forks source link

Plugin ignores --watch flag since v6 #497

Closed abriginets closed 4 years ago

abriginets commented 4 years ago

Hello. Recently I moved from 5.1.1 to 6 and now CopyWebpackPlugin ignores --watch flag and copy all files every time, but should copy only files that have been changed or added.

Expected Behavior

Plugin should copy only files that have been changed during the --watch mod

Actual Behavior

Plugin copies all files specified even if they were not changed and I made some changes to files that is not related to specified paths

Code

new CopyWebpackPlugin({
    patterns: [
        { from: path.resolve(`${PATHS.src}/img`), to: path.resolve(`${PATHS.assets}/img`) },
        { from: path.resolve(`${PATHS.src}/static`), to: PATHS.dist }
    ]
}),
alexander-akait commented 4 years ago

Hello. Recently I moved from 5.1.1 to 6 and now CopyWebpackPlugin ignores --watch flag and copy all files every time, but should copy only files that have been changed or added.

This is wrong behavior and we should keep persist assets between rebuilds, here changelog - https://github.com/webpack-contrib/copy-webpack-plugin/releases/tag/v6.0.0, webpack does not write assets if they exist and they content are same, therefore you should not worry

abriginets commented 4 years ago

@evilebottnawi I'm sorry to reopen this issue but it feels like I'm not going to resolve it alone. The main problem for me right now is that I have lots of images that have to be converted to webp format and for that purpose I'm using imagemin-webp-webpack-plugin. There is an issue in their repo saying that webp-plugin should not reconvert all the images after some changes been made to even non-related files, but I never faced that issue until I updated to v6 of CopyWebpackPlugin. It all started exactly since I updated CopyWebpackPlugin and if I remove its declaration from my webpack config, webp-plugin stops emitting all the images (and emits only those I change), which is where I'm getting really confused.

So my question is: aren't there some changes you did make to this plugin that can affect other plugins as well?

P.S. - I do understand that it's not your responsibility to handle bugfixes in third party software so you are free to close this issue without any comments, but It would be really appreciative from you to explain why this could happen and why removing CopyWebpackPlugin fixes behavior I described.

alexander-akait commented 4 years ago

@JamesJGoodwin

So my question is: aren't there some changes you did make to this plugin that can affect other plugins as well?

Implement persist assets between rebuilds solve a lot of problems with other plugins, like clean-webpack-plugin, now you can use minimizer (like terser-webpack-plugin) to compress copied JS files + a lot of other fixes

Two solutions for imagemin-webp-webpack-plugin

Both solutions are easy

janvennemann commented 4 years ago

@evilebottnawi i recently ran into similar issue after updating to v6. In https://github.com/webpack-contrib/copy-webpack-plugin/commit/57f3e618108c3a6c1f61f21186d69433ee51a561 the copyUnmodified option was removed. This works well with Webpack 5, however with Webpack 4 all assets are always emitted during a watch build.

Correct me if i'm wrong, but i guess this was done to fix issues with the clean-webpack-plugin which removed stale assets by default, right? I recently worked on another plugin which also needed to copy a bunch of files and i used the same approach as this plugin by using the additionalAssets hook. What i did to there to prevent emitting unchanged assets was to use the internal existsAt. Webpack will automatically set this and all that is needed to make it work is storing the complete asset object instead of the raw content so that the value of existsAt will be persisted between builds in watch mode. For assets that didn't change the assets object can be added the asset list again as is. That way Webpack doesn't emit unchanged assets again and clean-webpack-plugin should also be happy since the asset is in the list.

I'd be happy to work on a PR if you are open to restoring this behavior to Webpack 4.

alexander-akait commented 4 years ago

@janvennemann

This works well with Webpack 5, however with Webpack 4 all assets are always emitted during a watch build.

This is the expected behavior. By returning the option, we will again break other plugins. What exactly is the problem? Maybe you can demonstrate, for example - minimum reproducible test repo with simple README

janvennemann commented 4 years ago

@evilebottnawi I think there is a way to restore the behavior in Webpack 4 without breaking other plugins, but i need to verify. I'll get back to you with a PR or a test repo when i have some spare time to work on this.