[React] server & client 개발

페리·2021년 9월 6일
6
post-thumbnail

이번 프로젝트에서
front-end 개발은 react로,back-end 개발은 nodejs로 하게 되었다. (db는 mongoDB)

이때까지는 react 공부를 위해 client 위주로만 만들어보았기 때문에 server 단을 굳이 만들어보지 않았지만, 이제 본격적으로 api 사용을 위해 server 단을 구성해볼 필요가 있었다.

뭉뚱그려서 내가 만든 client 코드가 server로 전송하면 되면 '완성~!' 되는 것으로 알고 있었지만, 직접 실행을 해보려니 참 헷갈리는 부분이 많았다.

아무것도 몰랐던 때 궁금하던 것을 정리해보면 다음과 같다.


궁금증

  1. client랑 server를 어떻게 개발하지?

  2. client랑 server를 어떻게 각각 실행시킬까?

  3. client에서 개발한걸 어떻게 server로 전송시킬까?

  4. cafe24에 호스팅해야되는데, 어떻게 업로드 해야 하지?


아마도 react나 nodejs를 처음 접한 사람의 경우 나와 같은 고민을 해본 적이 있거나, 이 부분에 대해 배운 경험이 있을 것이다.

client는 react, server는 nodejs의 프레임워크인 express를 사용한다는 가정을 하고, 하나씩 정리해보도록 하겠다.


1. client와 server를 어떻게 개발하지?

- client 개발

client를 개발하는 방법은 react를 공부하다보면 자연스럽게 알게 된다.
create-react-app을 통해 react를 설치하고 실행하며 개발하는 것이 바로 그 첫 단계이다.

- server 개발

server의 정의는 다음과 같다.
서버는 클라이언트에게 네트워크를 통해 정보나 서비스를 제공하는 컴퓨터 시스템

원래는 Node.js로 서버 개발을 한다면, 기본적으로 routing(어떤 네트워크 안에서 통신 데이터를 보낼 때 최적의 경로를 선택하는 과정)을 하게 된다.

기본 프로젝트 구조

root

client/
models/
routes/
package.json

처음 시작하는 분들을 위한 상세 설명

프로젝트 이름은 project로 가정한다. 위와 같은 구조로 만들기 위해 다음 명령어를 입력하면 된다.

폴더를 만들고 싶은 경로에 시작

mkdir project && cd project
npx create-react-app client
mkdir models routes
npm init // packages.json을 만들 때는 엔터쳐서 생략해도 됨. 

위와 같이 설치하면 기본적인 파일 구조는 생성이 된다.
패키지 설치는 생략.

server.js

const express = require("express");

const app = express();

var defaultRouter = require("./routes/default");
var settingRouter = require("./routes/setting");

app.use("/", defaultRouter);
app.use("/setting", settingRouter);

/routers/default.js

const router = require("express").Router();

router.route("/page1").get((req, res) => {
	console.log("page1을 실행!");
});

와 같이 routing을 깔끔하게 관리할 수 있다.
(http://localhost:3000 을 입력받으면 defaultRouter에 있는 내용을,
http://localhost:3000/setting을 입력받으면 defaultRouter에 있는 내용을 보여준다.)

물론 Node.js 에서 뿐 아니라, react 내에서 react-router-dom이라는 라이브러리를 통해 직접 routing을 관리할 수도 있다.

그럴 때에는 페이지를 위한 routing 보다는, api 사용을 위한 라우팅으로 사용한다.

server.js

const express = require("express");

const app = express();

var userRouter = require("./routes/user");
var postRouter = require("./routes/post");

app.use("/api/user", userRouter);
app.use("/api/post", postRouter);

*user.js

const router = require("express").Router();

router.route("/").get((req, res) => {
	console.log("get user information");
});

router.route("/add").post((req, res) => {
	console.log("add user information");
});

이렇게 정의한 뒤에, client 단에서 /api/user, /api/user/add을 fetch 혹은 axios 등등의 함수로 사용하면 된다.

이 밖에도 server를 활용할 수 있는 방법은 많지만, 기본적인 기능만 적어보았다.


2. client랑 server를 어떻게 각각 실행시키지?

이에 대해서는 여러가지 방법이 있다.

(1) build 시키지 않고, client와 server를 port 번호를 다르게 설정하여 각각 실행시키는 방법

  • 이건 제일 간단한 방법인데, client의 포트가 3000 이라고 했을 때, server의 port 번호는 3001로 설정하여 각각 yarn start or npm run start, node server.js 로 client와 server를 각각 실행시키는 것이다.
    보통 client는 한번 실행을 시켜놓으면 내부 코드가 수정되어도 자동으로 적용이 되도록 할 수 있고, server는 nodemon을 사용하지 않으면 계속해서 다시 켜줘야하는 번거로움이 있다. (server를 실행시키는 것은 순식간에 되므로 그다지 번거롭지도 않다.)
    코드를 수정할 때마다 매번 build하고 실행시키고 확인하기에는 번거로우므로 개발 중일 때에는 이 방법을 사용해서 client & server를 실행시킨다.

(2) client를 build한 뒤에, server에서 client의 build/index.html을 참조하는 방법

  • client 개발이 끝났다면, npm run build를 통해 하나의 build 폴더를 만들고, server에서 client의 build/index.html 파일을 참조하는 방식으로 로드할 수 있다.

3. client에서 개발한걸 어떻게 server로 전송시킬까?

client, server에서의 실행 방식을 살펴보았다면, 각각 어떻게 구성해야될지가 궁금해진다.
client 단은 원래 모습 그대로 개발하고 build만 해주면 된다.
그러면 server만 잘 구성해주면 된다.

아래 파일 구조 예시는 client 개발이 끝나고 build가 되었다고 가정한 상태의 project 폴더 모습이다.

파일 구조 예시(/project)

/node_modules
/routes
/models
/uploads
packages.json
packages-lock.json
web.js
/client
 | /build
 | /src
 | /public
 | /node_modules
 | packages.json
 | packages-lock.json

/client 부분이 view를 나타내는 client 부분이 되고,
나머지 파일과 폴더들이 server 부분을 나타낸다. 특히 web.js가 server의 index.js를 나타내는 셈이 되므로 node web.js라는 명령어로 실행하게 된다.

이럴 때에 web.js 를 어떻게 구성하는지를 살펴보자.

web.js

const express = require("express");
const cors = require("cors");
const path = require("path");

const app = express();
const port = process.env.PORT || 8001;
app.use(express.static("uploads"));

'''
'''
'''

app.use(express.static(path.join(__dirname, "/client/build")));

app.get("/", function (req, res) {
	res.sendFile(path.join(__dirname, "/client/build/index.html"));
});

app.get("*", function (req, res) {
	res.sendFile(path.join(__dirname, "/client/build/index.html"));
});

app.listen(port, () => {
	console.log(`Server is running on port: ${port}`);
});

express.static 이라는 부분은, 특정 폴더 안의 파일들을 static 파일로 잘 보내주기 위한 함수이다. build 안에 있는 css js image 파일도 잘 사용하기 위함이다.

그리고 app.get("/", ~) 부분은 해당 서버에서 / 와 같이 루트 경로로 접속했을 때에 어떤 페이지를 보여줄 지 나타낸다.
원래는 app.get("/~~", ) 을 통해 각 페이지 별로 어떤 페이지를 보여줄 지를 나타내줘야하지만, react에서는 이미 react-router-dom을 통해 routing을 설정해주었기 때문에 서버에서는 routing을 해줄 필요가 없다.

그렇기 때문에 어떤 경로로 접근하던지 간에 react에서 나타내주면 되기 때문에 서버에서는 app.get("*", ) 와 같이 routing을 설정해주면 된다.

위와 같이 경로를 설정하면 /client 폴더의 /build 폴더에 있는 index.html 파일을 보여주게 되는 것이다.


4. cafe24에 호스팅해야되는데, 어떻게 업로드 해야 하지?

이제 내가 만든 사이트를 세상에 공유하기 위해 서버를 구매하던지, 서버 호스팅을 해야 한다.
이 프로젝트는 서버를 구매하기 보다는 cafe24 서버 호스팅을 이용했다.

cafe24에서 node.js 앱을 호스팅하는 방법은 아래와 같다.

1. cafe24 호스팅 신청

먼저 cafe24 홈페이지에서 nodejs 호스팅을 선택하여 적절한 서비스를 선택하여 결제한다.

이후 서버 승인 연락이 온 뒤부터 nodejs 앱을 업로드할 수 있게 된다.

2. 호스팅 관리를 클릭한다.

3. Public Key 생성

앱을 생성하기 전에 git을 public key를 생성해야 한다.
key 생성 방법은 git을 사용할 수 있는 git bash를 열어 다음 코드를 입력한다.

ssh-keygen -t rsa -C “키 파일의 별칭”

'키 파일의 별칭' 부분은 이메일 형식으로 작성해놓으면 된다.

그러면
Enter file in which to save the key 와 같은 질문이 나올 텐데, 그냥 엔터를 쳐주면 되고,
이후 사용할 비밀번호를 입력해주면 된다.

그렇게 되면, 위에 경로가 나타나는 곳에 id_rsa.pub 파일이 생성된다. 이 파일을 test editor로 열어서 모든 텍스트를 복사한다.

위의 부분에 Public Key 에 기존에 적어놓은 키 파일 별칭 이름을 입력하고, 복사해둔 Key를 하단에 입력하면 된다.

그러면 key가 생성된다.

4. App 생성

key를 생성하고 나면, [앱 생성 관리]에서 App을 생성하면 된다.

적당한 이름으로 app을 생성하고, 생성해둔 public key를 할당하면 끝이다.

그러면 나타나는 도메인과 저장소, 포트가 있을 것이다.
도메인은 현재 호스팅했을 때 나타날 도메인을 의미하고,
저장소는 나의 파일들을 업로드할 git 저장소,
포트는 말그대로 내가 사용할 포트 번호이다.

저장소 부분은 아마도

git abscdsaf@asdlkfjlaskdjf234

와 같이 되어있을 것이다.
저장소에서는 앞에 붙은 git이라는 단어를 제외한 나머지 문자열을 붙여 넣어야 한다. (abscdsaf@asdlkfjlaskdjf234)

5. git 저장소에 코드 업로드

server와 client 모두 개발했기 때문에 둘 모두를 업로드해야 한다.
client는 npm run build를 통해 build 된 폴더만 옮기면 된다.

git 업로드를 위한 폴더를 구성한다.

server는 build 필요없이 그 자체로 옮겨준다.

/project_upload/

/node_modules
/routes
/models
/uploads
packages.json
packages-lock.json
web.js
/build

위와 같이 구성해주면 된다.
물론 client와 server에서 포트 설정을 해준 것이 있다면, 새로운 서버에 맞게 8001 번으로 설정해야할 것이다.

폴더를 모두 구성했다면 git 설정을 해준다.

git init
git remote add origin <미리 받아놓은 저장소 주소>

git add *
git commit -m "first commit"
git push origin master

먼저 git 파일로 만들어주고,
저장소 주소로 remote 설정해준 뒤에 모든 파일들을 올리는 것이다.
참고로 여기서 gitignore로 숨길 파일이 전혀 없다. 모든 파일을 다올려야 한다. (.env, /node_modules, packages.json 등등)
(다시 적용해보니 /node_modules는 굳이 올리지 않아도 알아서 install 하는 것 같다. 고로 올리지 않아도 된다.)
그래야 server에서 인식하기 때문이다.

모든 파일을 올리기 때문에 git add * 부터 시간이 좀 걸리게 된다.

다 올리게 되면 사이트 업데이트 될 것이다.

만약 홈페이지를 작동했는데 화면이 안보이고 에러가 난다면, 로그를 확인하고 어떤 부분이 잘못인지 찾아가야 한다.


해보면서 오류가 나는 부분 정리

  1. cafe24에 올릴 때 .env파일을 만들어서 db 정보를 관리하려고 했는데, 왠지 모르게 process.env. 가 안먹었다. 물론 localhost에서 했을 때는 잘 됐는데, cafe24에 올릴 때 오류가 생겼다. dotenv pacakge를 require 해도 문제가 있었다.

  2. 원래는 포토갤러리라는 게시판에서 이미지를 올릴 때 image를 서버의 uploads라는 폴더에 올리고 싶었다. 근데 생각해보니까 cafe24는 git에 push 한 담에 그것으로 동작하는 구조인데, server에 저장이 될리가 없었다.... 그래서 firestorage에 저장하거나 EC2에 저장해야할 것 같다....

  3. password 설정할 때 bcrnyt 패키지를 사용해서 보안성을 강화하려고 했지만, cafe24에 올릴 때 이 패키지가 문제가 됐다. 그래서 일단은 그 부분을 지우고 한 상태이다.


혹시 1번에 대한 답을 아시는 분은 댓글 부탁드립니다...


참고 사이트

0개의 댓글