Getting started with webpack - Part 10: Webpack and React.js from scratch

Introduction

Introduction

In this final tutorial, we will consider how to configure another popular JavaScript library from scratch. As with Vue, React, comes with its own CLI tool that can help you get started pretty quickly. However, the React CLI tool abstracts all the logic and does all the magic in the background. So let’s attempt to set up React from scratch without using the CLI tool.

In the previous post we learned how we can configure the popular JavaScript library Vue.js from scratch. We configured things we are already used to having from the vue-cli tool like hot reloading, stylesheet support, loading .vue files, and more.

A quick reminder

Before we get started, please note that we are not recommending any way of setting up the libraries. This article is designed to show you in examples how you can use webpack. You should decide to use CLI tools or manual depending on the project and the level of customization you want to have.

Now, that that’s out of the way, let’s get started.

NOTE: Source code of the application is available on GitHub.

Prerequisites

To follow along in this series, you need the following requirements:

  • Completed all previous parts of the series.
  • Basic knowledge of JavaScript.
  • Basic knowledge of the CLI.
  • A text editor. VS Code is recommended.
  • Node.js (>= 6.11.5) and npm installed locally.

Let’s continue with the series.

Starting from scratch

The recommended way to start a React project is using the create-react-app tool. This tool will help us generate new React applications that are already complete with hot reloading, asset compilation and more all with one command:

    $ npx create-react-app my-app

However, the aim of this tutorial is to create a React application from scratch without using the CLI tool.

Getting started

To get started we have to create a new project directory. This will be the directory where all our code will reside. Create a new directory and cd to the directory on your terminal application and run the following command:

    $ npm init -y

The above command will initialize the project and add a new package.json file in the root of the directory.

When the command has finished executing, run the next command to install webpack and webpack-cli:

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

When both packages have been installed successfully, open the package.json file and add the following script as seen below:

1// File: ./package.json
2    {
3      // [...]
4      
5      "scripts": {
6        "build": "webpack --mode development"
7      },
8    
9      // [...]
10    }

Next, let’s install the required Babel packages. To do this, run the following command below:

   $ npm i @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev

This command will install the Babel packages we will use to bundle our React application. The babel-react package will help us compile the .jsx files if we have any in the project.

Before we continue, we need to configure our Babel installation. We can do this by creating a new .babelrc file in the root of the project and paste the following contents into it:

1// File: ./.babelrc
2    {
3      "presets": ["@babel/preset-env", "@babel/preset-react"]
4    }

Next, let’s create a new webpack configuration file and paste the following code into the file:

1// File: ./webpack.config.js
2    const env = process.env.NODE_ENV;
3    
4    module.exports = {
5      mode: env == 'production' || env == 'none' ? env : 'development',
6      entry: ['./src/app.js'],
7      module: {
8        rules: [
9          {
10            test: /\.(js|jsx)$/,
11            exclude: /node_modules/,
12            loader: 'babel-loader'
13          }
14        ]
15      }
16    };

This is actually the barest minimum we need to compile our React application. The main thing we added is the babel-loader which will help us bundle the JS and JSX files. Now let’s start writing some sample components.

To get started, we need to install the React package. In your terminal, run the following command to install React as a dependency:

    $ npm i react react-dom --save-dev

When the installation is complete, we can start creating some React specific files. In the root of the project, create a new src directory and inside the directory, create a new file app.js and paste the following code into the file:

1// File: ./src/app.js
2    import React from 'react';
3    import ReactDOM from 'react-dom';
4    
5    const App = () => <div>Hello React!</div>;
6    
7    ReactDOM.render(<App />, document.getElementById('app'));

Next, we need to create a new HTML file as our entry point. Create a new index.html file in the root of the project and paste the following code into it:

1<!-- File: ./index.html -->
2    <!DOCTYPE html>
3    <html lang="en">
4      <head>
5        <meta charset="UTF-8" />
6        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
8        <title>React and Webpack</title>
9      </head>
10    
11      <body>
12        <div id="app"></div>
13      </body>
14    </html>

To make sure webpack adds the bundled JavaScript to the HTML file, let’s install the html-webpack-plugin and add it to our webpack configuration file. Run the following command in your terminal to install the plugin:

    $ npm i html-webpack-plugin -D

When the installation is complete, open the webpack configuration file and update it as seen below:

1// File: ./webpack.config.js
2    // [...]
3    
4    const HtmlWebPackPlugin = require('html-webpack-plugin');
5    
6    module.exports = {
7      // [...]
8      
9      plugins: [
10        new HtmlWebPackPlugin({
11          template: 'index.html',
12          filename: 'index.html',
13          inject: true
14        })
15      ]
16    };

Next, run the following command below to build the application:

    $ npm run build

This will build the application to the dist directory in the project directory. Open the dist/index.html file in your browser to see the bundled application:

webpack-10-1

Improving our webpack bundling

Although our build above works, we can definitely do better. Let’s do some additional configuration that will get us closer to an actual development environment. First, we will install the webpack dev server. This will remove the need for us to manually launch the index.html file.

In your terminal, run the following command:

    $ npm i webpack-dev-server -D

Next, in your package.json file, add the following build script:

1// File: ./package.json
2    {
3      // [...]
4      
5      "scripts": {
6      
7        // [...]
8    
9        "dev": "webpack-dev-server --open"
10      }
11      
12      // [...]
13    }

Now when we run the dev script and visit http://localhost:8080, we should see the same output as above. However, when we change the contents of the App.vue the changes are not reflected immediately.

To add hot reload, let’s make a few changes. In the webpack configuration file, update as seen below:

1// File: ./webpack.config.js
2    // [...]
3    const webpack = require('webpack');
4    
5    module.exports = {
6      // [...]
7      
8      devServer: {
9        hot: true,
10        watchOptions: {
11          poll: true
12        }
13      },
14      
15      // [...]
16    
17      plugins: [
18        new webpack.HotModuleReplacementPlugin(),
19        
20        // [...]
21      ]
22    };

Now we can re-run the dev script and we will see true hot reloading whenever we change our source files.

Adding styles and other components

Right now, we have a single component and an unstyled HTML page. Let’s add some styling and an additional component.

In the src directory create a new components directory and in the directory create a new file HelloWorld.js and paste the following code:

1// File: ./src/components/HelloWorld.js
2    import React from 'react';
3    
4    const HelloWorld = () => <h1>Hello World!</h1>;
5    
6    export default HelloWorld;

Next, create a new styles directory in the src directory and in this directory, create a new app.css file. Paste the following code inside the file:

1/* File: ./src/styles/app.css */
2    #app .container {
3      width: 100%;
4      margin: 0 auto;
5      max-width: 1200px;
6    }
7    
8    #app .container h1 {
9      color: #232b2b;
10      text-align: center;
11    }

Next, open the src/app.js file and replace the contents with the following:

1// File: ./src/app.js
2    import React from 'react';
3    import ReactDOM from 'react-dom';
4    import HelloWorld from './components/HelloWorld';
5    
6    import './styles/app.css';
7    
8    const App = () => (
9      <div className="container">
10        <HelloWorld />
11      </div>
12    );
13    
14    ReactDOM.render(<App />, document.getElementById('app'));

Before we run the server again, let’s add a loader to handle the CSS we imported above. In your terminal, run the following command:

    $ npm i css-loader style-loader -D

When the installation is complete, open the webpack configuration file and update as seen below:

1// File: ./webpack.config.js
2    
3    // [...]
4    
5    module.exports = {
6      // [...]
7      
8      module: {
9        rules: [
10          // [...]
11          
12          {
13            test: /\.css$/,
14            use: ['style-loader', 'css-loader']
15          }
16        ]
17      }
18      
19      // [...]
20    };

Above, we just added the style-loader and css-loader to handle the CSS in the application.

Now, run the command to build and start the server once again (if it was previously running, you need to kill it with ctrl+c and restart it):

    $ npm run dev

Now you should see the styled application when you visit http://localhost:8080

webpack-10-2

That’s all. We have successfully created a React web application from scratch using webpack.

Conclusion

In this final tutorial of the series, we learned how to set up a new React application from scratch using the power of webpack.

Throughout the series, we have touched on various aspects of webpack as a whole and though there is still a lot more, you should know your way around webpack now. If you need more information, you can always visit the documentation.

The source code to the applications built in the series is available on GitHub.