일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 제로베이스
- 개발
- 프론트엔드
- 코딩
- 프론트엔드 스쿨
- TypeScript
- 조건문
- 공식문서
- 타입스크립트
- TS
- 콜백
- 탄스택쿼리
- Tanstack Query
- JavaScript
- props
- JS
- hooks
- 부트캠프
- 개발공부
- components
- Tanstack
- 리액트
- react
- 개발자
- 인터넷
- 프론트
- HTML
- CSS
- 자바스크립트
- 리액트쿼리
- Today
- Total
SUE 개발 블로그
개인프로젝트 멍미팅 ! ( 24.03.04 ~ 03.29 ) 본문
제로베이스 학습을 어느정도 마치고 개인프로젝트 기간이 찾아왔었습니다.
주어진 카테고리 내에 저는 소셜 커뮤니티를 골랐고
반려견을 키우는 애견인들을 위한 산책 커뮤니티 멍미팅을 기획했습니다.
개인프로젝트이지만 마침 여유가 되는 지인분이 연습겸 서버를 만들어주겠다하여 값진 프로젝트가 되었다.
기획 단계는 피그마를 이용해 와이어 프레임 및 프로젝트에 필요한 페이지 및 기능등을 적으며 기획했습니다.
개인프로젝트 전에 진행한 리액트 과제에서 사용한 Vite를 사용해 React.ts로 작업을 시작했으며
React-router-dom v6, axios, zustand, TailwindCSS 라이브러리를 추가로 사용했습니다.
실시간 날씨 데이터 ( Open Weather API )
Open Weather API를 이용하여 서울을 기본으로
선택창에 있는 지역에 맞게 현재 날씨를 업데이트하여 보여줍니다.
다크모드
다크모드 버튼을 이용하여 테마를 변경할 수 있으며 로그아웃, 새로고침을 해도 그 테마가 유지됩니다.
로그인 ( 소셜 로그인, 로그아웃 )
카카오와 구글을 연동하여 로그인 후 접속할 수 있습니다.
카카오와 구글 연동시 기존 계정에서 유저의 정보를 받아오며 어떤 소셜로 로그인했는가에 따라
카카오와 구글 이용자를 구분도 해봤습니다. 글쓰기 & 마이페이지는 로그인 상태에서만 진입가능합니다.
마이페이지 ( 프로필 이미지, 닉네임, 반려견 등록 & 삭제 )
유저는 마이페이지에서 자신의 정보를 확인하고 프로필 이미지와 이름을 변경할 수 있으며
로그인시 카카오나 구글에 등록되어있는 이름, 이메일, 프로필 이미지를 불러옵니다.
변경된 데이터는 자신의 마이페이지와 게시글, 댓글에 모두 반영되며 로그아웃 후 재접속해도 유지됩니다.
또 자신의 반려견을 추가하고 삭제할 수 있습니다.
게시글 작성 ( 작성 및 수정, 삭제 )
제목, 이미지, 주소 ( 카카오 지도 API, 다음 주소 검색 API ), 시간, 내용을 입력하여 게시글을 게시할 수 있습니다.
게시글 작성시 이미지를 제외한 부분은 전부 작성해야 게시글이 등록됩니다. ( 유효성 검사 후 미충족시 alert )
작성이 완료되면 홈으로 이동하며 스크롤업하여 자신의 게시글을 바로 확인할 수 있습니다.
해당 유저가 작성한 게시글일 경우 로그인시 그 유저에게만 수정과 삭제 버튼이 보이며
수정을 통해 제목과 내용, 주소 및 시간을 변경할 수 있습니다. ( 제목이나 내용, 지도, 시간만 따로 변경가능 )
삭제버튼을 눌러 게시글을 삭제할 수 있습니다.
댓글, 좋아요 작성
비로그인 유저는 글쓰기, 마이페이지, 좋아요, 지도보기를 할 수 없습니다.
댓글창을 볼 수 있으며 댓글은 작성할 수 없고, 로그인 이후 좋아요, 지도보기, 댓글 작성 및 삭제를 할 수 있습니다.
좋아요 ( 즐겨찾기 ) 및 필터링 검색
최신순, 오래된순, 좋아요순, 댓글순으로 게시글을 필터링하여 볼 수 있습니다.
로그인시 검색창 옆의 즐겨찾기 버튼을 누르면 유저가 좋아요를 눌렀던 게시글만 보여주며 필터링이 가능합니다.
페이지네이션, 스크롤 업 버튼
한 페이지에 6개의 피드를 보여주며 페이지네이션으로 이동하며 게시글을 확인할 수 있습니다.
스크롤 업 버튼을 만들어 일정 이상의 스크롤이 다운되면 버튼이 나타나면 누를시 상단으로 이동하며 사라집니다.
반응형
화면의 크기에 따라 레이아웃이 변화하게 반응형으로 프로젝트를 제작하였습니다.
🗒️ 프로젝트 API 명세서 ( 노션 )
서버와 통신하기 위한 API 주소들은 포스트맨을 이용하다 차후에 노션을 이용해
명세서 페이지를 만들어 정리해가며 관리, 서버와 소통하며 작업을 이어나갔습니다.
💻 프로젝트 사용 기술 스택
Vite, React, TypeScript
React-Query, React-router-dom, Axios, zustand, TailwindCSS
yarn, Github, Notion, Vercel
📁 폴더 트리 구조
```
📦
├─ .eslintrc.cjs
├─ .gitignore
├─ README.md
├─ index.html
├─ package.json
├─ postcss.config.js
├─ public
│ ├─ thumbnail.png
│ ├─ favicon.png
│ └─ vite.svg
├─ src
│ ├─ App.css
│ ├─ App.tsx
│ ├─ assets
│ │ ├─ dog.mp4
│ │ ├─ noFeed.mp4
│ │ ├─ noPage.mp4
│ │ ├─ noProfile.jpg
│ │ ├─ react.svg
│ │ ├─ writeDark.png
│ │ └─ zustand.png
│ ├─ components
│ │ ├─ AddPet.tsx
│ │ ├─ CommentBar.tsx
│ │ ├─ CustomPagination.tsx
│ │ ├─ EditInfo.tsx
│ │ ├─ Feed.tsx
│ │ ├─ Footer.tsx
│ │ ├─ Header.tsx
│ │ ├─ Map.tsx
│ │ ├─ ScrollTopBtn.tsx
│ │ ├─ SearchBar.tsx
│ │ ├─ ThemeBtn.tsx
│ │ └─ weather
│ │ ├─ CitySelector.tsx
│ │ ├─ Loader.tsx
│ │ └─ WeatherBar.tsx
│ ├─ hooks
│ │ ├─ useComment.ts
│ │ ├─ useFeed.ts
│ │ ├─ useGetData.ts
│ │ ├─ useLikes.ts
│ │ ├─ useLogin.ts
│ │ ├─ usePageTitle.ts
│ │ ├─ useProfile.ts
│ │ └─ useWrite.ts
│ ├─ index.css
│ ├─ main.tsx
│ ├─ pages
│ │ ├─ Home.tsx
│ │ ├─ Kakao.tsx
│ │ ├─ Login.tsx
│ │ ├─ MyPage.tsx
│ │ ├─ NotFound.tsx
│ │ ├─ ProtectRoute.ts
│ │ └─ Write.tsx
│ ├─ store
│ │ └─ User.ts
│ └─ vite-env.d.ts
├─ tailwind.config.js
├─ tsconfig.json
├─ tsconfig.node.json
├─ vercel.json
├─ vite.config.ts
├─ vite
│ ├─ .gitignore
│ ├─ README.md
│ ├─ index.html
│ ├─ package.json
│ ├─ pnpm-lock.yaml
│ ├─ public
│ │ └─ vite.svg
│ ├─ src
│ │ ├─ App.vue
│ │ ├─ assets
│ │ │ └─ vue.svg
│ │ ├─ components
│ │ │ └─ HelloWorld.vue
│ │ ├─ main.js
│ │ └─ style.css
│ └─ vite.config.js
└─ yarn.lock
```
⏱️ 프로젝트 기간
2024 / 03 / 04 ~ 2024 / 03 / 29 ( 약 4주 )
🔥 프로젝트 과정중 겪은 트러블 슈팅들 🔥
1. Tailwind 설정 오류
평소와 다름없이 테일윈드로 스타일링을 하는데 테일윈드와 bg-brand 와 같이 커스텀한 설정값이 사이트에 적용되지 않았다. 알고보니 Vite 환경에서 Tailwind를 사용하려면 npm과 달리 추가로 설정해야할 것들이 있었다. 또한 CommonJS 와 ESM 두가지 문법을 하나의 파일에서 사용하고 있었기에 수정해주었다.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Install Tailwind CSS with Vite - Tailwind CSS
Setting up Tailwind CSS in a Vite project.
tailwindcss.com
[JS/Module] CommonJS와 ES Modules는 무엇일까?
1. CommonJS, ES Modules는 무엇일까? 우리는 JS 모듈을 내보내거나 가져올 때 2가지 방식을 사용한다. 첫번째 방법은 module.exports로 모듈을 내보내고 require()로 접근하는 CJS(CommonJS), 두번째 방법은 export
mong-blog.tistory.com
2. Vite 에서의 .env 방식 차이
CRA만 주구장창 사용했던 나에게 Vite는 낯설었다. 테일윈드 다음으로는 노출해서는 안돼는 환경변수를 .env에 정리하여 사용하는데 process.env 파일을 불러오지 못했었다. 찾아보니 Vite에서 환경변수 .env 설정과 받아오는 방법이 달랐다.
// 기존 환경
REACT_APP_API_KEY = **************************
const API_KEY = process.env.REACT_APP_API_KEY;
// 바이트 환경
VITE_REACT_APP_API_KEY_ **************************
const API_KEY = import.meta.env.VITE_REACT_API_KEY;
3. 실수로 API KEY를 노출하고 깃에 커밋해버렸다.
위에서 열심히 노출안되게 하려고 애쓰고 테스트하다가 API 키들이 노출되어 누구나 깃허브에서 볼 수 있게되버렸다 ... 다행히 어렵지 않게 git log 명령으로 노출전 시점으로 git reset, git push -f origin main 으로 되돌릴 수 있었다.
4. 백엔드와 내가 생각하는 통신 방식이 달랐다. ( 통신은 처음이라 ... 먄 )
분명 서로 상의한 기능을 만들고 통신을 붙여 작동을 확인하는데 계속해서 실패했었다. 날잡고 같이 얘기를 나눠보니 서로 방식이 달랐다. 사실 소통 문제도 있지만 내가 통신 코드를 짜보는게 처음인게 많이 미숙해서 멍청하게 작성했었다. 다행히 요청하는 방식을 알게되었고, 백엔드가 보내준 명세서에 맞게 코드를 작성하며 status 200을 보며 통신을 성공할 수 있었다. ( 이거 쾌감 지린다 )
const editUser = async (userData: any) => {
await axios.post(
"https://mungdata.net/api/info",
{
mode: "edit",
data: {
name: userData.name,
profile: userData.img,
},
},
{
headers: {
Authorization: "bearer " + token,
},
}
);
};
5. CORS 에러 발생 ( Cross-Origin-Resource Sharing )
프로젝트를 진행하던 도중 갑자기 그 유명한 CORS 에러가 발생했다. ( 피해갈 수 없구나 ) 이 부분에 대해서 백엔드에게 전했는데 무시무시한 악명과 다르게 잠시 수정하겠다더니 해결되었다. 생각보다 무안했지만 그래도 알아놔야지 하고 관련 글을 찾아봤다.
CORS 발생 원인과 해결 방법
CORS에 대해 간단히 알아보기
velog.io
CORS란? CORS를 해결해보자 | 구보현 블로그
CORS란? CORS를 해결해보자 20200522 프로젝트를 하면서 프론트에서 서버에서 제공한 API로 요청하자, CORS 에러가 발생했다. 지금까지 CORS에러를 해결하기만 하고 정확히 CORS가 무엇이고 어떻게 동작
bohyeon-n.github.io
6. 개인 정보, 게시글, 댓글 등등 새로 업데이트 된 데이터가 바로 랜더링되지 않아요.
통신결과 정상적으로 완료가 되지만 새로고침, 화면이동을 해야 업데이트된 데이터를 반영한 화면이 랜더링 되었다. ( 넘어갈 수 없다 ) 결국 팀프로젝트 때 사용하기로 했던 React-Query를 부랴부랴 학습하여 적용하였고 덕분에 업데이트 되는 데이터에 따라 랜더링되었다. 마이페이지에서 유저 정보 수정의 경우 꾀 많이 골치를 겪었는데 후기에서 더 자세히 후술하겠습니다.
사실 기간이 얼마 남지 않아 급하게 적용했기 때문에 리액트 쿼리는 팀프로젝트 시작전에 제대로 학습해보려합니다.
7. 글쓰기, 마이페이지에서 새로고침을 하면 로그아웃 된 상태로 그 페이지에 머물러있어요
로그인 상태가 아니라면 글쓰기와 마이페이지 상태에서는 접근할 수 없어야한다. 하지만 그 페이지에 머무른채로 새로고침시 ( 로그아웃 ) 그 페이지에 그대로 머물러있는 상태가 발생했다 ( 모든 유저가 로그아웃 버튼 눌러서 로그아웃을 착실히 한다는 생각이 잘못된 것 ) 어떻게 이걸 로그인 중인지 구분하여 진입하지 못하게 막을지 고민하다가 아래와 같은 방법을 사용해 방지할 수 있었다.
ProtectRoute를 만들어 children ( 글쓰기와 마이페이지 ) 을 받고 유저가 로그인 중이라면 토큰을 가지고 있을테니 토큰이 있을 경우 그대로 children을 보여주고 만약 토큰이 없는 상태라면 홈화면으로 보내게끔 만들어 설정해주었다.
8. Vercel 배포 오류 발생 ( 404 Not Found ! )
가비아에서 도메인을 구매 후 버셀로 배포한 사이트에 도메인을 연결했다. 이제 끝이구나 싶었는데 아니였다.
( 버셀은 https로 배포를 해주는데 내 프로젝트는 http API 주소를 호출해서 요청 거부 에러가 있었는데 서버도 배포해서 해결했다 )
카카오 로그인, 홈페이지를 제외한 페이지에서 새로고침시 내가 만든 <NotFound/>도 아닌 버셀 자체 404 에러가 뜨면서 기능이 막혔다. 똑같이 버셀로 배포한 동기분의 파일과 방식을 보니 다르지 않았는데 왜 나만 이렇게 오류가 발생하지? 좌절에 삽질을 반복했지만 ... 버셀 공식 문서에 이와 같은 문제에 대한 내용이 있었다.
Configuring Projects with vercel.json
Learn how to use vercel.json to configure and override the default behavior of Vercel from within your project.
vercel.com
프로젝트 파일 최상위에 vercel.json을 만들고 위와 같이 내용을 설정해준뒤 재배포하니 해결되었다.
9. 카카오지도 맵 생성이 안돼요. ( 나는 바보였다 )
로컬 환경에서는 아무 이상없이 작동하는 카카오 맵 생성이 되지않았다.
억 숨이 턱 막혔으나 내가 바보였다.
콘솔창에도 에러가 뜨지않아 네트워크 창에서 원인을 찾자 위와 같이 권한이 없다는 내용을 확인. ( 401 error 권한 관련 )
진짜 개멍청이 ...
10. 새로고침 할 때 마다 로그인이 풀려요 ! ( zustand persist )
이번에 zustand로 전역상태관리를 이용하면서 store를 만들고 이곳에 유저 데이터를 저장해서 사용하기로 했다. 장점으로는 Context API의 불필요한 랜더링을 방지하고 간결한 초기 설정과 복잡하지 않은 전역 변수를 관리하는데 편리했다. 또한 Provider로 감싸지 않아도 되기에 처음 사용에도 크게 불편하진 않았다. ( 타입스크립트 적용은 버벅였지만 ) 하지만 문제는 새로고침시 기존의 데이터들이 전부 날라가는 것이 문제였다.
실은 이 부분에 대해서 별 생각이 없었는데 배포 후 주변 사람들에게 테스트를 부탁하면서 로그인을 몇 번이나 반복해야 하나요, 새로고침 했더니 로그아웃 됐어요 라는 의견들이 쌓이며 아 내가 미숙했구나 싶었다. 생각해보니 로그아웃 기능을 만든 로그아웃 버튼이 존재하는데 새로고침으로 유사 로그아웃이 가능한 흐름이 이상하다 느꼈다. 그리고, 많이 불편해 하시길래 이건 그냥 넘어갈 문제가 아님을 인지했습니다.
그러던 중 persist 라는 기능이 존재함을 알게되었고 이를 적용해 state를 localStorage에 저장할 수 있었습니다. 개발자로써 사용자 입장에서 이용시 겪는 문제점 및 의문점에 대해 더 신중하게 기획해야함을 느꼈습니다. ( 지인이라도 냉정하게 평가해준다 )
🎀 프로젝트를 하며 느낀 점 🎀
매일 매일 시간 압박과 오류 투성이에 밤샘을 해가며 프로젝트를 이어나갔다.
힘든 것도 많았지만 그래도 배운점이 많았으며, 기획 단계가 더 중요함을 알게되었고
( 언제까지 어떤 기능 어떤 구성, 데이터를 어떻게 사용할 것인가 )
그래도 나만의 프로젝트를 만들어나가며 완성되가는 순간들은 즐거웠으며
실제로 존재하게끔 배포를 성공했을 때의 성취감은 남달랐다.
전역상태관리 zustand 써보기 라는 목표도 이뤘으며 사실
사용 전까지는 useContext 말고 왜 전역상태관리를 사용하지 ?
전역상태 ... 란 어떤거고 무엇을 이걸로 설정해서 써야하지란 고민이 많았는데
일단 학습해서 사용해보니 감이 잡히고 확실히 편리했다. ( store 만세 )
또 persist 란 기능에 대해서도 알고, 적용할 수 있는 기회를 얻게되었다.
또 프로젝트를 기획할 때 데이터 흐름 및 어떻게 사용할지 잘 구성해야함을 깨달았다.
마이페이지의 경우 쿼리로 받아오는 게시글 데이터 ( 그 안에 이름, 이미지, 펫들 등등 ... ) 를 이용해서
마이페이지에서 정보 수정 → 게시글 데이터 내 이름, 이미지, 펫이 바로 반영 →
useEffect 의존성 배열에 그 data를 넣어서 업데이트라는
기발한 초짜의 발상으로 작동은 되지만 지인 테스트 결과
게시글을 작성하지 않으면 프로필이 바로 랜더링 되지않는 문제를 겪었었다.
이에 대해서 조언을 받았는데 해당 페이지에서 사용하지 않는 데이터를
이런 방식으로 쓰는 것은 옳지않고 이해가 되지 않는다.
라는 말을 들으며 와 진짜 나 일단 만들어나가자란 마인드로 작업했구나를 통찰해버렸다.
다음 부터는 이러한 흐름도 잘 생각하고 기획해야겠음을 배웠다. 코드는 수정해서 현재 잘 작동한다.
실제 백엔드 서버와 ( 도와준 병규킴 고마워 ) 수차례 통신하는 과정도 너무 값진 경험이었고,
특히 배포는 정말 처음인지라 처음보는 에러들과 상황들에 많이 힘들고 지쳤었다. ( 그래도 포기 못해 )
그래도 이번에 겪은 문제 상황들을 토대로 같은 상황이 발생하면
어떤게 문제이고 어떻게 해결해야할지 경험치를 많이 쌓았다.
특히 데이터를 어떻게 받아와 어디에 어떻게 쓸 것인지 더 잘 구성을 생각해보며 설계하는 것과
클라이언트 입장에서 이용시 가질 수 있는 의문점과 불편함에 대해 한 번 더 생각하게되었네요.
( 따뜻하지만 에러라던가, 의문점은 날카롭게 지적한 동기 및 지인분들 감사합니다 🥹 )
마지막으로 배포하고 싶어 죽는 흔적들 ...
을 보며 할 수 없는게 아니라 될 때 까지 박치기하면 길이 보인다를 배웠다.
( 커밋 컨벤션을 지키지 못한 부분들이 너무 아쉽다 ... 밤샘에 피폐해져서 제정신 X 😭 )
GitHub - sueWavy/project_pet: 개인프로젝트 반려견 산책 커뮤니티 " 멍미팅 🐶 " 만들기
개인프로젝트 반려견 산책 커뮤니티 " 멍미팅 🐶 " 만들기. Contribute to sueWavy/project_pet development by creating an account on GitHub.
github.com
멍미팅
반려견과 견주님들의 산책 커뮤니티
www.mungmeeting.site
고마워요 많은 조언 및 도움을 준 승찬, 혜민, 병규, 규성, 멘토님들 !
'프로젝트' 카테고리의 다른 글
팀프로젝트 With Me ( 24.04.22 ~ 05.30 ) (0) | 2024.07.02 |
---|