Webpack文件加载器重复文件

11
我正在使用webpack以及它的file-loader + html-loader将文件传送到我的输出目录。它几乎达到了预期效果,但也会复制这些文件。
以下是我的webpack.config.js文件的一部分:
module.exports = {
   module: {
      rules: [
         { test: /\.html$/, use: ["html-loader"] },
         {
            test: /\.(jpg|png)$/,
            use: {
               loader: "file-loader",
               options: {
                  name: "[name].[ext]",
                  outputPath: "img",
               },
            },
         },
      ],
   },
};

这是一个我输出目录的小例子:

dist/
- img/
   - img1.png
   - img2.png
- ab0d12.png
- c3d612.png
- index.html
- bundle.js

{{两个带哈希名称的图像是img目录中那些不需要的重复文件。正如上面的例子所示,我甚至没有设置名称为哈希值,也无法以任何方式打开重复的文件。}}
{{我使用了一些插件,例如HtmlWebpackPlugin或CleanWebpackPlugin,但我认为它们并不是造成问题的原因。}} 版本:
  • webpack 5.28.0
  • file-loader 6.2.0
  • html-loader 2.1.2

你能展示一下导入这些图片的 .html 或 .js 文件吗?在打包之前,img1.pngimg2.png 存储在哪里? - superhawk610
@superhawk610 图像存储在 src/ 目录下的 img/ 目录中。我使用 src 属性导入它们:<img src="./img/img1.png"> - Daweed
3个回答

13
经过漫长的搜寻,我找到了一个看起来和我的问题非常相似的SO问题,然而,文件重复的原因不同。
在版本5中,webpack引入了Asset Modules作为raw-loaderurl-loaderfile-loader的替代品,并且现在默认情况下执行:

Asset Modules是一种模块类型,允许使用资源文件(字体、图标等)而无需配置额外的加载器。

每次webpack开始打包项目时,asset/resourcefile-loader同时运行,导致重复。
最终,我只需要从webpack.config.js文件中移除file-loader并将output.assetModuleFilename设置为我想要的输出目录即可解决问题。

我本来也想问同样的问题,后来发现了你的提问。谢谢! - Victor Zakharov
是的,那是正确的答案。我也遇到了同样的问题,谢谢兄弟。 - mod7ex
这是与编程有关的内容。 - rttmax
1
你能否分享一下你的Webpack配置文件,以便更好地理解吗?我有些困惑。 - Himanshu Singh

0

webpack.prod.js(开发配置不需要压缩图像)

...
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使用资产模块类型取代了所有这些加载器, 并且使用image-minimizer-webpack-plugin来压缩图片


虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。 - Mousam Singh
配置示例已添加 @Mousam Singh - LinTao

0

就像 @Daweed 已经解释过的那样,文件会被处理两次: 一次是由文件加载器(file-loader)处理,另一次是由资源模块(asset module)处理。

如果由于某种原因你还没有准备好迁移到资源模块,你可以通过添加

type: 'javascript/auto'

到文件加载器中来禁用资源模块的处理,如文档所述:

[...] 你可能希望停止资源模块再次处理你的资源,以避免资源重复。这可以通过将资源的模块类型设置为 'javascript/auto' 来实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接