Customizing image bundling in webpack

Deborah Emeni

Developers can customize image bundling using Webpack, which provides asset modules for using files (containing the fonts and icons). This is done without configuring additional loaders like url-loader and file-loader. Before Asset modules came in existence, a developer would have to install and configure different asset loaders.

In this article, you will learn about asset modules in webpack, and how you can customize image bundling. You will also learn to manage media content loaded in a React application and the transition from url/file loaders.

Here’s the Demo on CodeSandbox

Prerequisites

To follow along with this tutorial, ensure you have the following:

  • Npm installed (v8.x current release)
  • A basic understanding of JavaScript and React.js
  • CodeSandbox
  • React (latest version v17.0.2)
  • Terminal

Asset modules

Asset modules is a module that allows the usage of asset files (icons and fonts) with four (4) module types. During image bundle customization, asset modules achieve this by replacing the loaders (that is, url-loader or file-loader) with one of four (4) module types. These module types are are 'asset/resource', 'asset/inline', 'asset/source' and 'asset'.

  • The asset/resource module for emitting a separate file, exporting the image URL. It replaces file-loader.
  • The asset/source module type for exporting the source code of the asset. It replaces raw-loader.
  • The asset/inline module type exports a data URI of the asset. It replaces url-loader.
  • The asset module automatically choose between inline and resource type following a default condition.

Setting up a react.js application

Here, you will learn how to bundle three images with three file formats, jpg, png, and gif, using Webpack's Asset/resource rule in a React.js application.

Open your terminal and run the following command to initialize npm:

1npm init -y

Afterwards, install webpack and some functional dependencies with the following commands using npm:

1npm i -D wepback webpack-cli wepback-dev-server babel-loader @babel/core @babel/preset-env @babel/preset-react
2
3
4- webpack-dev-server: This module provides a development environment with hot reloading
5- webpack-cli: This dependency provides CLI commands that speed up a webpack project setup
6- babel-loader: This dependency transpiles the JavaScript files using babel and webpack.
7- @babel/core: Babel compiler core
8- @babel/preset-env: Allows the usage of the latest JavaScript syntax without providing transforms or polyfills.
9- @babel/preset-react: A React.js preset for Babel.

Next, create a source folder, src folder for our development file, including an index.js file.

Create a dist folder which will contain the built static files. In the dist folder, create a main.js file that will hold the bundled JavaScript and an index.html file.

Note that you will use webpack to bundle your index.js file into the main.js file, which would requires webpack’s configuration.

In your dist/``index.html file, enter the following:

1<div id="root"></div>
2 <script src="main.js"></script>

Next, configure your package.json file by setting private to true, which lets webpack know that your project isn't a package. Include the following script commands:

1- "start”: “webpack server”
2- “build”: “webpack”

Start a local development server for the project using webpack-server and the following command:

1npm run start

Handle imported images

First, in src/index.js file, import react, react-dom and the images to be rendered with:

1import React from "react"
2import {render} from "react-dom"
3import FirstImg from "../img1.jpg";
4import SecondImg from "../img1.jpg"
5import ThirdImg from "../img3.gif";

These images are imported as resource assets. Other import types include inline and source.

Next, add two new rules in webpack.config.js:

  • A rule to bundle image assets with certain file formats
  • A rule to bundle all JavaScript files (ending in .js), excluding node modules
1"rules": [
2 {
3 "test": /\.(png|jpe?g|gif|svg)$/i,
4 "type": "asset/resource",
5 },
6 {
7 "test": /\.js$/,
8 "exclude": /node_modules,
9 "use": {
10 "loader": "babel-loader",
11 },
12 }
13]

Here’s the complete webpack-config.js file:

1module.exports = {
2 "mode": "development",
3 "module": {
4 "rules": [
5 {
6 "test": /\.(png|jpe?g|gif|svg)$/i,
7 "type": "asset/resource",
8 },
9 {
10 "test" : /\.js$/,
11 "exclude": /node_modules/,
12 "use": {
13 "loader": "babel-loader",
14 },
15 },
16 ],
17 },
18 "devtool": false,
19 devServer: {
20 static: './'
21 },
22};

You can see all webpack configuration options here.

Finally, configure babel by creating a babel.config.js file in the project’s root directory with the following content:

1module.exports = {
2 "presets": ["babel/preset-env", ["@babel/preset-react", {"runtime": "automatic"}]],
3}

We’ll build the project to create the static files in the dist directory, using the command:

1npm run build

The dist folder contains static files that can be served over a http server or hosted on a Content Delivery Network (CDN).

Here’s what the served page with three images looks like:

Tools like create-react-app exist to abstract this development experience with setting up webpack and managing asset bundling.

Conclusion

In this post, you learned how to setup a React.js project bundled with webpack. The project also includes image files bundled using webpack’s asset modules.

Resources

You may find the following resources useful.

Deborah Emeni

Developer

I'm a Software Developer and Technical Writer with skills in Nodejs, React, and Solidity.