“This is the fifth day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.
preface
We all know React is great and awesome, so we can use create-React-app to quickly build a front-end application. However, React builds only front-end static resources (such as HTML, CSS, JS, etc.), which cannot be deployed independently. We also need a WEB server and API calls. In this article, I’ll create a full-stack project using React and NodeJS. This section describes how to use Node.js as a Web server to load static resources created by React and how to use the React application to call the NodeJS API directly.
The preparatory work
Before you start, make sure you have Node and NPM installed on your computer.
Create a project directory
First we use the command line to create a directory of my-app and enter my-app
$ mkdir my-app
$ cd my-app
Copy the code
Initialize the React program
Then create a React program using create-react-app. This is the client code, so we call it client
$ npx create-react-app client
Copy the code
Use NodeJS to implement our API
Create API directory
$ mkdir api
$ cd api
Copy the code
Initialize the nodeJS project
npm init -y
Copy the code
Express.js is a very lightweight Node.js framework that installs Express.
npm i --save express
Copy the code
In the API folder, create server.js
// api/server.js
const express = require("express")
const app = express()
app.use(express.json());
app.get("/".function(req, res) {
res.send("It's working!")
})
app.listen(3000.() = > {
console.log("app listening on port 3000")})Copy the code
Start the API service on port 3000
Add the startup script in the scripts section of package.json
"scripts": {"start": "node ./api/server.js"
}
Copy the code
Then run it, visit http://localhost:3000, and you can see the following in your browser.
npm start
Copy the code
React access the API
The data returned in the./ API /server interface is JSON
app.get("/".function(req, res) {
res.json({"name": "Zhang"})})Copy the code
Change. / client/SRC/app. Js
import React, { useEffect, useState } from "react";
export default function App() {
const [name, setName] = useState("");
useEffect(() = > {
fetch("http://localhost:3000")
.then((res) = > res.json())
.then((data) = >setName(data.name)); } []);return <div>Hello {name}</div>;
}
Copy the code
This will not be visible on the page. If you look at the Chrome console, you will see the following prompt.
This is because a cross-origin request occurs when the Fetch request is made. To solve this problem:
Plan a
To change the interface to allow cross-domain, we need to install this package before cORS:
npm install --save cors
Copy the code
Change./client/ SRC /app.js to reference this function via middleware.
const cors = require("cors")
app.use(cors())
Copy the code
Then stop the service, NPM start restarts, and you can see the effect.
Scheme 2
Create-react-app supports interface proxy Settings
The development environment
Set in the client/package. Json
proxy:localhost:3000
Copy the code
You can then use relative path requests in JSX
useEffect(() = > {
fetch("/api")
.then((res) = > res.json())
.then((data) = >setName(data.name)); } []);Copy the code
The production environment
Add the following code to serve.js:
if(process.env.NODE_ENV==='production') {// Point the static resource to 'client/build'
app.use(express.static(path.resolve(__dirname, '.. /client/build')));
// The interface is prefixed with API
app.get("/api".(req, res) = > {
res.json({ message: "Hello from server!" });
});
// Any other unprocessed interface returns index.html
app.get(The '*'.(req, res) = > {
res.sendFile(path.resolve(__dirname, '.. /client/build'.'index.html'));
});
}
Copy the code
NPM installs the cross-env package to differentiate between development and production environments.
Change Settings in API /package.json
{
"scripts": {
"dev": "cross-env NODE_ENV=development node ./api/server.js",
"start": "cross-env NODE_ENV=production node ./api/server.js"
}
}
Copy the code
Plan 3
Development environment or use proxy proxy, production environment using nGINx reverse proxy.
I use Docker-compose locally
Use the following docker-comedy.yml
web:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "8080:80"
Copy the code
Create nginx.config in the root directory
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;keepalive_timeout 65; gzip on; upstream server { server server:3001; } upstream web { server web:3000; } server { listen 80; server_name localhost; location / { proxy_pass http://web/; } location ^~ /api/ { proxy_pass http://server/api/; }}}Copy the code
Start the container service
docker-compose up -d
Copy the code
Then go to http://localhost:8080 and you can see it in your browser.
The last
Guys, which solution would you use? Leave a comment in the comments section.
I hope this article was helpful to you, and you can also refer to my previous articles or share your thoughts and insights in the comments section.