How to create a React App with Webpack and Express

How to create a React App with Webpack and Express

Hello Reader!

If you want to create a simple web application using React, Webpack, Babel, and Express, this guide will help you!

Prerequisites: You should be having a node and npm/yarn installed.

Firstly, Create a folder with any name you like. open the windows command prompt pointing to the newly created folder.

Now run the below command to initialize the project.

npm init

or

npm init -y

I have used shell as the language for the above.

Note: The "-y" flag when passed to NPM commands tells the generator to use the defaults instead of asking questions.

The above command will generate a package.json file like below

{
  "name": "myapp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Express

Let's create an Express server with a couple of APIs.

Express.js is a Node.js web application framework. This framework will help in creating RESTful APIs and routes.

For installing express run the below command

yarn add express

or

npm install --save express

Create a folder "server" at the root level. Add a new file "index.js" inside the "server" folder.

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const sampleResponse = {
  msg: "I\'m alive!!!"
};

app.get('/api/heartbeat', (req, res) => {
  res.send(sampleResponse);
});

app.get('/', (req, res) => {
 res.status(200).send('Hello from Express Server!!!');
});

app.listen(port, function () {
 console.log('App listening on port: ' + port);
});

Here we are creating two APIs

  • "/api/hearbeat" which serves with a response {"msg":"I'm alive!!!"}
  • "/" which serves with a response "Hello from Express Server!!!"

Add the following start script to your package.json

 "scripts": {
    "start": "node server/index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

Let's bring up the server by running the command "yarn start" or "npm run start"

Yayyy!!!! Now your application will be running at localhost:3000

you can confirm the APIs works properly by hitting the below URLs in the browser localhost:3000/ and localhost:3000/api/heartbeat

image.png

Webpack

Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging​.

Firstly, Install webpack and webpack-cli

yarn add --dev webpack webpack-cli

or

npm install --save-dev webpack webpack-cli

Now add the build script in package.json file

"scripts": {
    "start": " node server/index.js",
    "build": "webpack --mode production",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

Next step is to create folder "src" at the root level and add a file "index.js" in that folder. let index.js be empty for now.

image.png

Now you can build the project by using the below command

yarn build

or

npm run build

A dist folder in the project contains the minified files.

image.png

Babel

Babel is a JavaScript compiler that converts ECMA 2015+ code into a backward-compatible version of JavaScript in current and older browsers or environments. to know more about it click this

For install babel run the below command

yarn add --dev @babel/core @babel/preset-env @babel/preset-react babel-loader

or

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

Now create a file .bablerc at the root level and add the following

{
    "presets": ["@babel/preset-env", "@babel/preset-react"]
}

The next step is to integrate babel into your project. Create a webpack.config.js file at the root level and add the below snippet. This webpack configuration will tell the babel to compile .jsx and .js files before being bundled.

module.exports = {
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader"
                }
            }
        ]
    }
};

React

Install react and react-dom

yarn add react react-dom

or

npm install --save react react-dom

Now create an index.html with the following content under the src folder.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React with webpack and Express Server</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>

Add the below code snippet in the index.js under src folder.

import React, { lazy, Suspense } from 'react';
import ReactDOM from 'react-dom';


const AppContainer = lazy(() => import("./components/AppContainer"));

const App = () => {
    return <Suspense fallback={<div>Loading...</div>}><AppContainer/></Suspense>;
};

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

In order to make your react app and webpack to work together, you will have to install html-webpack-plugin. This is a webpack plugin that simplifies the creation of HTML files to serve your webpack bundles. This is especially useful for webpack bundles that include a hash in the filename which changes every compilation. You can either let the plugin generate an HTML file for you, supply your own template using lodash templates, or use your own loader.

yarn add --dev html-webpack-plugin

or

npm install --save-dev html-webpack-plugin

update the webpack.config.js with the below content.

const HtmlWebPackPlugin = require('html-webpack-plugin');
const path = require('path');
const htmlPlugin = new HtmlWebPackPlugin({
    template: "./src/index.html",
    filename: "./index.html"
});

const dirName = path.resolve(path.dirname(''));

module.exports = {
    entry: "./src/index.js",
    output: {
        path: path.join(dirName, "/dist"),
        filename: "CompleteBundle.js"
    },
    plugins: [htmlPlugin],
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader"
                }
            }
        ]
    }
};

It's time to connect your react app and Express server. Add dev script in the package.json

"scripts": {
    "start": " node server/index.js",
    "dev": "webpack --mode development && node server/index.js",
    "build": "webpack --mode production",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

Now you are at the final step. Refactor the src/index.js file.

const express = require('express');
const app = express();
const path = require('path');
const port = process.env.PORT || 3000;
const dirName = path.resolve(path.dirname('')); //New
const DIST_DIR = path.join(dirName, '/dist'); //New
const HTML_FILE = path.join(DIST_DIR, 'index.html'); //New
const sampleResponse = {
  msg: "I\'m alive!!!"
};

app.use(express.static(DIST_DIR)); //New

app.get('/api/heartbeat', (req, res) => {
  res.send(sampleResponse);
});

app.get('/', (req, res) => {
 res.sendFile(HTML_FILE); //Edit
});

app.listen(port, function () {
 console.log('App listening on port: ' + port);
});

The express server will read the bundled index.html file from the dist folder and servers it.

Now run the application

yarn dev

or

npm run dev

Yayyyy!!! Now your application is running here localhost:3000

image.png