[Go!Street] MERN STACK으로 혼자 구현해보는 커뮤니티 사이트 1️⃣

Beanxx·2022년 10월 26일
0

Go!Street Project 🚚 

목록 보기
1/3
post-thumbnail

💡 MERN STACK

MongoDB, Express, React, Node

아무래도 서버쪽은 구현이 익숙하지 않기 때문에 나중에 다시 해보려면 기억이 잘 안 날 것 같아서 express 기초 세팅 & mongoDB 연결부분 위주로 구현 과정 기록해놓기 ✍️

🕰 구현 순서

1. [Client] React로 기초 세팅
2. [Server] Express로 기초 세팅
3. [Server] mongoDB 연결
4. [Client] axios로 서버에 요청보내보기
5. [Client] Cors 설정
6. [Server] `mongoose`로 스키마 작성하기
7. [Client] react-bootstrap 적용
8. [Client] Emotion 적용

🔗 설치해야 할 모듈들

cd client

npm i react-router-dom@6
npm i axios --save
npm i http-proxy-middleware --save
npm i react-bootstrap@5.1.3
npm i @emotion/css @emotion/react @emotion/styled

# 빌드한 파일과 서버를 연결해야 함
npm run-script build

# ----------------------------

cd server

npm init -y  # 기본 package.json 생성
npm i express --save
npm i path --save # server 파일 경로와 client 파일 경로 합쳐주는 모듈
npm i mongoose --save # mongoDB와 node.js를 연결시켜주는 드라이버

# package.json -> "scripts" -> "start": "nodemon index.js"

📚 FE (React)

✅ JSX

  • CamelCase 원칙 - ex. className
  • js: {}
  • css, style: {{}} + object
    // jsx내에선 {}로 js문법을 써줘야 하는데 이 안에서 객체 형태로 써줘야 해서
    // inline style 지정시 {{ }} 요런 형태로 style를 지정해줘야 했던 것!
    // 무작정 저렇게 쓰는구나해서 잘 안 외워졌는데 이젠 안 까먹을듯?
    <div style={{ fontSize: "1rem" }} />

✅ event.target.value 대신 event.currentTarget.value 사용도 가능하다

✅ 데이터 추가 함수

const [content, setContent] = useState("");
const [contentList, setContentList] = useState([]);

// 기존 contentList에 content 데이터 추가하기
const onSubmit = () => {
	let tempArr = [...contentList];
	tempArr.push(content);
	setContentList([...tempArr]);
}

✅ Router 설정

// index.js

import { BrowserRouter } from 'react-router-dom';

<BrowserRouter>
	<App/>
</BrowserRouter>
// App.js

function App() {
	return (
		<>
			{/* Route 밖에 작성한 컴포넌트는 항상 보임! */>
			<Heading/>
			<Routes>
				<Route path="/list" element={<List/>}/>
			</Routes>
		</>
	)
}

✅ useEffect()

useEffect(() => {
	// 컴포넌트가 나타날 때 실행될 코드
	return () => {
		// 컴포넌트가 죽을 때 실행될 코드
	}
}, []) 

✅ React-Bootstrap 적용

공식문서에 나와있는 link 태그쪽 코드 복붙하기
🔗 React-Bootstrap 공식 문서

// public/index.html
<head>
	...
	<link
	  rel="stylesheet"
	  href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css"
	  integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi"
	  crossorigin="anonymous"
	/>
</head>

✅ axios 요청

useEffect(() => {
  let body = {
    text: "Hello",
  };
  axios
    .post("/api/test", body)
    .then((response) => {
      console.log(response);
      setText(response.data.text);
    })
    .catch((error) => {
      console.log(error);
      });
}, []);

✅ Cors 설정

const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = function (app) {
  app.use(
    "/api",
    createProxyMiddleware({
      target: "http://localhost:4000", // 서버 포트 설정해주기
      changeOrigin: true,
    })
  );
};

📚 BE (Express & MongoDB)

먼저 server 폴더 내에 index.js 파일 기본 설정해주기

// server/index.js

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

const app = express();
const port = 4000; // 포트 번호 4000번으로 설정

// path 모듈 사용 (server & client folder를 join으로 합쳐주기)
// build 폴더명까지 작성 주의! (여기엔 파일명 작성 X)
app.use(express.static(path.join(__dirname, "../client/build")));

// [body-parser] client에서 보내는 body 명령어 추적 가능해짐!
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// https://localhost:4000/ 으로 빌드한 client 파일 연결
app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "../client/build/index.html"));
});

// 모든 path로도 빌드한 client 파일 연결되도록 설정
app.get("*", (req, res) => {
  res.sendFile(path.join(__dirname, "../client/build/index.html"));
});

다음으로 mongoDB를 서버에 연결할건데 git에 바로 올리면 mongoDB pw가 노출되니까 따로 파일을 추가해서 이 파일은 .gitignore 설정해준다!

// sever/config/dev.js
// git에 mongoDB PW 올라가지 않도록 따로 파일 생성해서 .gitignore에 따로 설정해주기
module.exports = {
  mongoURI:
    "mongodb+srv://[ID]:[PW]@cluster0.amddoze.mongodb.net/[DATABASE_NAME]?retryWrites=true&w=majority",
};

// [ID], [PW] 자리에는 자신이 설정한 id, pw를 넣어주면 된다.
// [DATABASE_NAME] 자리에는 원하는 데이터베이스 이름을 넣어주면 된다.(이건 옵션으로 따로 설정안해줘도 됨)

다시 index.js 파일로 돌아와서 위에서 따로 설정한 mongoDB 연결 코드를 import해서 mongoDB를 서버에 연결해주기

// server/index.js

const config = require("./config/key.js"); // mongoDB pw 가져오기

// mongoDB 연결
app.listen(port, () => {
  mongoose
    .connect(config.mongoURI) //mongoURI은 다른 폴더에선 export해준 url 넣어줌
    .then(() => { // DB가 성공적으로 연결되었으면 then문 실행
      console.log(`Example app listening on port ${port}`);
      console.log("connecting MongoDB...");
    })
    .catch((err) => {
      console.log(`${err}`);
    });
});

이제 Model 폴더를 새로 생성한 후, DB 모델을 설정해준다.

// server/Model/Post.js
// Mongoose Schema 생성

const mongoose = require("mongoose");

const postSchema = new mongoose.Schema(
	// 스키마에 넣을 데이터 형식 설정
  {
    title: String,
    content: String,
  },
  { collection: "posts" } // collection 이름
);

<br/>

// 위의 스키마로 Post라는 모델를 생성하고 모델을 export해서 index.js에서 사용하기!
const Post = mongoose.model("Post", postSchema);

module.exports = { Post };

위에서 설정해준 DB 모델을 다시 index.js 파일 내에 불러와서 사용하기! (요청, 응답 확인)

// server/index.js

const { Post } = require("./Model/Post.js"); // mongoose schema import

// client에서 /api/test로 보낸 요청 받기
app.post("/api/test", (req, res) => {
	// 생성된 Post 스키마에 임시적으로 아래 데이터 전달 (MongoDB에 데이터 저장)
  const CommunityPost = new Post({ title: "test", content: "testing" });

	// 성공적으로 MongoDB에 데이터가 저장되었으면 아래 코드 실행
  CommunityPost.save().then(() => {
    res.status(200).json({ success: true });
  });
});

여기까지 구현하면 일단 mongoDB 내에 데이터가 들어온 것을 확인할 수 있다.
또한 콘솔로 성공적으로 요청이 받아와진 것도 확인 가능!

스크린샷 2022-10-26 오후 4 52 05 스크린샷 2022-10-26 오후 4 52 42

📚 DB (MongoDB)

1. MongoDB Atlas 접속해서 로그인
2. Deploy a cloud database → Shared(FREE) 선택
3. 한국 선택, Username & Password 설정 (기억해야함!)
4. My Local Environment 선택
5. IP Address → 0.0.0.0/0 입력 (어느 IP주소로도 접속 가능하도록 설정)
6. Connect → Connect your application 선택
7. mongodb+srv~ 코드 복사

이젠 CRUD 기능을 구현해보자아 💫

profile
FE developer

0개의 댓글