webpack-image-resize-loader icon indicating copy to clipboard operation
webpack-image-resize-loader copied to clipboard

Create thumbnail of original image

Open AlecRust opened this issue 3 years ago • 3 comments

I have a folder of "large" images e.g. src/img/photos/my-photo.jpg etc.

As-per webpack docs these are being copied to my dist folder using Asset Modules i.e.

{
  test: /\.(png|jpe?g|gif|svg|woff2?|ttf|eot)$/i,
  type: 'asset/resource',
  generator: {
    filename: '[name].[contenthash][ext]',
  },
}

I want to create 200x200px thumbnails i.e. "small" versions but also keep the "large" images being copied.

When I use webpack-image-resize-loader (or webpack-sharp-loader) in combination with either the Asset Modules approach as above or the old file-loader approach, the resulting "large" image is broken and cannot be opened.

It seems these loaders interfere with separate file handling I have. Any ideas for a solution to this?

AlecRust avatar Feb 06 '22 16:02 AlecRust

Thanks for letting me know, I'll take a look tomorrow

Calvin-LL avatar Feb 06 '22 22:02 Calvin-LL

I think the issue is in your Webpack config. It's important to note, that Asset Modules is a Webpack5 feature and the current version of this plugin was made for the old file-loader (Webpack4) technique to solve output file extension renaming after format conversion (see code). If you only want to use Asset Modules, I recommend you to read my compatibility workaround.

If your "large" image is "broken" I assume this is only because the output file extension doesn't match the real format/MIME of that image because with Asset Modules the [ext] placeholder holds the extension of the input file, not the one for the final, converted file.

If by default you only want to "copy" large images as-is (without any optimization), you should use Rule.oneOf with two items: The 1st with resourceQuery targeted for query params like format and/or width to do image processing with this loader (e.g. your thumbnails) and you can use the file-loader approach here if you want. The 2nd should be the default "copy only" part with your code above using Asset Modules.

Hope it helps.

szegheo avatar Feb 07 '22 08:02 szegheo

Many thanks @szegheo that helped clear some things up for me.

In the end I went with responsive-loader (seems to be compatible with webpack 5) with the following setup:

webpack.config.js

{
  test: /\.(svg|woff2?|ttf|eot)$/i,
  type: 'asset/resource',
  generator: {
    filename: '[name].[contenthash][ext]',
  }
},
{
  test: /\.(jpe?g|png)$/i,
  use: {
    loader: 'responsive-loader',
    options: {
      adapter: require('responsive-loader/sharp'),
      name: '[name].[contenthash]-[width].[ext]',
      format: 'webp'
    }
  }
}

src/index.html

<a href="<%= require('./img/example.png') %>">
  <img src="<%= require('./img/work/example.png?size=200') %>" />
</a>

AlecRust avatar Feb 12 '22 16:02 AlecRust