React.js17.x: Creating Application with WebPack 5.x

 Creating React.js 17.x  Application From Scratch using Webpack 5.0

In my previous article, I have explained the approach of creating React.js application using Webpack from the scratch. The React Application can be created using create-react-app tool, but not all projects are using that approach. With my experience with some of the customers, I have experienced that they are also using  React.js application for development, build, and production using Webpack configuration.  

The WebPack is a static module bundler for the modern JavaSCript application e.g. React.js, Angular, etc. When the Webpack is used to process that application using the configuration, it internally builds the dependency graph based on dependencies used in the application development. These dependencies could be, bootstrap framework, or any other JavaScript files used in the project. The Webpack configuration allows using various loaders to load these CSS styles in the application and further helps to create the development and production build.

In this article, we will discuss all steps to create a React.js application and configure it.  In this article, we will be using Webpack version 5.0. The new version of Webpack is released last year in October. In this article, we will also see the Webpack configuration for the development and production environment. We will be requiring the following packages for the configuration of the React.js application with Webpack.

  1. @babel/core
    1. Since we will use ES 6+ JavaScript for the React.js coding we need the Babel Transpilaer to transpile the JavaScript code.
  2. @babel/preset-env
    1. This is a smart preset that allows using the latest JavaScript without bothering to decide on the JS Syntax that is supported the target environment. This is used to make the development easier and reducer the size of the javascript bundle.
  3. @babel/preset-react
    1. This is a preset that is used for React for making the react development experience easier without worrying about the JavaScript Syntax to be followed during coding. This preset includes the following plugins
      1. @babel/plugin-syntax-jsx
      2. @babel/plugin-transform-react-jsx
      3. @babel/plugin-transform-react-display-name
  4. babel-loader
    1. This package is used for transpiling the JavaScript files using Babel and Webpack.
  5. css-loader, scss-loader,style-loader
    1. This is used in the case when the Webpack needs to include CSS, SCSS files in the React bundle.
  6.  html-webpack-plugin
    1. This plugin is used to simplify the creation of HTML files to serve the output bundle.
  7. webpack, webpack-dev-server, webpack-cli, webpack-merge
    1. These packages are used for them making the use of webpack bundler in the application. 
    2. The webpack-dev-server is the development server that is used to run the JavaScript application development environment. 
    3. The webpack-merge provides a merge function. This function provides the functionality of concatenating arrays and merging objects. In this example, we will be creating separate webpack configurations for the development and production environment. The development and production environment will be having common configurations. The merge function will be used to merge the common configuration with the development and production configuration.
  8. clean-webpack-plugin
    1. This plugin is used to clean the output or destination folder from all Webpack unused assets. 
The React.js Project creation using Webpack

We will use the Microsoft Visual Studio Code and Node.js for the project creation. 

Step 1: Create a new folder on the drive (Windows/Linux/macOS machine) and name it as Webpack_Setup. Open the Command Prompt or the terminal window and navigate to the Webpack_Setup folder. Run the following command to create a package.json for the project

npm init -y

Step 2: Once the pakcge.json is created, we need to install babel and Webpack packages in the global scope. Run the following command to install these packages in the global scope

npm install -g @babel/core webpack webpack-dev-server webpack-cli

Step 3: The most important thing here is to install various loaders, babel, and Webpack for creating the react.js application. To install these packages run the following commands  from the command prompt 

npm install --save react react-dom bootstrap

npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader 
html-webpack-plugin css-loader scss-loader style-loader webpack webpack-merge webpack-cli webpack-dev-server  clean-webpack-plugin
             
Step 4: Since, all dependencies are installed, open the Webpack_Setup folder in VS Code. Tn this editor, in the Webpack_Setup folder, add a new folder and name it as public. In this folder, add a new file and name it as index.html. In this file add the markup as shown in listing 1


<!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.js 17 with Webpack</title>
</head>

<body>
  <h1>The React.js app with Webpack</h1>
  <div id="root"></div>
</body>

</html>
Listing 1: The index.html with the markup  

Step 5: In the project, add a new file and name it as .babelrc. This is a babel resource configuration file. This file is used during the JavaScript babel transpilation. In this file add the code as shown in listing 2


{
    "presets": ["@babel/preset-env", "@babel/preset-react"]
}
Listing 2: The .babelrc file

Step 6: In the project add a new folder and name it as src. IN this folder add newcomponent.js, app.js ,and index,js. These files will contain the React.js components code as shown in listing 3

newcomponent.js
import React from 'react';
const NewComponent=()=>{
    return (
        <div className="container">
            <h2>Thew New Component</h2>
        </div>
    );
};

export default NewComponent;

app.js
import React from 'react';
import NewComponent from './newcomponent';

const App=()=>{
  return (
        <div>
          <h1>The React App</h1>
          <NewComponent></NewComponent>
          <input type="button" value="Click" className="btn btn-success"/>
        </div>
  )
};

export default App;

index.js
import React from 'react';
import ReactDOM from 'react-dom';
// import './../node_modules/bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));



Listing 3: The various React components source files 
    
In the index.js, the App component is imported from the app.js, whereas the App Component imports NewComponent from the newcomponent.js. The index.js also imports the bootstrap.min.css to load various classes. This means that index.js is the entry point of the application.

Step 7: Once the React.js code is done, it's time for us to create a Development and Production configuration for the project.  In the project add a new file and name it webpack.common.js. This file will contain all the common Webpack configurations for using entry point, loaders, and output configurations as shown in listing 4


const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path'); 

module.exports = {
    entry: './src/index.js', // an entry point for the build, dev and production
    module: {
        // configuring all the dependencies
        rules: [
            {
                test: /\.(js)$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },

            {
                test: /\.(css|scss)$/,
                use: [
                    "style-loader", // creates style nodes from JS strings
                    "css-loader", // translates CSS into CommonJS
                    "sass-loader" // compiles Sass to CSS, using Node Sass by default
                ]
            }
        ]
    },
    resolve: {
        extensions: ['.js', '.jsx'],
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'public/index.html' // the HTML output
        })
    ],
    output: {
        filename: '[name].bundle.js',  // The output file that will be generated
        path: path.resolve(__dirname, 'dist'), // The folder where the output will be generated
        clean: true,
      },
};
Listing 4: The Webpack common configuration 

As shown in Listing 4, the Webpack is using index.html as an entry point for creating the application build for the development and production environment. Since the project needs to transpile the React JavaScript files the Webpack is configured to read all .js files from all folders except the node_modules folder and using the babel-loader these files will be transpiled.  The project uses bootstrap classes, the Webpack needs to use CSS, SCSS, and Style loaders to bundle css, scss, and style files. 

Step 8: In the project add a new file and name it as webpack.dev.js. This file will use the webpack.common.js configuration file to create the development build. In this file add the code as shown in the listing 5


const { merge } = require('webpack-merge');
 const common = require('./webpack.common.js');
 const port = process.env.PORT || 3000;
 module.exports = merge(common, {
   mode: 'development',
   devtool: 'inline-source-map',
   devServer: {
     static: './dist',
     host: 'localhost',
     port: port
   }
 });
Listing 5: The Development configuration

As shown in Listing 5, the development configuration is using the merge function from the webpack-merge package to merge the common configuration with the development configuration. We are using the Webpack Development Server. We are using port 3000 where the application will be hosted and the contents will be delivered from the dist folder.

Step 9: In the project add a new file and name it as webpack.prod.js. In this file, we will write the production configuration that will be merged with the common configuration as shown in listing 6


const { merge } = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const common = require('./webpack.common.js');
module.exports = merge(common, {
  mode: 'production',
  devtool: 'source-map',
  entry: './src/index.js',
  output: {
    filename: 'main.min.js',
    path: path.resolve(__dirname, 'dist')
  },
  performance: {
    hints: false,
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      inject: true,
      template: path.resolve(__dirname, 'public', 'index.html'),
    }),
  ]
});
Listing 6: The Webpack configuration production configuration                

As shown in Listing 6, the production configuration is using the Webpack configuration. All the JavaScript files will be transpiled and will be merged in the main.min.js. This file will be delivered to the browser along with the index.html. The performance option is used by the Webpack to notify if the output bundle is exceeding a specific limit. In the current case, we are setting the performance hint value to false. This means that even the bundle size is more than 250kb, no error or warning will be shown. 

Step 10: Finally, let's modify the package.json to add scripts commands to run the project in development and production mode as shown in listing 7

.....
"scripts": {
    "start": "webpack serve --open --config ./webpack.dev.js",
    "build": "webpack --config webpack.prod.js",
    "prod": "webpack serve --config webpack.prod.js"
  },
  .....
Listing 7: Package.json scripts commands

As shown in Listing 7, the start command will be used to run the project in the development model using Webpack cli and the configuration from the webpack.dev.js file. The prod command will be used to run the project in the production mode using Webpack cli and webpack.prod.js.
   
To run the application in development mode using the following command 

npm run start

This command will show output on the console as shown in figure 1



Figure 1: The development mode execution of the project

The React component will be rendered in the browser with main.bundle.js as shown in figure 2



Figure 2: The React.js in the development model

We can see the main.bundle.js is loaded with all React components' code in it. Stop the application. To run the application in production mode, run the following command

npm run prod

The server will host the project on port 8081, open the browser and enter the URL as http://localhost:8081, the result will be displayed in the browser as shown in figure 3


Figure 3: The Production mode   
 
The main.min.js will be loaded in the browser. The minified  JavaScript will be delivered to the browser with the reduction of the downloaded size. 

Conclusion: The Webpack provides a great mechanism to configure the JavaScript project with various plugins to create JavaScript applications from scratch.
           

Comments

Popular posts from this blog

gRPC Services using .NET 5: Using Entity Framework Core with gRPC for Performing Database Operations

Using Session State in ASP.NET Core

Understanding Token Based Authentication in ASP.NET Core 3.1 using JSON WEB TOKENS