DEV Community

Cover image for ⛴ Deploy React Apps In Production Pretty Easily 😎
sudarshan
sudarshan

Posted on

⛴ Deploy React Apps In Production Pretty Easily 😎

🍟 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.



npm init --y 


Enter fullscreen mode Exit fullscreen mode

🍩 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.



npm i express dotenv cors --save 


Enter fullscreen mode Exit fullscreen mode

🚀 Ignite the Server 🚀

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




//--------------------- 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}`));


Enter fullscreen mode Exit fullscreen mode

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

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.



npx create-react-app frontend


Enter fullscreen mode Exit fullscreen mode

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.



  "proxy": "http://localhost:5001"


Enter fullscreen mode Exit fullscreen mode

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.



cd front end
npm i axios


Enter fullscreen mode Exit fullscreen mode

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



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;




Enter fullscreen mode Exit fullscreen mode

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



    "client  " : "cd  frontend && npm run start"


Enter fullscreen mode Exit fullscreen mode

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

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



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


Enter fullscreen mode Exit fullscreen mode

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.



mv ./build ../


Enter fullscreen mode Exit fullscreen mode

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.



NODE_ENV = production


Enter fullscreen mode Exit fullscreen mode

content of .env file will look like this



PORT=5001
NODE_ENV=production


Enter fullscreen mode Exit fullscreen mode

Now, for visit the url



http://localhost:5001/home


Enter fullscreen mode Exit fullscreen mode

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

  • AWS EC2 Instance
  • Digital occean Droplet
  • Virtual Machine

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

image


😎 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 🙏

Top comments (11)

Collapse
 
01pooja profile image
Pooja G

Hey Sudarshan ,

I have a query.

I am unable to connect the dots here. Now I have the react front end project ready with build folder and Nodejs is installed on a Linux server . Now how can I deploy this react project on to nodejs? I wanted nodejs to serve both static and dynamic requests.

Collapse
 
sudarshansb143 profile image
sudarshan

nice question. So, when you create a build folder from react app then basically you end up with html, css and minified JS stuff. Now, for final deployment you will move this build folder to the Linux server and place it into the same directory as of your node.js server. Once done you can follow above article from Deployment Stuff

Hope it will be helpful

Collapse
 
01pooja profile image
Pooja G

Yes Sudarshan , this was the best article that I followed.

Collapse
 
cristianortiz profile image
Cristian Ortiz Navia

this is nice, this could work if a need to deploy a MERN app in a private server running other apps in LAMP?? there i need virtual host configs i think, but your setup could pull off this apache node deployment??

Collapse
 
sudarshansb143 profile image
sudarshan

sorry for delayed reply !

I don't have proper understanding of apache. But, I can assure you it would work with your other apps until it's port is available !

Hope this will be helpful

Collapse
 
radkriss profile image
radkriss

Hi Sudarshan,

I have a query.

  1. In development setup, we need to start the node server as well as the front end react app.

  2. For production setup, we have built the react front end and have those as static data in build folder. Start only the node server.

Is my understanding right ? Please clarify.

Collapse
 
sudarshansb143 profile image
sudarshan

You got that !

Because, we are serving the react build folder as the static asset of our nodejs backend 😃

Collapse
 
radkriss profile image
radkriss

Thanks for the clarification, Sudarshan.

One query which has been in my mind for a long time is => "Why do we need a Nodejs server? If my React app is connecting to an external api (Java for eg) can't we have just the React front end ?"

Thread Thread
 
sudarshansb143 profile image
sudarshan

it's absolutely fine !

You can use node.js, django, spring / struts, rails or anything. But, you have to find a way to serve assets using that specific framework or technology

Collapse
 
vanhung1999dev profile image
HungNguyen

this is so simple...great..:

Collapse
 
rajeshkumaryadavdotcom profile image
Rajesh Kumar Yadav

This is super interesting