Ultimate Guide for configuring Webpack & Babel for your React App: Pt. 1

Setting up webpack may seem daunting š¤¢ if you are new to it, but my aim behind writing this article is to make it simple for you. This article will be split across parts in which we will be going from zero to hero š
Link to GitHub Repo: https://github.com/AbhishekGautam01/webpack-react
create-react-app(CRA) comes really handy to set up a react app with a ton of predefined templates that are wildly popular amongst developers. But this leaves us with a lot of default configurations which is definitely not very desirable, also every app is different so there is no one size fit all.
But if you need to have more control over your build process then webpack comes really handy. So before we start ahead letās look understand what Webpack and babel are.
Webpack: Introduction
Browsers are able to run JavaScript but not in the same way as we code JS as we may be using some transpiled or experimental features or maybe using features available in a newer release of ES but all these are not immediately made available in all Browser.
Here Webpack bridges the gap and produces cross-browser compatible code. Although the official site may define webpack as a āstatic module bundlerā but it is more than that like code-splitting, Tree shaking, Hot Module Replacement, etc.
Babel (JS Loader): Introduction
It is a transpiler ā It takes Modern JS code and compiles it into older versions of JS to support a variety of browsers. Babel will be required in our react project to convert JSX to JS. Although by Transpiling you canāt add a new feature for that we can use Polyfilling but this we will be discussing in one of our future articles.
It also supports a plugin-based environment which helps make it more extensible and configurable.
So letās get started with building our app.
npm init
Letās start with making react app first. The first step would be to create a directory, you can name it anything you want and switch to that directory, and run:
npm init -y
Once this is done then open the root directory in your favorite code editor (mine being Visual Studio Code ā its extension-based ecosystem makes it powerful) and you will notice a package.json file that is being created. This file is used to store metadata about our project. It keeps track of modules that we add to our project through npm.
Installing React
You can search all npm modules here.
npm install ā save react react-dom
This would add react and react-dom to the project dependencies section in package.json. One more noticeable change you will see in the project directory is a new node_modules directory where all the project modules that you install will be present.
Installing Babel
To install babel related modules that we will be using in our react project, we will be using the following command.
npm install -D @babel/core babel-loader
Please note we are installing this as a dev dependency as this is required only during development time.
Configuring Babel
In order to make babel work, we will need to provide it a config file to do this we can either have a .babelrc file or creating babel.config.js . Letās have a look at some of the packages we will be requiring to configure babel:
@babel/preset-env: Provides backward compatibility for JS code we write.
@babel/preset-react: Converts JSX syntax into vallina JS
@babel/plugin-transform-runtime: Babel uses very small helpers for common functions such as _extend. By default, this will be added to every file that requires it. This duplication is sometimes unnecessary, especially when your application is spread out over multiple files.
This is where the @babel/plugin-transform-runtime plugin comes in: all of the helpers will reference the module @babel/runtime to avoid duplication across your compiled output. The runtime will be compiled into your build.
@babel/plugin-syntax-dynamic-import: To enable dynamic imports() syntax in browsers that donāt support promised.
@babel/plugin-proposal-class-properties: This plugin transforms static class properties as well as properties declared with the property initializer syntax
Also, letās add some packages to perform react specific optimization:
babel-plugin-transform-react-remove-prop-types: removes unnecessary prop-types from production code.
@babel/plugin-transform-react-inline-elements: evaluates React.createElement
during compilation and inlines the result.
@babel/plugin-transform-react-constant-elements extracts static React elements as constants.
npm install -D @babel/preset-env @babel/preset-react @babel/runtime @babel/plugin-transform-runtime @babel/plugin-syntax-dynamic-import @babel/plugin-proposal-class-properties babel-plugin-transform-react-remove-prop-types @babel/plugin-transform-react-inline-elements @babel/plugin-transform-react-constant-elements
For now, we are good to go with babel. But still, this is not enough to run our react app but we will also be needing a transformation manager that will be taking code and applying transformation in the right order. Here webpack comes in very handy and is suitable for large enterprise application although we have other options as parcel, esbuild, etc but letās leave that for future discussion.
Installing and configuring webpack
Letās start by installing all webpack related dependencies to our project. We will be discussing each pretty soon for now you can run:
npm install -D webpack webpack-cli
We will be configuring webpack to take our react code and run it through various transformations. For this we will need to add a webpack.config.js and this file should be location at the root level in our project directory.
Elemental Configurations
Since webpack v4, we are not required to provide a config file, this should work, unless you are not a great fan of defaults or have some custom needs.
We need to provide the below three information to Webpack in order for it to work:
1. What files it should apply transformation on?2. Which transformation should be applied on a type of file?3. After transformation where it should go?
The first thing the webpack needs to know is the entry point which will be the file webpack will take and start transforming.
Please note, if the entry point is the outermost component of your app then webpack will transform the whole app.
The entry path can be a single file path or an array of file paths.
So letās have a look at webpack.config.js after adding all elemental config:
Loaders ā ā Rules
please note: In some of the older tutorials of webpack you will find Loaders being added to module.exports but this have been renamed to Rules.
Okay so now webpack has grabbed the outermost file of the project & now we will be configuring the transformations. So in the module.exports we will be adding a module key that will have an array of rules. Each object we will be adding in this will be a transformation our code will be going through before executing in the browser.
Every rule has a test property that mentions the files the loader will be operating upon. Also, a rules object can optionally have exclude & include properties. Finally, it should have a loader property
babel-loader comes from the npm modules we installed in one of our previous steps.
Configuring JS Loader into our webpack
What now after transformation?
So far we have communicated to webpack what files it needs to work on & what transformations need to be applied. After transformation webpack will look at the output property which will have filename(Name of newly transformed file) & path(the location where the new transformed file should be stored).
Transforming HTML with Webpack
Okay, so far we have done with the basic configuration. If you have followed till here give a pat on your back.
But so far webpack is only aware of index.js but usually, our main view is in app/index.html where we have a script tag that looks something like this:

But now this arises another problem after webpack is done with the transformation it will generate a transformed file for index.js with different name so index.js reference will fail to work. The obvious solution to overcome this problem is to apply some transformation to index.html.
So now letās Now configure an HTML rule for Webpack:
npm install -D html-webpack-plugin
To configure it we need to add it in the plugins array and we need to provide a filename and inject.
INJECT: Its value can be (true, false, head, body) ā Inject all assets into the given template or templateContent. When passing the body all javascript resources will be placed at the bottom of the body element. the head will place the scripts in the head element. Passing true will add it to the head/body depending on the scriptLoading option. Passing false will disable automatic injections.
So by now, your webpack.config.js should look something like this.
Creating Local React App
We are pretty much done with the required configuration to run our react app. But we haven't. added any react code so far. So create two directories src and public.
NPM Scripts
With the app size growing may be requiring multiple command-line scripts to run like for testing, coverage, building, running, etc. Here npm scripts save us from a lot of pain.
We need to add the following npm scripts in our package.json

Now to run the application in your local :
npm run start

To build your project for production mode:
npm run build
Migrating from webpack1 to 2+ : click here
Thatās all for now. We will be looking into more advanced topics in the upcoming series.
Happy Learning š„š„š„