⛴ Deploy React Apps In Production Pretty Easily 😎
Tags: react, webdev, productivity, beginners
Published: 2021-05-26 15:47:46

## 🍟 TL:DR :

Serving react app is pretty simple if we does it directly through development environment( i.e. serve apps directly including their source_code), but how to serve react apps as bundled static assets (in production environment) will be the main focus of this article.

Going deep into working of this tools can feel get pretty cumbersome, if someone is heavily using tools like *Create React App*. (which works like magic and does all the heavy lifting behind seens). Hence, I will keep it simple.

Today, we will be deploying simple react app (using Node.js back end). The final project is pretty simple and could be used as base template for your next production ready app.


### 🏋 Start Nodejs project  

First thing first, we will start basic node app, which will serve as a back end for our react front end.

```bash 
npm init --y 
```
--------------

### 🍩 Add some utility 

Now, we will install some packages like express, cors and dotenv. I am using dotenv for maintaining global values like `NODE_ENV` or anything as needed.

```bash 
npm i express dotenv cors --save 
```
--------------


### 🚀 Ignite the Server 🚀

Now, we will create a simple index.js, which will serve our as API for the client application.

```javascript 

//--------------------- imports ---------------------
const express = require("express");
require("dotenv").config();
const cors = require("cors");

//--------------------- Init App ---------------------
const app = express();
const PORT = process.env.PORT || 5000;

//--------------------- Serve Assets ---------------------
if (process.env.NODE_ENV === "production") {
  app.use(express.static("build"));
}

app.use(express.json());
app.use(cors());

app.get("/home", function (req, res) {
	 res.status(200).json({
	 status: true,
	 data: "Backend Responded "
	 })
})

app.listen(PORT, () => console.log(`Example app running on ${PORT}`));
```

This is dead simple web server, for react client. 

Now, we will add a a script in package.json. Which will start server on specified port.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zjra53kjrnq6d7r1aos3.png)

We will modify it later for client building stuff.

--------------


### 🎨 Create Front End App 

Initialize react app using *CRA* (create react app) or you can configure it on your own using babel and webpack or which ever tool you wanna use (if you want that). I will be preferring CRA  

Inside our back end project directory, initialize the front end  project.

```bash 
npx create-react-app frontend
```

After a while, we now have a new react app, which 😱magically 😱 does nothing (beside spinning a huge blue react logo).

After it, modify content of package.json of front end project and add following code to it.

```json 
  "proxy": "http://localhost:5001"
```
This will save us from typing API URL multiple times from our ajax calls, which we will be writing in front end component.

--------------


### 🛠 Write a component 

Before writing component, I will install *axios* (if preferred or use fetch) for back end communication.

```bash 
cd front end
npm i axios
```

Then, create a basic component for testing  and verifying purpose. Which will verify the connection between front end and back end.

```javascript 
import axios from "axios";
import { useEffect } from "react";

function App() {
  const fetchData = async () => {
    try {
      let resonse = await axios("/home");
      if (resonse.status) {
        alert("hooray");
      } else {
        alert("OH ! Snap....");
      }
    } catch (err) {
      console.log("err ", err.message);
    }
  };

  useEffect(() => {
    fetchData();
  }, []);

  return (
    <div className="App">
      <p > Testing Deployment </p>
    </div>
  );
}

export default App;


```
This component does only fetching of data and throwing an alert. Here, we are executing function of API call, directly in useEffect() for avoiding extra bit of code for testing purpose only. 
 
Then, add the script in the back end project as
 
```json 
    "client  " : "cd  frontend && npm run start"
```

This script will run the project and you will see the normal alert

--------------

### 🚚 The Deployment Stuff 

Until this point every thing is good. 

Now, it's time to deploy it using static asset serving. Many tutorials are currently explaining, how to ship this kind of project on platforms like heroku or varcel. Which are pretty good. But, this platforms are friendly up to a certain extent. For ex. 

* Heroku is free, but your free **dyno** will be inactivated if it is not actively getting used for a certain duration. Rebooting the slept **dyno** can take fairly large amount of time as compared to normal requests.*

For avoiding this, we end up serving the project's on paid servers, there we should serve the apps in this fashion. 
 

For deployment, we will be generating the bundle of static files which will be served from Nodejs back end. We Already, added a snippet for this in *index.js*.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gynsa4uuutl3pr0iwzqb.png)
 

This way, whenever we are using it in production this will work as expected

---------------------

### Step 1 - Generate Bundle 

Add script in package.json of back end project, for building the static asset from react source code 

```json 
    "build" : "cd frontend && npm run build"
```

This will change the current working directory and after that, it will generate the /build folder in front end project.

### Step 2 - Place /build directory in root folder 

move the build directory in the root of the project.

```bash 
mv ./build ../
```

### Step 3 - Set NODE_ENV to production 

Afterwards, last step is to change/set the value of **NODE_ENV** (in .env file) as the "production" which depicts, we are in production mode and enable static asset serving.

```bash
NODE_ENV = production
```

content of .env file will look like this 

```bash 
PORT=5001
NODE_ENV=production
```
Now, for visit the url 

```bash 
http://localhost:5001/home
```
You will get the  alert response and finally everything is working. 

Now if we deployed this Nodejs project on any production ready cloud environment like 

<ul>
	<li> AWS EC2 Instance </li>
<li> Digital occean Droplet</li>
	<li> Virtual Machine </li>
</ul>

Then this will work as expected. Thus final directory structure will look like this 

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dn0leslqz20tbeldvq6i.png)
 
--------------

###😎 Final Thoughts
 
This is one of way of serving the full stack application created using React and Nodejs. When, I was deploying this kind project, I haven't found any comprehensive guide, so I decided to write one !

Thanks for reading 🙏