shou2017.com
JP

All About Webpack Image Bundling

Wed Mar 4, 2020
Sat Aug 10, 2024

There are two ways to bundle image files with webpack:

  • Converting image files to Data URLs
    • Use this for small images that appear in large numbers
    • Example: Icons, etc.
  • Simply managing image file paths
    • Use this for large image files that are fewer in number
    • Example: Background images, etc.

Converting Image Files to Data URLs

You can use url-loader to convert image files to Data URLs and include them as part of your .js file.

Installation:

$ npm install --save-dev webpack webpack-cli url-loader

webpack.config.js configuration:

<!-- webpack.config.js -->

module.exports = {
    entry: './src/index.js',
    output: {
        path: `${__dirname}/public`,
        filename: 'main.js'
    },
    devServer: {
        contentBase: `${__dirname}/public`,
    },
    module: {
        rules: [
            {
                test: /\.(gif|png|jpg)$/,
                loader: 'url-loader'
            }
        ],
    }
};

Since url-loader is often used for icons, you can import the images in index.js as shown below and specify them in SASS:

<!-- index.js -->

import './assets/images/logo.svg';

When using in SASS, simply write:

account-icon::after {
    background-image: url("../images/logo.svg")
}

For outputting images with JavaScript, it’s easier to understand by looking at the code, like this:

// Logo
import logo from './assets/images/logo.svg';
window.addEventListener('DOMContentLoaded', function () {
    const headerLogo = document.createElement('img');
    headerLogo.src = logo;
    headerLogo.alt = 'logo';
    siteHeader.appendChild(headerLogo);
})

Simply Managing Image File Paths

file-loader is a loader that maintains references to external files without bundling them.

Installation:

$ npm install --save-dev webpack webpack-cli file-loader

webpack.config.js configuration:

<!-- webpack.config.js -->

module.exports = {
    entry: './src/index.js',
    output: {
        path: `${__dirname}/public`,
        filename: 'main.js'
    },
    devServer: {
        contentBase: `${__dirname}/public`,
    },
    module: {
        rules: [
            {
                test: /\.(png|jpe?g|gif)$/i,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            limit: 51200,
                            name: '../images/[name].[ext]'
                        }
                    }
                ]
            }
        ],
    }
};

Under the options parameter, the limit parameter (in bytes) determines whether a file should be converted to Data URL format or remain as a file. In the example above, if the image size is larger than 50KB, it will be output as a file with a name like ../images/[name].[ext].

  • path: Path to the resource
  • name: Base name of the original file
  • ext: Extension of the original file
  • hash: Hash value based on the data content

The reference method is the same as with url-loader.

<!-- index.js -->

import './assets/images/backgroudimage.jpg';

In SASS, just write:

background-image: url("../images/backgroudimage.jpg");

File Output for Images Exceeding the Threshold

For example:

To convert images smaller than 50KB to Data URLs and output larger ones as files, simply configure the options:

module: {
    rules: [
        {
            test: /\.(svg|png|jpe?g)$/,
            loader: 'url-loader',
            options: {
                limit: 51200,
                name: '../images/[name].[ext]'
            }
        }
    ],
}
See Also