Webpack Improves Integration with Image CDNs

Friday, April 3, 2020

webpack-dynamic-images

Webpack is, by a long shot, the most popular and widely adopted asset bundler and until very recently, it didn’t play nicely with projects leveraging Image CDNs for their image delivery. If you wanted to pass on special instructions for image processing along with the request, which is typically done by appending URL parameters to a source file path, you were out of luck: Webpack would strip them away from the resulting file path and there was no way to prevent this behavior using the provided API.

Webpack’s configuration problem

Most Image CDNs are usually pre-configured to deliver the most optimal experience for a website visitor’s specific environment (device type, compatibility, network conditions, and so on). There are still occasions, however, when you need to customize your images on-the-fly, perhaps in an effort to bring them to a common standard in a situation when you have limited control over the images. A good example of such a scenario is photos uploaded by users or pictures pulled from third-party sources. Adjustments are typically applied by appending URL parameters to a file path:

 <img src="./bread.png?imgeng=/w_300/f_webp" />

In the example above, based on ImageEngine’s directives, we instruct the Image CDN to resize our image to a specific width (300px) and convert it to a WebP format.

While this works in most cases (server-side rendering, in particular), you will likely hit a nasty snag in a single-page application (SPA) bundled by Webpack:

import cardBackground from './directory/card_bg.png?imgeng=/w_300/f_webp'

console.log(cardBackground)
// public/card_bg.some_hash.png

The query string gets dropped, and developers working on SPAs had, until now, no other choice but to resort to various workarounds to circumvent the limitation, ranging from using a custom image loader to relocating all their image assets to a `static` folder so they won’t be touched by Webpack.

Thankfully, `file-loader`, a ubiquitous plugin typically responsible for handling non-inlined images, recently got an upgrade with out-of-the-box query strings support.

No more inconvenient workarounds – just append a new `query` placeholder to the resulting file path in your configuration and you are all set:

module.exports = {
  output: {
    publicPath: 'xyz.cdn.imgeng.in',
  },
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[path][name].[ext][query]',
            },
          },
        ],
      },
    ],
  },
}

Looking forward

You might be keeping an eye on, or even using, Webpack’s experimental features might be wondering if the new built-in `asset modules` type (replacement for standalone loaders). The asset modules will indeed also support the new `query` placeholder. Start kicking the tires of both an ImageEngine and webpack today!