Arhitector
Arhitector

Reputation: 41

Webp images doesn't render correct

I have the problem with webpack build webp images. There is SSR react project. Example of react code:

import slotroulette from './slotroulette.png';
import slotrouletteWebp from './slotroulette.webp';

...

  return (
    ...
        <picture>
          <source srcSet={slotrouletteWebp} type="image/webp" />
          <img
            css={{ width: '200px' }}
            src={slotroulette}
            alt="slot-roulette"
          />
        </picture>
    ...
    )
  );
};

Example webpack config file:

{
    test: /\.(jpe?g|gif|svg|ico|png)$/,
    use: [
      {
        loader: 'file-loader',
        options: {
          hash: 'sha512',
          digest: 'hex',
          publicPath: `${CDN_HOST}/pub/`,
          outputPath: 'pub/',
          name: '[hash].[ext]',
        },
      },
      {
        loader: 'image-webpack-loader',
        query: {
          mozjpeg: {
            progressive: true,
          },
          gifsicle: {
            interlaced: false,
          },
          svgo: {
            plugins: [
              {
                removeViewBox: false,
              },
            ],
          },
          webp: {
            quality: 80,
          },
        },
      },
    ],
  },

In this case i have next error:

ERROR in .../slotroulette.webp
Module parse failed: Unexpected character '' (1:6)
You may need an appropriate loader to handle this file type.

In case I add 'webp' to the 'test'( test: /.(jpe?g|gif|svg|ico|png|webp)$/,) I will get next problem webpack convert webp to png that can't be opened.

Upvotes: 1

Views: 3925

Answers (1)

Christian4423
Christian4423

Reputation: 1796

This is how I formatted my jsx.

JSX

<picture>
    <source srcSet={`${baseUrl.public}img/rsgis-logo.webp`} type="image/webp" />
    <source srcSet={`${baseUrl.public}img/rsgis-logo.png`} type="image/png" />
    <img src={`${baseUrl.public}img/rsgis-logo.png`} className="rsgis-logo" alt="RS&amp;GIS Logo" />
</picture>

Webpack

I did my webpack a little different. The webp-loader worked well for me except for the fact that it did not transfer the png to the output directory.

With the webp-loader:

loaders: [
  {
    test: /\.(jpe?g|png)$/i,
    loaders: [
      'file-loader',
      'webp-loader?{quality: 80}'
    ]
  }
]

The webp-loader will convert the images into the webp format. Then place the images in the output/img directory (I didn't specify the output location above as I dont have the code on my person right now)

Then to get the pngs to the output directory, I used the webpack plugin CopyWebpackPlugin. This takes a directory and places it in the output directory.

plugins: [
    ...,
    new CopyWebpackPlugin([
        { from: "./src/images/png", to: "./img" }
    ]),
    ...
],

After I did this implementation, I decided to do the reverse. I did not like the web-loader. I ended up converting my images via CLI using the webp tool and used the CopyWebpackPlugin to move the webp files to the output directory. I then had webpack process my images normally using the file-loader

{
    test: /\.(svg|gif|jpe?g|png)$/i,
    use: [{
        loader: "file-loader",
        options: {
            name: "/img/[name].[ext]"
        }
    }]
},
plugins: [
    ...,
    new CopyWebpackPlugin([
        { from: "./src/images/webp", to: "./img" }
    ]),
    ...
],

Hopefully this helps a little!

Upvotes: 1

Related Questions