React, but With Webpack

GitHub Repository Link

» What we are doing?

Today, we’re going to talk about Webpack and set up a React project with it from scratch.

» What is Webpack?

In simple terms, Webpack is a powerful tool that helps you manage and bundle your JavaScript files along with other assets like CSS, images, and even HTML. Think of it as a bundler for your web application.

It takes all these files and bundles them into a few optimized files, making your website faster and easier to manage.

Advantages of using Webpack:

Module Bundling: Webpack bundles your modules. It can take all your JavaScript files and their dependencies, and bundle them into a single file or a few smaller files.

Code Splitting: Webpack supports code splitting. This means you can split your code into smaller chunks and load them only when needed.

Loaders: Webpack uses loaders to transform your files. You can use loaders to preprocess your files before bundling. For example, you can use Babel loader to transpile your modern JavaScript code into a version that’s compatible with older browsers. Or you can use CSS loaders to import and bundle your CSS files directly into your JavaScript.

Plugins: Webpack has a powerful plugin system. Plugins allow you to extend Webpack’s functionality. You can use plugins to optimize your bundles, manage your assets, and perform a wide range of tasks. For example, you can use the HTML Webpack Plugin to generate an HTML file that includes your bundled assets.

Development Server: Webpack has a built-in development server. This makes it easy to set up a local server for your development environment. The Webpack Dev Server supports hot module replacement, which means you can see your changes in real-time without needing to refresh the page.

» Set Up Webpack with React

So let’s now set up a React project using Webpack from scratch.

We’ll follow the folder structure used by Create React App.

Folder Structure:

my-react-app/
├── public/
│   └── index.html
├── src/
│   ├── Hello.jsx
│   └── index.js
├── package.json
└── webpack.config.js

First create a project folder and all the necessary files:

mkdir my-react-app
cd my-react-app
mkdir public
touch public/index.html

Next, let’s create the src folder in the root dir and inside it add two files: index.js and Hello.jsx.

mkdir src
touch src/index.js src/Hello.jsx

Let’s bring in the code:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

This is a simple HTML file with a root div where our React app will be mounted.

// index.js
import ReactDOM from 'react-dom/client';
import Hello from './Hello.jsx';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Hello />
);

Here, we have a simple functional component that displays ‘Hello World!’.

Before we move on, we need to install React and ReactDOM. Run the following command in your terminal.

npm install react react-dom

Install the build tools we need: Webpack, Webpack CLI, HTML Webpack Plugin, and Babel Loader.

npm install --save-dev webpack webpack-cli html-webpack-plugin babel-loader

With the dependencies installed, let’s create our Webpack configuration file, webpack.config.js."

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin');  

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'build'),
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'public', 'index.html'),
        }),
        new MiniCssExtractPlugin()
    ],
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            ['@babel/preset-env', { targets: 'defaults' }],
                            ['@babel/preset-react', { runtime: 'automatic' }]
                        ]
                    }
                }
            },
            {
                test: /\.css$/i,
                use: [MiniCssExtractPlugin.loader, "css-loader"],
           },
           {
            test: /\.(png|jpe?g|svg)$/i,
            type: 'asset/resource'
        }
        ]
    }
};

path is a Node.js module that helps us handle file paths.

HtmlWebpackPlugin generates an HTML file that includes our bundled JavaScript.

MiniCssExtractPlugin extracts CSS into separate files."

entry property specifies the entry point of our application. This is where Webpack starts building the dependency graph. In our case, it’s ./src/index.js.

output property tells Webpack where to output the bundled files.

filename is the name of the output file, and path is the directory where the output file will be placed.

We use path.resolve to get the absolute path to the build directory.

We’re using HtmlWebpackPlugin to generate an HTML file based on our template in public/index.html.

We’re also using MiniCssExtractPlugin to extract CSS into separate files."

The module property defines how different types of modules are treated. We use rules to specify loaders for different file types.

babel-loader to transpile JavaScript and JSX files.

The test property specifies the file types to match.

exclude ensures that we don’t transpile files in the node_modules directory.

use specifies the loader and its options. Here, we’re using Babel presets to transpile modern JavaScript and React code.

And that’s how to configure Webpack for our projects.

Let’s add a build script to our package.json to run Webpack in production mode.

// package.json 
"scripts": {
    "build": "webpack --mode production"
}

» CSS Loaders

Now Let’s have a support for CSS file.

Let’s start by creating a CSS the file.

First, create a CSS file called main.css in the src folder.

touch src/main.css

Add the following CSS to style our Hello component.

h1 {
    color: blue;
}
p {
color: green;
}

Then Import the CSS file in Hello.jsx.

import './Hello.css';

const Hello = () => (
    <h1>
        Hello World!
    </h1>
);

export default Hello;

And To handle CSS files, we need to install mini-css-extract-plugin and css-loader.

To do so run the command:

npm install --save-dev mini-css-extract-plugin css-loader

And we need to do changes in web.config.js file too.

» Image Support

Let’s add support for image files. Create a new component Image.jsx in the src folder.

touch src/Icon.jsx

Add the following code to Image.jsx.

import image from 'image.png';

const Image = () => (
    <img src={image} width={64} height={64} />
);

export default Image;

Import and use this Image component in Hello.jsx.

import Icon from './Icon.jsx';

const Hello = () => (
    <div>
        <Icon />
        <h1>Hello World!</h1>
    </div>
);

export default Hello;

And now Run the build script:

npm run build

And you will have a build folder in the root dir with the index.html, main.js, main.css, and also image file present.

» Webpack dev server

Last but not the least we want to make development easier right?, For it we can use built in webpack-dev-server.

To Install it using the following command.

npm install --save-dev webpack-dev-server

Add a start script to package.json.

"scripts": {
    "start": "webpack serve --mode development --open",
    "build": "webpack --mode production"
}

Now you can start the development server with the following command.

npm start

It will start the dev server on localhost:8080. Now we can make changes in real time without needing to manually reload the page again and again.

And there you have it! We’ve set up a React project with Webpack from scratch, including support for CSS and images, and a development server.


And That’s it! You’ve successfully built a react app with webpack.

Thank You and Happy coding!😊