webpack-contrib / file-loader

File Loader
MIT License
1.86k stars 257 forks source link

Same asset doesn't get rebuild after first build #352

Closed b13nxx closed 4 years ago

b13nxx commented 4 years ago

Expected Behavior

Rebuild logo.svg after first build

Actual Behavior

Doesn't rebuild after first build of logo.svg

Folder Structure

Let say we have something similar to this:

-src
--img
---logo.svg
---logo.png
-App.tsx

Code

Our webpack.config.js includes this section:

// webpack.config.js
...
{
  test: /\.(png|jpe?g|gif|svg|ico|icns)$/,
  exclude: path.resolve(__dirname, "./node_modules"),
  loader: "file-loader",
  options: {
    name: "[path][name].[ext]"
  }
}
...

How Do We Reproduce?

[Step 1] Just include one image in your React app:

// App.tsx
import logo from "./src/img/logo.svg";

const App: React.FC = () => {
  return (
    <div className="App">
      <img src={logo} className="App-logo" alt="logo" />
      Hello to React World
    </div>
  );
};

export default App;

[Step 2] Then build with webpack --watch.

First build will be successful and you'll see logo.svg in dist folder (lets assume output folder for webpack).

[Step 3] Then change image:

// App.tsx
-import logo from "./src/img/logo.svg";
+import logo from "./src/img/logo.png";

This time you'll see logo.png in dist folder (which is obviously right).

[Step 4] But if you include same image again:

// App.tsx
-import logo from "./src/img/logo.png";
+import logo from "./src/img/logo.svg";

You will not see logo.svg in dist folder. It won't get rebuild.

Unnecessary Facts

  1. During example, we used clean-webpack-plugin. That's mean unnecessary assets get removed after build (and every rebuild).
  2. During example, we used TypeScript.
  3. This behavior was encountered within a larger project. But you can see same behavior in create-react-app with yarn eject and added writeToDisk: true for devServer option.
alexander-akait commented 4 years ago

Can you create reproducible test repo? Also try to disable clean-webpack-plugin

alexander-akait commented 4 years ago

Fixed in webpack@5, can't be fixed on loader side

dbowling commented 4 years ago

I ran into this same issue and clean-webpack-plugin was the cause. My images and fonts were blown away on the second run. I verified this was with the plugin by adding verbose: true, and fixed the issue by setting cleanStaleWebpackAssets: false.

My plugin now looks like:

new CleanWebpackPlugin({
            verbose: true,
            cleanStaleWebpackAssets: false
        }),

Upgrading to webpack@5 did not resolve the issue when this plugin was enabled.