A guide on getting a React and Node/Express Server to run parallel with one another
Contents
- Step 1: Setting up the Folder Structure
- Step 2: Creating the Node Backend using Express
- Step 3: Creating the React Frontend
- Step 4: Using the Concurrently Package to Connect Frontend and Backend
- Step 5: Connecting Frontend with Backend using Docker
- Starter Code
Step #1: Setting up the Folder Structure
Create a root directory folder for your project and initialize the project by running the following command in the terminal.
npm init -y
"This command will create the package.json file and ask a few questions regarding your app, but using the -y command gives the default answers for these questions. The package.json file keeps track of app scripts, modules, and any dependencies necessary for the Node app"
The folder structure should look like this so far:
> my-app
> node_modules
- Package-lock.json
- Package.json
Step #2: Creating the Node Backend Using Express
Within your app, create a folder called server and place a single file called index.js inside this folder. This index.js file will run the server.
In the terminal, install Express as a dependency using the following command.
npm i express
Place the following code inside the index.js file in our server folder.
// server/index.js
const express = require("express");
const PORT = process.env.PORT || 5000;
const app = express();
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);});
"Express will help create a basic web server for us that will run on port 5000 when running on your local machine."
In our package.json file, we can create a script that tells our app to run the server when called on our terminal. In this case, the script is npm start:
// server/package.json
...
"scripts": {
"start": "node server/index.js"
}
...
Run npm start in the terminal and we should see that it's running on port 5000:
npm start
> node server/index.js
Server listening on 5000
Now that our server is running, let's use our Node and Express server as an API so that we can get data and manipulate it. Let's have our React app say "Hello World" by using the server. Add the following code to the index.js file.
// server/index.js
app.get("/api", (req, res) => {
res.json({ message: "Hello World!" });});
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);});
"The code below creates an endpoint for the route /api. If our React app makes a GET request to that route, we respond (using res, which stands for response) with our JSON data. Keep in mind that you should place this above the app.listen function."
Let's restart our server since we made changes to our Node code. End the start script in the terminal by pressing Command/Ctrl + C. Then restart it by running npm start again. To test if the server works, you can visit http://localhost:5000/api in the browser and see a message with "Hello World."
Congrats! You have your backend server set up! Now let's move on the next step.
Step #3: Creating the React Frontend
Now that we have our backend, we can now move on to the frontend. To start, go to your terminal and use create-react-app to create a new React project with the name client. This will serve as the folder for the frontend.
npx create-react-app client
"This is a React shortcut for starter code that will create a React app with all of its dependencies installed."
Connecting to the backend is very simple as we will only need to add a property called proxy to our package.json file. Keep in mind that this package.json file is different from our server. This will be important later on.
The proxy property will allow us to make requests to our Node server without having to provide the origin it is running on (http://localhost:5000) every time we make a network request to it:
// client/package.json
...
"proxy": "http://localhost:5000",
...
Using the npm start script we can then run our React App. However, make sure to cd into the newly-created client folder first. Running this command will start up the app on localhost:3000:
cd client
npm start
Compiled successfully!
You can now view client in the browser.
Local: http://localhost:3000
Now that that's all set up, let's get both the client and server running at the same time!
Step #4: Using the Concurrently Package to connect Frontend and Backend
While we have a frontend and a backend connected, the issue with this setup is that we will need to run scripts on two different terminals in order to run both of them in parallel with one another. That's where the concurrently module comes in.
Before we move on, let's make sure our folder structure looks something like this:
> my_app
> client
> node_modules
> src
- package.json
> server
> node_modules
- index.js
- package.json
"Make sure the client and server have their own package.json files"
Concurrently is a package which can run multiple npm scripts simultaneously. Install concurrently using the following command.
npm i -D concurrently
Now that we have this package, all we have to do is change up our scripts in the package.json file in our server side.
...
"scripts": {
"server": "node server/index.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\""
}
...
"Notice how concurrently is run under the dev script and accessed both the server and client scripts"
Now when we run npm run dev, we should see that our client and server are running at the same time!
Step #5: Connecting Frontend with Backend using Docker
Creating a Dockerfile for React
Create a file name Dockerfile in the client folder and paste the following code.
FROM node:lts-slim
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
EXPOSE 3000
CMD [ "npm", "start" ]
"This will be our docker image instructions for our react app where our react app will get compiled and run."
Creating a Dockerfile for Server
Create a Dockerfile in the server folder. And make sure you have a dev script in your package.json. If you have different script for running your server, you can change the CMD instruction in the Dockerfile below.
FROM node:lts-slim
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
EXPOSE 5000
CMD [ "npm", "run", "dev" ] #You can change this script
Using Docker-compose to Run App
Docker-compose helps us combine and run mutiple Dockerfiles into a single network container. Make a file named docker-compose.yml in the root of the project and copy the following code.
version: "3"
services:
frontend:
container_name: awesome_web
build:
context: ./client
dockerfile: Dockerfile
image: user/awesome_web
ports:
- "3000:3000"
volumes:
- ./client:/usr/src/app
backend:
container_name: awesome_server
build:
context: ./server
dockerfile: Dockerfile
image: user/awesome_server
ports:
- "5000:5000"
volumes:
- ./server:/usr/src/app
Finally, we'll have a folder structure somewhat like this.
> awesome_project
> client # This is our react front-end
> node_modules
> src
- Dockerfile
- package.json
> server # This is our Node.js server
> node_modules
- index.js
- Dockerfile
- package.json
- docker-compose.yml
Lastly, you need to change the proxy field in the client/package.json like this:
{
"proxy" : "http://backend:5000"
}
"Backend is the name of our backend service in the compose file"
Now we can run our project by running following command. This will create docker images and volumes which will run in the containers.
$ docker-compose up
If you want to build your images before starting your containers.
$ docker-compose up --build
Congrats! You now have a full stack application up and running!
Comentarios