@brigad/ideal-image-loader

A loader for webpack which handles 2x/3x/webp and works well with gatsby-image and react-ideal-image

Usage no npm install needed!

<script type="module">
  import brigadIdealImageLoader from 'https://cdn.skypack.dev/@brigad/ideal-image-loader';
</script>

README

@brigad/ideal-image-loader

🖼️ A loader for webpack which handles 2x/3x/webp and works well with gatsby-image and react-ideal-image

CircleCI version downloads MIT License All Contributors PRs Welcome Code of Conduct code style: prettier semantic-release Star on GitHub

Release article

Demo project

Installation

yarn add @brigad/ideal-image-loader

Or, if you are using npm:

npm install --save @brigad/ideal-image-loader

Usage

ideal-image-loader works like file-loader, but will also load @2x, @3x and .webp variations of the file.

// Will also try to resolve:
// - ./image@2x.png
// - ./image@3x.png
// - and try to generate:
// - ./image.webp
// - ./image@2x.webp
// - ./image@3x.webp
import img from './image.png';
// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|svg|gif)$/i,
        use: [
          {
            loader: '@brigad/ideal-image-loader',
            options: {
              name: 'images/[name].[ext]',
            },
          },
        ],
      },
    ],
  },
};
// output
// x1, x2 and x3 are different variations of the srcset (base, @2x and @3x)
// src is the location of the image, output of file-loader (https://github.com/webpack-contrib/file-loader)
// preSrc is a low quality placeholder, output of lqip.base64 (https://github.com/zouhir/lqip)
// palette is a palette of dominant colors, output of lqip.palette (https://github.com/zouhir/lqip)
// webp is the image converted to webp, if possible, output of imagemin-webp (https://github.com/imagemin/imagemin-webp)
{
  "x1": {
    "src": "https://....png",
    "preSrc": "data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhY...",
    "palette": [
      "#628792",
      "#bed4d5",
      "#5d4340",
      "#ba454d",
      "#c5dce4",
      "#551f24"
    ],
    "webp": "https://....webp"
  },
  "x2": {
    "src": "https://....png",
    "preSrc": "data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhY...",
    "palette": [
      "#628792",
      "#bed4d5",
      "#5d4340",
      "#ba454d",
      "#c5dce4",
      "#551f24"
    ],
    "webp": "https://....webp"
  },
  "x3": {
    "src": "https://....png",
    "preSrc": "data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhY...",
    "palette": [
      "#628792",
      "#bed4d5",
      "#5d4340",
      "#ba454d",
      "#c5dce4",
      "#551f24"
    ],
    "webp": "https://....webp"
  }
}

And run webpack via your preferred method.

A fully-working component example is available here (based on gatsby-image), feel free to copy it and to adapt it to your needs!

Problem

At Brigad, we have been looking for a solution to lazy-load images in a way that would feel good for the user and the developer. We also wanted our images to be as lightweight as possible for a given screen resolution. We tried to use gatsby-image (but without using Gatsby) and react-ideal-image, but we needed a loader to help us load our images without manually converting all of them to Webp, and manually importing each variation.

Solution

To solve the problems listed above, ideal-image-loader will, based on one imported image, resolve the @2x and @3x formats, and generate the .webp alternatives.

And the cherry on the top: it works seamlessly with gatsby-image without the need to use Gatsby, and also works with react-ideal-image!

Scroll down to learn more about the options! To learn more about the problem and solution, you can also read the release article.

Options

Recommended configuration:

const IS_PRODUCTION = process.env.NODE_ENV === 'production';

options: {
  name: 'images/[name].[hash].[ext]',
  base64: IS_PRODUCTION,
  webp: IS_PRODUCTION ? undefined : false,
  warnOnMissingSrcset: !IS_PRODUCTION,
},

This loader forwards all additional options (such as name) to file-loader.

base64

Type: boolean, Default: true

Specifies whether a low quality image placeholder (lqip) should be generated under the key preSrc.

This option allows to show a blurred placeholder while the image is loading.

For more information about the output, read lqip's documentation.

palette

Type: boolean, Default: false

Specifies whether a color palette should be generated under the key palette.

This option allows to show a color palette while the image is loading.

For more information about the output, read lqip's documentation.

webp

Type: object, Default: undefined

Specifies the configuration object passed to imagemin-webp to generate .webp images, under the key webp. undefined is the default configuration, null deactivates this feature, and any other option will be passed to imagemin-webp.

This option allows to load webp images (which are lighter than jpg and png) on browsers that support it.

For more information about the options and output, read imagemin-webp's documentation.

srcset

Type: boolean, Default: true

Specifies whether @2x and @3x images should be resolved, and new properties x2 and x3 should be put alongside x1.

This option allows to load the right resolution based on the user's screen.

warnOnMissingSrcset

Type: boolean, Default: false

Specifies whether the loader should warn when there are missing @2x and @3x images.

This option allows to make sure all your images have corresponding srcset.

Peer dependencies

Ideal-image-loader assumes you are using >=Node 6.9.0, Webpack >=4.0.0 and File-loader >=2.0.0.

Contributors

Thanks goes to these people (emoji key):


Adrien HARNAY

📝 💻 🎨 📖 💡 🤔

Thibault Malbranche

🤔

Aymeric Beaumet

💻

Cheng Gu

💻

This project follows the all-contributors specification. Contributions of any kind welcome!