'How to change path for output images in webpack 5?

I have some pictures in folder "src/assets/img/". I would like to keep the relative path to pictures.
Example: before -> after

Part of my webpack config:

const config = {
  entry: {
    app: './src/app.js',
  },

  output: {
    path: path.resolve(__dirname, './dist'),
    filename: '[name].js',
    assetModuleFilename: 'assets/[name][ext]',
    clean: true,
  },

  // ...
  module: {
    rules: [
      // ...
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        use: {
          loader: 'image-webpack-loader',
          options: {
            disable: !isProduction,
            mozjpeg: {
              progressive: true,
              quality: 80,
            },
            optipng: {
              optimizationLevel: 3,
            },
            pngquant: {
              quality: [0.7, 0.9],
              speed: 4,
            },
          },
        },
        type: 'asset/resource',
        generator: {
          filename: 'assets/img/[name][ext]',
        },
      },
    ],
  },
  // ...
};

But all folders inside are deleting -> like this
I'm sure it's about

generator: { 
  filename: 'assets/img/[name][ext]' 
}

But I didn't find anything



Solution 1:[1]

Maybe this will help you and others.

generator: {
  filename: ({ filename }) => {
    if (filename.includes('source')) {
      return filename.replace('source', 'dist');
    }
    if (filename.includes('node_modules')) {
      return filename.replace('node_modules', 'dist');
    }
    return filename;
  },
},

Solution 2:[2]

To set the path for different types of assets (for fonts, etc.), you need to add the 'asset/resource' type to the rules. And in the output add the assetModuleFilename field with the function. In this case, all assets will be saved to the same path as in the src folder:

// File: webpack.config.js

const config = {
  ...
  output: {
    ...
    assetModuleFilename: pathData => {
        const filepath = path.dirname(pathData.filename).split('/').slice(1).join('/');
        return `${filepath}/[name][ext]`;
    },
  },
  module: {
    ...
    rules: [
      ...
      {
        test: /\.(jpe?g|png|gif|svg|webp|avif|ico)$/i,
        type: "asset/resource",
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        type: "asset/resource",
      },
    ]
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 StasNemy
Solution 2 alexsoin