dependencies": {
"express": "^4.18.2",
"nodemon": "^2.0.20"
}
const express =require('express');
const app =express();
const path =require("path");
const port = 8000;
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, '/client/build/index.html'));
});
// 8000 포트에서 서버가 열림
app.listen(port, ()=>{
console.log("open server", port)
})
url의 기본값이 '/'으로 서버가 열리면, build된 react 프로젝트의 내용이 담긴 client/build 폴더를 사용할 수 있다.
서버가 열리고, 상대경로가 '/'일때 즉, localhost:8000 일때 build/index.html 파일을 프론트엔드에 전달한다.
index.html이 프론트엔드에서 열리면서 index.html은 client/build에서 필요한 js,css등을 불어온다.
만약 react 프로젝트와 gitbhub 저장소를 연결 했다면 app.use와 app.get의 경로를 다르게 설정해주어야 한다. A 와 같이 경로를 설정한다면 404 에러가 발생한다.
👩💻 React와 Node.js 연동시 404 error 글 보러가기
<!-- ..... -->
<link rel="manifest" href="/manifest.json"/>
<title>React App</title>
<script defer="defer" src="/static/js/main.29dc12ff.js"></script>
<link href="/static/css/main.073c9b0a.css" rel="stylesheet">
<!-- ..... -->
<!-- ..... -->
<link rel="manifest" href="/저장소이름/manifest.json"/>
<title>React App</title>
<script defer="defer" src="/저장소이름/static/js/main.29dc12ff.js"></script>
<link href="/저장소이름/static/css/main.073c9b0a.css" rel="stylesheet">
<!-- ..... -->
⚠️ github 저장소와 연결된 react 프로젝트를 build하면, 그렇지 않은 경우와 달리 manifest.json과 css, js 파일의 경로 앞에는 저장소의 이름이 추가로 붙게 된다.
그렇기 때문에 app.use와 app.get의 경로를 다음과 같이 수정해주어야한다.
app.use('/저장소이름',express.static(path.join(__dirname, 'client/build')));
app.get('/저장소 이름' ,function (req, res) {
res.sendFile(path.join(__dirname, '/client/build/index.html'));
})
그리고 서버를 실핼 시킨 후에 localhost:8000/저장소이름 으로 들어가면, react 프로젝트가 잘 작동하는 것을 볼 수 있다.
server.js롤 작성한 node 서버를 실행시키려면 nodemon server.js 를 명령어를 사용하면 된다.
nodemone은 지정된 파일의 변화가 있을 시에 node를 다시 실행 시켜주는 모듈로, 다른 js나 css 파일의 변화도 감지하고 싶다면 nodemon -e js, html server.js 를 명령어로 사용하면 되고, package.json의 scripts에 해당 명령어를 추가해 보다 간편하게 사용할 수 있다.
"scripts": {
"dev": "nodemon -e js, html server.js"
}
app.get('/', (req, res)=>{
res.send("data")
// res.json("data")
})
//...
async function getData (){
const data = await (await fetch('/', {
method:"GET"
})).json()
...}
//...
try{
const data =await fetch('/', {
method:"GET"
}).json();
....
}catch(error){
....
}
위와 같이 data를 받아온다면 data는 Promise 상태가 된다.
이를 해결하기 위해서는 await fetch() 를 await로 다시 한번 더 감싸주어야한다. 그러면 fetch가 완료 후에 json 함수가 진행된다.
const data =await (await fetch('/', {
method:"GET"
}
)
).json()
만약, 서버로 특정한 데이터를 보내서 해당 데이터를 활용해 리소스를 만들어야하는 경우( ex : 외부에서 데이터를 가져오는 경우)라면 post 요청을 활용하면 된다.
프론트 엔드 requset의 body를 사용하기 위해서는 body-parser라는 모듈을 설치해야한다.
사전 작업 : npm i axios
외부에서 데이터를 가져오기 위해서 axios 모듈을 설치해야한다.
fetch는 웹브라우저에서 지원하는 API이기 때문에 백엔드인 node.js에서는 사용할 수 없다.
/src/App.js
const reqBody ={
apiUrl:url
};
try{
const data =await (await fetch('/', {
method:"POST" ,
headers:{
//json 형태로 받아옴 (option )
'Content-Type':'application/json'
},
body:JSON.stringify(reqBody)
})).json();
....
}catch(error){
....
}
/server.js
//....
const axios =require('axios');
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
//....
app.post ('/', async(req, res)=>{
const url = req.body.url;
try {
const result = await axios.get(url);
const response = result.data;
res.send(data);
} catch (error) {
const e =`[Error]:${error}`;
res.json({message:e});
}
})