Create Simple POS With React, Node and MongoDB #4: Optimize App and Setup Deployment Workflow

 

Create Simple POS With React, Node and MongoDB #4: Optimize App and Setup Deployment Workflow

Create Simple POS With React, Node and MongoDB #4: Optimize App and Setup Deployment Workflow

Before we add more features to our POS app, we need to optimize and restructure the app for better performance and clarity. Also, we will introduce a deployment pipeline so that when we commit code changes to GitHub, the app is automatically deployed to Heroku and Netlify.

This is the list of the tasks we have to complete during this chapter.

  • [ ] separate backend and frontend
  • [ ] add environment variables to the backend
  • [ ] add environment variables to frontend
  • [ ] separate to individual route
  • [ ] setup auto-deployment of backend and frontend through Github

So, let’s get started.

[✔️ ] Separate backend and frontend

We will remove the backend folder from the backend folder and move it outside. We also need to uninstall and reinstall the node modules.

BASICPOS folders

BASICPOS folders

[✔️ ] Add an environment variable to the backend

We will install the dotenv package to easily maintain keys and prevent API keys from being exposed to the outside world.

npm install dotenv

Import the package to index.js.

require("dotenv").config({ path: __dirname + "/.env" });

Create a .env file in the root directory and add our API key to the file in a key-value structure.

MONGODB_URL=mongodb://localhost:27017/basicpos
JWT_SECRET=qwertyuiopasdfghjklzxcvbnm123456
SENDGRID_API_KEY=SG.EaHyDwHnQN6I4SXQKaNo6g

Replace the keys we previously used in backend files using process.env.<key-name>.

sgMail.setApiKey(
   process.env.SENDGRID_API_KEY
);

[✔️ ] Add an environment variable to frontend

When using create react app, it is easier to maintain the environment variables. You can refer to the official document to see find out more details.

  1. Create .env file.
  2. Add a new variable to the .env file ( have prefix REACT_APP_ ). eg.REACT_APP_API_URL=http://localhost:8080/
  3. Replace the old static string.
    axios
    .post(process.env.REACT_APP_API_URL + "login", values)
  4. Restart the server.

[✔️ ] Separate routes

As our app expands and the number of routing endpoints increases, keeping all route access points in a single index.js file is not a good practice. Therefore, we reorganize our backend by moving all the routes to a new folder which has a main route access point. Then, we need to import these routes to the index.js file.

First, we will create a new api.js file and configure it as the main route access point.

const express = require("express")
const router = express.Router()
require("./db")
router.use(require("./api_auth"))
<em class="markup--em markup--pre-em">// router.use(require("./api_product"))
</em><em class="markup--em markup--pre-em">// router.use(require("./api_employee"))
</em><em class="markup--em markup--pre-em">// router.use(require("./api_customer"))
</em><em class="markup--em markup--pre-em">// router.use(require("./api_pos_machine"))
</em><em class="markup--em markup--pre-em">// router.use(require("./api_branch"))
</em>module.exports = router

The commented routes will be taken into use in the upcoming chapters.

Now, create a file named api_auth.js inside the route older and move all the routes that relate to authentication from index.js into this. Here, replace the occurrences of ‘app’ with ‘router’.

const express = require("express");
const router = express.Router();
const Users = require("./models/user_schema");
const jwt = require("./jwt");
const bcrypt = require("bcrypt");
const formidable = require("formidable");
const path = require("path");
const fs = require("fs-extra");
const jsonwebtoken = require("jsonwebtoken");
const sgMail = require("@sendgrid/mail");
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
router.post("/login", async (req, res) =&gt; {
.......//colapse code
});
router.post("/register", async (req, res) =&gt; {
.......//colapse code
});
router.get("/activation/:token", async (req, res) =&gt; {
 .......//colapse code
});
router.post("/profile", async (req, res) =&gt; {
.......//colapse code
});
uploadImage = async (files, doc) =&gt; {
.......//colapse code
};
router.put("/profile", async (req, res) =&gt; {
.......//colapse code
});
router.post("/password/reset", async (req, res) =&gt; {
.......//colapse code
});
router.put("/password/reset", async (req, res) =&gt; {
.......//colapse code
});
module.exports = router;

Import api.js to index.js.

app.use("/api/v1", require("./api"))

[✔️ ] Separate repository

Creating a new repo

Creating a new repo

We need to create a new repository for the backend.

Pushing the locally changed code to GitHub.

Pushing the locally changed code to GitHub.

Push the locally changed code to GitHub.

[✔️ ] Deploy Node backend to Heroku

Deploy Node backend to Heroku

Deploy Node backend to Heroku

Setting up automatic deployment from Github

Setting up automatic deployment from Github

Heroku is one of the top cloud providers that provide a simple way to deploy apps using Nodejs backend. Before deploying to Heroku, we need to build the app. This can be achieved by setting up automatic deployment from Github so that the whole process takes just one click.

Set up auto-deploy from Github.

Set up auto-deploy from Github.

Set up auto-deploy from Github.

Select the auto-deploy option to the auto-deployment.

Select the auto-deploy option to the auto-deployment.

Select the auto-deploy option to the auto-deployment.

Setup env key in Heroku

Adding all the environment variable keys into Heroku setting

Adding all the environment variable keys into Heroku setting

We need to add all the environment variable keys into Heroku setting

We need to configure the app to use the Heroku port. Add the following code line to achieve this:process.env.PORT

app.<strong class="markup--strong markup--pre-strong">use</strong>("/api/v1",<strong class="markup--strong markup--pre-strong">require</strong>("./api"))
const port = process.env.PORT || 8080;
app.<strong class="markup--strong markup--pre-strong">listen</strong>(port, () =&gt; {<strong class="markup--strong markup--pre-strong">console</strong>.<strong class="markup--strong markup--pre-strong">log</strong>("Server is running... on port " + port);

Heroku auto-deploy activity in the Activity tab

Heroku auto-deploy activity in the Activity tab

Now, every time you push the code to GitHub you will see Heroku auto-deploy activity in the Activity tab.

Now try to open the app.

Open the app

Open the app

Viewing the app log to figure out the problem

Viewing the app log to figure out the problem

We are getting a not found error. In Heroku, if something goes wrong, you can view the app log to figure out the problem.

[✔️ ] Setup auto deployment from GitHub to Netlify

We can use Heroku to host the frontend. But we have another better option to use Netlify. Netlify is a dedicated service for static hosting.

Get the backend API url to be used in the frontend.

Get the backend API url to be used in the frontend.

Get the backend API url to be used in the frontend.

Creating a new site -1

Creating a new site -1

Creating a new site -2

Creating a new site -2

Deploy settings

Deploy settings

Getting started

Getting started

Here, you can see deploy activities.

Deploy activities

Deploy activities

Now we can open our live app hosted on Netlify.

Opening app on Netlify

Opening app on Netlify

You can see a demo of the application here.

Conclusion

In this chapter, we learned how to setup environment variables on Node and React. Then we learned how to use the express router to organize the backend structure. Finally, we learned how to set up auto-deployment from Github to Heroku and Netlify.

Git repos:

https://github.com/krissnawat/basicpos-backend

https://github.com/krissnawat/basicpos-frontend

Credit

The post Create Simple POS With React, Node and MongoDB #4: Optimize App and Setup Deployment Workflow appeared first on Soshace.

Source: Soshace