文件加载器在 dist 文件夹的根目录中创建额外的文件

file-loader creating extra file in root of dist folder

我正在使用文件加载器 6.2 将静态图像文件复制到我的 dist 目标中的图像文件夹中,使用以下配置一切正常(即 svg 从我的 src 文件夹复制到 dist/images ):

    test: /\.(png|jpe?g|gif|svg)$/i,
    loader: 'file-loader',
    options: {
      name: '[name].[ext]',
      outputPath: 'images',
      publicPath: 'images',
    },

但是,除了复制静态文件外,它还会在 dist 文件夹的根目录中创建另一个引用该静态文件的文件 - 例如,当我复制一个名为 loading.svg 的文件时,它会创建该文件以及具有随机哈希值的文件(例如 817e56ed349aea52edfa.svg)

在这个文件中,它只是引用了另一个文件:

export default "images/loading.svg";

如果我随后检查我编译的 sass,我可以看到它引用了哈希文件而不是复制到图像文件夹中的资产。

background: url(../817e56ed349aea52edfa.svg) center center no-repeat; 

如何停止创建额外的文件,以便它只直接创建和引用图像文件夹中的图像?

附带说明一下,我尝试将文件加载器替换为复制 webpack 插件,这也将文件复制到图像文件夹中,但在那种情况下,它没有引用该文件,而是还创建了一个散列版本根目录中的 svg(但包含实际的 svg 内容而不是 webpack 导出)并引用它 - 所以可能是其他原因导致了这个问题?我在下面包含完整的 webpack 配置,以防任何人发现任何明显的问题或其他原因导致的问题

完整的 webpack 配置

const paths = require("./webpack.paths");
const { VueLoaderPlugin } = require('vue-loader');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require("terser-webpack-plugin");

const isProduction = (process.env.NODE_ENV === 'production');
if (isProduction) {
  console.log("Bundling in PRODUCTION mode")
} else {
  console.log("Bundling in DEVELOPMENT mode")
}

module.exports = {
  entry: {
    styles: paths.styles,
    home: './vue/templates/home/main.js',
  },
  mode: isProduction ? 'production' : 'development',
  output: {
    path: paths.dist,
    filename: 'js/[name].js'
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
      },
      {
        test: /\.(css|scss)$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            // Use the css-loader to parse and minify CSS imports.
            loader: 'css-loader',
            options: { sourceMap: true }
          },
          {
            // Use the postcss-loader to add vendor prefixes via autoprefixer.
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                config: paths.postcssConfig,
              },
              sourceMap: true
            }
          },
          {
            // Use the sass-loader to parse and minify CSS imports.
            loader: 'sass-loader',
            options: { sourceMap: true }
          },
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/i,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]',
          outputPath: 'images',
          publicPath: 'images',
        },
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              ['@babel/preset-env', { targets: "defaults" }],
            ]
          }
        },
      },
    ]
  },
  devServer: {
    hot: true,
    noInfo: true,
    overlay: true,
    contentBase: [paths.root],
  },
  plugins: [
    new VueLoaderPlugin(),
    new MiniCssExtractPlugin({
      filename: 'css/[name].css'
    }),
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: [
        `${paths.dist}/css/*`,
        `${paths.dist}/images/*`,
        `${paths.dist}/js/*`,
      ],
    }),
    new ESLintPlugin({
      extensions: ['vue', 'js'],
    })
  ],
  optimization: {
    minimize: isProduction,
    minimizer: [
      new TerserPlugin(),
    ],
    runtimeChunk: 'single',
    splitChunks: {
      minSize: 0,
      cacheGroups: {
        vendor: {
          name: 'vendor',
          chunks: 'all',
          test: /[\/]node_modules[\/]/,
          priority: 10,
          enforce: true
        }
      }
    }
  }
}

if (isProduction) {
  module.exports.plugins = (module.exports.plugins || []).concat([
    new CompressionWebpackPlugin(),
  ])
}

最后看起来好像是 css 加载器导致了这个问题 - 所以我将它配置为忽略 url,然后从 file-loader 插件更改为 copy-webpack-plugin复制图像:

使用 css 加载程序忽略 url

      MiniCssExtractPlugin.loader,
      {
        // Use the css-loader to parse and minify CSS imports.
        loader: 'css-loader',
        options: {
          sourceMap: true,
          url: false,
        }
      },

复制webpack插件复制图片

const CopyPlugin = require("copy-webpack-plugin");

plugins: [
  new CopyPlugin({
    patterns: [
      {
        from: 'vue/images', // src location
        to: 'images',       // destination location in dist folder
      },
    ],
    options: {
      concurrency: 100,
    },
  }),
]

然后在我的 css 中,我可以将图像作为相对图像从 dist 文件夹 css 引用到 dist 文件夹图像文件夹:

background-image: url(../images/loading.svg);

对我来说似乎有点奇怪,我必须这样做才能不获取额外的 svg 文件,所以如果有人想出更好的解决方案或知道如何不创建额外的文件,请随意回答