How to change path for output images in webpack 5?

Viewed 547

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

2 Answers

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;
  },
},

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",
      },
    ]
  }
}
Related