How to Install Webpack with React JS from Scratch?

Quick Summary:

Have a scalable React app requirement that ‘create-react-app‘ can’t handle? Curious about how to use webpack with React js? Here is all you need to know!

We are all used to using CRA (create-react-app) to build any React project. Even if you aren’t a React developer, you probably know about this quick and efficient way of initializing a React project. Running a single command 'npx-create-react-app project-name' sets up all the necessary tools needed to initiate a React project.

These templates are helpful for React developers working on a small-scale React project. However, it takes away the developer experience, and bundle output is saddled with multiple defaults that cannot be configured. This solution might not be ideal when working on large-scale React apps. For gaining better control of the overall build process, it is better to opt for a custom React webpack configuration from scratch. Before diving deeper into using Webpack with React js, we should understand Webpack React.

What is Webpack in React?

There is an apparent gap between the way we write JavaScript code today and the codes that browsers can comprehend and execute. To fill this gap, developers often depend on various resources and experimental features that aren’t supported in modern browsers. Now many available JavaScript module bundlers can be used for closing this gap. However, one of the most tried and tested bundlers is React Webpack, which many developers have used for achieving cross-browser compatible coding standards while retaining absolute control in the developers’ hands, opening up room for customization and optimization.

Does React need Webpack? Benefits of using React Webpack

Is webpack an absolute must for creating React apps? No. There are alternatives available such as Parsel, Browserify, and Brunch. However, Webpack is the one that is widely accepted module that has proven its merit across the global React.js dev community. The active community is always ready with answers for wherever you get stuck; besides, it is one of the most minimal and straightforward bundlers and task runners. Here are the benefits that using React with Webpack brings to your React project:

1. Enhances Scalability of your React app

Since React Webpack is a module system, it can help make your React app highly scalable. Webpack is based on the ES6 standards with other module system standards. Whenever you create a file using this module system, it automatically becomes its module with its scope. This is very helpful if your project depends on various vendor dependencies. Using Webpack React also allows React developers to understand how front-end boilerplates work under the hood.

2. Optimize Development Time with Hot Module Replacement

React with Webpack has a promising feature named ‘Hot Module Replacement’. One of the most annoying problems in web development has been situations where the changes made on the web app don’t render as expected. This ultimately forces the developers to refresh the browser to see the most recent updates on their web project.

Many developers created different plugins and tools to manipulate the DOM to re-render every time the developer saves the changes without a full reload. This is popularly known as Hot Reloading in React, where it replaces the specific module of the App with an updated one during runtime so it can be used instantly when needed. Hot Module Replacement is taking that further where your page doesn’t need to trigger a page reload for reflecting minor changes in your JS or CSS code. You need to add CSS loaders in the webpack config file. Moreover, the page loading time while debugging is also gets significantly reduced. This replacement feature helps reduce overall development time, boosting the publishing time of your website.

3. Absolute control over React Build Systems

The biggest problem with modern coding is that it is difficult for older browsers to understand them. Basic browsers are used with HTML, CSS, and JavaScript formats, whereas React sometimes uses JSX and ES6+ code. Using React webpack gives you complete control and the option to choose builds like Babel or Traceur for transpiling your modern code to versions supported by older browsers. This can help put you ahead of your competitors right from the start.

Also Read: Latest React 18 Features & Changes

Understanding how React Webpack works?

Like create-React-app, React Webpack is also a command-line tool used to create a bundle of assets (files and code). It doesn’t run on the browser or the server. It takes all the JS files and other assets, transforming them into one large file. Now, this compressed file can be sent to the browser or the server depending on which rendering style you have set up for your website. React webpack file is typically configured through a file labeled webpack.config.js. This is the place where all the configurations will take place.

const path = require("path");

module.exports = {
  entry: path.resolve(__dirname, "src", "index.js"),

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
};

React Webpack Components – What goes on under the hood

You should familiarize yourself with some of the React webpack terms and what they mean, which will help you understand what iswebpack.config.js in React.

LookinG for React developers to hire?

Get in touch to develop highly scalable web app project.

1. Entry

As the name suggests, entry refers to the entry point of your React app. The React app architecture can be visualized as a tree. All React components branch out from App.js. And app.js is found inside the index.js file. Webpack enters your React app via this index.js file and creates a dependency graph to understand what files are needed to load first.

2. Loader

Loaders are important in webpack. They work like compilers that check for different kinds of files and match them with their appropriate loaders for handling them. This is what a loader configuration would look like:

module.exports = {
    entry: { ... as before}
    output: { ... as before },
    
    module: {
        rules: [
            {
                test: /\.[jt]sx?$/, // matches .js, .ts, .jsx and .tsx files
                use: ['babel-loader'],, // uses babel-loader for the specified file types
                include: path.resolve(__dirname, 'src'),
                exclude: /node_modules/,
            }
        ],
    }
}

Also Read: List of Best React Static Site Generators

If you check the module part of the above code, it takes a list of rules that can be used for different purposes. Here are the rules you should know about:

Rule Description
test Checks for specific file types.
use Specifies a list of loaders used for any specific file type.
exclude Helps developers decide which files should not be processed
include Helps developers decide which files should be processed

At times you need more than one type of loader for working on a file like loading a CSS file. The rule for loading a CSS file is like this:

{
    test: /\.css$/, // matches .css files only
    use: ['style-loader', 'css-loader'],
},

As you can see, both CSS-loader and style-loader are being used for processing this file. Though we write style-loader first and CSS-loader second, they get loaded in the reverse order. Initially, the CSS-loader process will work, and then the style-loader will work on the output created by the class-loader.

3. Output

Output is relatively easy to understand. After completing all the processes, your React webpack creates a bundle file. We specify the name and the location of the final output file using the output function.

4. Plugins

Webpacks use Plugins like you would use third-party vendors to power any React App. These plugins have immense power, and they can enter the React app process during any stage and boost its productivity, Scalability, and performance. Here is what importing a plugin in your React webpack app looks like:

const HtmlWebpackPlugin = require("HTML-webpack-plugin");
const path = require("path");

module.exports = {
  entry: "index.js",
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "index_bundle.js",
  },
  plugins: [new HtmlWebpackPlugin()],
};

Here we installed a plugin named HTML-webpack-plugin. This plugin helps developers include all their webpack bundles in the body using script tags.

5. Mode in React Webpack

Mode is a simple yet very important concept to understand for React-webpack. It helps developers use different setups when they are in development and production modes. This is what it looks like in code:

module.exports = merge(common ,{
    entry:  {...},
    output: {...},
    module: {...},
    plugins:{...},
    
    mode : 'development' or 'production'
})

If you set the mode to production, the output bundle gets minified and optimized.

6. Development Server

And finally, you should know about development server. When developing your React app, it can be annoying and inefficient if the app compiles every time you change something. To avoid that you need to use devServer for your application.

module.exports = merge(common ,{
    entry:  {...},
    output: {...},
    module: {...},
    plugins:{...},
    mode :  {...},
    
    devServer: {
        contentBase: path.join(__dirname, 'public/'),
        port: 3000,
        publicPath: 'http://localhost:3000/dist/',
        hotOnly: true,
    },
})

This setup will serve your application from the dist you set up earlier as your output.

Also Read: How to Secure ReactJS App?

Install Webpack in React

Now that we understand the role of webpack in React, we should look at the React with Webpack installation process. We can add webpack config to create-react-app, but this would again limit the customization and freedom we would have if we created a React app using webpack from scratch. Installing React webpack will help you gain complete control over the configuration and open up the scope of customization.

Searching for a ReactJS Development Company?

Hire Certified Developers from Aglowid to build scalable feature-rich ReactJS Solution

1. Install npm int | Installing dependencies

Assuming you already have the latest Node.js and npm version installed in your system, the first thing you need to install is npm init. Although VS Code is a popular choice, you can use whichever code editor you want. Start by running this process:

$ npm init -y

Doing so creates a starter package and creates a package.json file as well. All the dependencies needed to build your App will be listed here. Next, we want to create a basic React application, for which we need two libraries – React & React DOM. We can add them as dependencies using npm:

$ npm i react react-dom --save

Now we can add a webpack for bundling our App together. Webpack is also needed for its hot reloading replacement feature. Here is how to install webpack-react in your project:

$ npm i webpack webpack-dev-server webpack-cli --save--dev

The save dev command tells the React app that these are just ‘dev’ dependencies.

React Webpack dependencies Function
webpack module Will include all core webpack functionality
webpack-dev-server This server automatically reruns webpack when files are changed
webpack-cli Allows running webpack from the command line

2. Set up Project Structure

You would have a package.json file and a package-lock.json file in your root. Next, we will create some empty files that we will be populating later. Now you should set your project in a way that it looks like the structure shown below:

TUTORIAL-REACT-WEBPACK
└───src
│   └───App.js
│   └───index.js
|   └───index.html
|   └───index.css
└───package-lock.json
└───package.json
└───webpack.config.json

3. Create a simple React App

Now that we have all the assets in place let’s populate those folders we created earlier with proper codes to test how they function on the browser.

<!DOCTYPE html>
<html>
  <head>
      <title>React with Webpack</title>
  </head>
  <body>
      <div id="app"></div>
  </body>
</html>
import React from "react";
import ReactDOM from "react-dom";
import App from "./App"; ReactDOM.render(<App />, document.getElementById("app"));
...
import React from "react";

export default function App() {
return <h1>Hello World</h1>;
}

This basic Hello World app is supposed to render a <h> tag that says ‘Hello World’ on the page. But if you try adding an index.js file to your HTML file like this:

...
    <script src="index.js" />
  </body>
</html>

The code won’t work. Your browser will shoot a blank page. Your browser doesn’t know how to import App from the ./App directory. The browser can only load static JS files. Hence, webpack configuration is needed for converting your React app into readable code that browsers can understand.

4. Utilizing Loaders

As discussed above, loaders are an essential part of React Webpack as they can be used for compiling complex JSX files to browser understandable JavaScript files. We will use the babel-loader for this task. Install babel-loader by writing this code:

npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader

We have installed babel, two presets, and the babel-loader needed to load our JSX files.

Also Read: ReactJs Advantages and Disadvantages

5. Configure React-Webpack

Now we need to configure webpack React for instructing it to use Babel during bundling process for understanding the JSX files:

const path = require("path");
module.exports = {
  entry: "/src/index.js",
  output: { path: path.resolve(__dirname, "dist") },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env", "@babel/preset-react"],
          },
        },
      },
    ],
  },
};

Here we instructed webpack to use babel-loader whenever it finds a file with js or JSX extension.

6. Bundle your React App

Now we need to add a script to our package.json file which allows us to build our App whenever needed seamlessly:

import { LinearProgress } from "@mui/material"
import { Router } from "@reach/router"
import React, { Suspense } from "react"
export function Routes() {
  const LoginComponent = React.lazy(
    () => import("./Login")
  )
  const SignUpComponent = React.lazy(
    () => import("./Signup")
  )
  const ForgotComponent = React.lazy(
    () => import("./ForgotPassword")
  )
  const AuthenticatedComponent = React.lazy(
    () => import("./Authenticated")
  )
  return (
    <Suspense fallback={<LinearProgress />}>
      <Router>
        <LoginComponent path="login" />
        <SignUpComponent path="signup/*" />
        <ForgotComponent path="reset/*" />
        <AuthenticatedComponent path="app/*" />
      </Router>
    </Suspense>
  )
}

Now run the build using this command

npm run build

This will create the main.js file in the dist folder of your project root. Now we can attach this bundled JS to our HTML:

6.1 Manually running bundled App

Once you have added the script tags mentioned above, open the index.html in the browser, and now you will see the Hello World! text on the browser.

<!DOCTYPE html>
<html>
  <head>
    <title>React with Webpack</title>
  </head>

  <body>
    <div id="app"></div>
    <script src="../dist/main.js"></script>
  </body>
</html>

6.2 Using HtmlWebpackPlugin

The above method is great for adding bundled JS to your HTML. However, it is not practical in real life. Any real app will have multiple webpack plugins for chunking your JS files. Hence manually importing all bundling scripts to HTML will be cumbersome and futile. Instead, we can automate the process by installing a powerful React plugin named HTML-webpack-plugin by running the following command:

npm i -D HTML-webpack-plugin

Modify our project configuration file for adding this plugin by running the following code:

const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: "/src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env", "@babel/preset-react"],
          },
        },
      },
    ],
  },
  plugins: [
    new HtmlWebPackPlugin({
      template: "./src/index.html",
    }),
  ],
};

Also Read: React State vs Props

By running this code, we included the plugin and gave it a template HTML that has the webpack attached to the bundled JS after the build. After this, we can remove the <script> tag from the src/index.html directory. Now run the build using:

npm build

You will see that the index.html file is also generated alongside main.js in the dist folder when you do this.

How to optimize performance using Webpack?

The best tool for bundling all your code is Webpack. The configuration has so many features that you can overlook some of the best ones for utilizing Webpack to increase the speed of React apps. The project bundles may be optimized using three tried-and-true methods.

Webpack Bundle Analyzer

A measure for visualizing the packages your application uses is the Webpack Bundle Analyzer. Although it won’t shrink your bundle size, it might help you prioritize your optimization efforts by showing you how much space each package takes up.

Use the following command to import the package to configure Bundle Analyzer:

npm install webpack-bundle-analyzer --save-dev
or
yarn add webpack-bundle-analyzer -D

import the package in your webpack.config.js

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin

With the package imported, add it to your plugins:

plugins: [

  new BundleAnalyzerPlugin()

]

The breakdown of your bundles will be displayed in a new browser window when you rerun Webpack.

Code-Splitting

Code splitting refers to dividing code into several bundles or components that load concurrently or on demand. However, it doesn’t lessen the size of your bundle overall. Depending on the parameters you supply, it divides your single output file into multiple smaller files. Only when it is requested, do individual files load. Faster page loads are a result of smaller files. This has been particularly helpful for me on pages like login, signup, and password reset that do not require authentication. It would be best to use Lazy to load the sections or pages you want to divide for Code-Splitting to function. In the following example, it is divided things up by route.

import { LinearProgress } from "@mui/material"
import { Router } from "@reach/router"
import React, { Suspense } from "react"
export function Routes() {
  const LoginComponent = React.lazy(
    () => import("./Login")
  )
  const SignUpComponent = React.lazy(
    () => import("./Signup")
  )
  const ForgotComponent = React.lazy(
    () => import("./ForgotPassword")
  )
  const AuthenticatedComponent = React.lazy(
    () => import("./Authenticated")
  )
  return (
    <Suspense fallback={<LinearProgress />}>
      <Router>
        <LoginComponent path="login" />
        <SignUpComponent path="signup/*" />
        <ForgotComponent path="reset/*" />
        <AuthenticatedComponent path="app/*" />
      </Router>
    </Suspense>
  )
}

The routes that were lazily loaded will each be divided into a separate file and loaded as needed. A more thorough explanation of code-splitting may be found here if you’re interested in reading it.

Wrapping up!

This is all you need to know about React Webpack! Make sure to be sure webpack with React if you are working on a large-scale app project that needs customization, Scalability, and complex configurations to ensure your React app can handle all the demands and performs seamlessly without any bottlenecks.

have a unique app Idea?

Hire Certified Developers To Build Robust Feature, Rich App And Websites.

This post was last modified on December 11, 2023 5:21 pm

Saurabh Barot: Saurabh Barot, the CTO at Aglowid IT Solutions, holds over a decade of experience in web, mobile, data engineering, Salesforce, and cloud computing. Renowned for his strategic vision and leadership, Saurabh excels in overseeing technology strategy, managing data infrastructure, and leading cross-functional teams to drive innovation. Starting with web and mobile application projects, his expertise extends to Big Data, ETL processes, CRM systems, and cloud infrastructure, making him a pivotal force in aligning technology initiatives with business goals and ensuring the company stays at the forefront of technological advancements.
Related Post