Reputation: 1432
I'm using webpack and it's file-loader + html-loader to emit files into my output directory. It works almost as expected, because it also duplicates those files.
Here is a part of my webpack.config.js
file:
module.exports = {
module: {
rules: [
{ test: /\.html$/, use: ["html-loader"] },
{
test: /\.(jpg|png)$/,
use: {
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "img",
},
},
},
],
},
};
There is a small example of how my output directory looks like:
dist/
- img/
- img1.png
- img2.png
- ab0d12.png
- c3d612.png
- index.html
- bundle.js
The two images with hashed names are unwanted duplicates of those in img/
directory. As you can see in the example above, I'm not even setting the name to be hashed and I also cannot open the duplicate files in any way.
I'm using some plugins like HtmlWebpackPlugin
or CleanWebpackPlugin
, but I believe they are not causing the problem.
Versions:
5.28.0
6.2.0
2.1.2
Upvotes: 11
Views: 3898
Reputation: 401
Like @Daweed already explained, the files are processed twice: Once by the file-loader and once by the asset module.
If for some reason you are not ready to migrate to asset modules, you can disable the asset module processing by adding
type: 'javascript/auto'
to the file-loader as mentioned in the documentation:
[...] you might want to stop Asset Module from processing your assets again as that would result in asset duplication. This can be done by setting asset's module type to 'javascript/auto'.
Upvotes: 0
Reputation: 48
webpack.prod.js (dev config does not need compress image)
...
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'assets/app.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
assetModuleFilename: 'img/[name][ext][query]' // dont use [hash] in name
},
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: "asset/resource"
}
],
},
plugins: [
new ImageMinimizerPlugin({
minimizerOptions: {
plugins: [
["mozjpeg", { quality: 60 }],
["pngquant", { quality: [0.6, 0.8] }],
],
},
})
]
};
webpack5 use Asset Modules type replaces all of these loaders, and with image-minimizer-webpack-plugin to compress images
Upvotes: 0
Reputation: 1432
After a long searching I came across this SO question that seemed very similar to mine, however, the cause of the file duplication were different.
In version 5, webpack introduced Asset Modules as a replacement for raw-loader
, url-loader
and file-loader
and which are now ran by default:
Asset Modules is a type of module that allows one to use asset files (fonts, icons, etc) without configuring additional loaders.
Every time webpack started bundeling my project, asset/resource
and file-loader
were running at the same time and resulted into duplication.
Eventually, all I had to do to fix my problem was to remove the file-loader
from the webpack.config.js
file and set a output.assetModuleFilename
to my desire output directory.
Upvotes: 14