-
๊ธฐํ ๋ฐฐ๊ฒฝ: ์ปดํจํฐ์ ํจ๊ป ์ค๋ ์๊ฐ ์๋ฆฌ์ ์์์ ๋งค์ผ ํ๋ฒ๊ฑฐ(๐)๋ฅผ ๋จน๊ณ ์๋ ์ ๋ฅผ ๋ฐ๊ฒฌํ๊ณ , ์ผ์๋ณ๋ก ์๋จ์ ๊ธฐ๋กํ๊ณ ๊ด๋ฆฌํ๋ ์๋น์ค์ ๋ํ ํ์์ฑ์ ๋๊ผ์ต๋๋ค.
-
ํ ์ค ์ค๋ช : ์๋จ์ ๊ฒ์/๊ธฐ๋ก/๋ถ์ํ์ฌ ํจ๊ณผ์ ์ผ๋ก ์์ต๊ด์ ๊ด๋ฆฌํ ์ ์๋๋ก ํ๋ ์๋น์ค์ ๋๋ค.
-
๋์: ์๋จ ๊ด๋ฆฌ๊ฐ ์ด๋ ค์ด ์ฌ๋๋ค
-
๊ฐ์ธ ํ๋ก์ ํธ
-
๊ฐ๋ฐ ๊ธฐ๊ฐ: 2023/07 ~ ์งํ ์ค
-
๋ฐฐํฌ ์ฃผ์: https://nutrinotes.net
๐ฅ ์๋จ ๋๋ฌ๋ณด๊ธฐ
์นดํ
๊ณ ๋ฆฌ๋ณ ์๋จ์ ์บ๋ฌ์
๋ก ๋๋ฌ๋ณผ ์ ์๊ณ , ๊ฐ ์๋จ ์นด๋๋ฅผ ์ ํํ๋ฉด ์์ธ ์์ ์ฑ๋ถ์ ํ์ธํ ์ ์์ต๋๋ค.
๐ ์๋จ ๊ฒ์
์ธ๋ถ API(EDAMAM)์์ ๊ฐ์ ธ์จ ์๋จ์ ๊ฒ์ํ๊ณ , ์์ธ ์์ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
โ๏ธ ์๋จ ๊ธฐ๋ก
์บ๋ฆฐ๋์์ ์ผ์๋ฅผ ์ง์ ํด ์๋จ์ ์ ์ฅํ์ฌ ๋์๋ณด๋์์ ํด๋น ์ผ์์ ์ ์ฅ๋ ์๋จ๊ณผ ์์ ์ฑ๋ถ์ ๋ถ์ํด ์๊ฐํํ ์ฐจํธ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
๐ ํ์ ๊ฐ์ & ๋ก๊ทธ์ธ
JWT๋ฅผ ํ์ฉํ ํ์๊ฐ์
๋ฐ ๋ก๊ทธ์ธ์ ๊ตฌํํ์ต๋๋ค. React Hook Form๊ณผ Zod๋ฅผ ์ฌ์ฉํด ํ์
์์ ์ฑ์ ๋ณด์ฅํ๋ ์คํค๋ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํผ์ ๊ด๋ฆฌํ๊ณ , debounce๋ฅผ ์ฌ์ฉํด ์ด๋ฒคํธ ์ค๋ณต ํธ์ถ์ ๋ฐฉ์งํ์์ต๋๋ค.
1. ์น ์ฌ์ดํธ ์ฑ๋ฅ ์ต์ ํ
ํ๋ก ํธ์๋ ์ฑ๋ฅ์ด ์ฌ์ฉ์ ๊ฒฝํ์ ์ํฅ์ ๋ฏธ์น ์ ์๋ค๋ ๊ฒ์ ์๊ณ , ๊ฐ์ ์ ์ ์ฐพ๊ณ ์ ํ์ต๋๋ค. (๋ธ๋ก๊ทธ)
-
์ด๊ธฐ ๋ฒ๋ค ์ฌ์ด์ฆ ๊ฐ์๋ฅผ ํตํ ์ด๊ธฐ ๋ก๋ฉ ์๋ ํฅ์
-
๋ถํ์ํ ํจํค์ง ์ ๋ฆฌ. ํฐ ๋ถ๋ถ์ ์ฐจ์งํ๋ Lodash์ ๊ฒฝ์ฐ, ํธ๋ฆฌ์์ดํน์ ์ํด default import๋ก ํ์ํ ํจ์๋ง ๋ฐ์์ค๋๋ก ์์ .
-
ํ์ด์ง ๊ธฐ๋ฐ dynamic import๋ฅผ ํตํด ํ์ํ ์์ ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋ก๋ํ์ฌ ์ด๊ธฐ์ ๋ก๋ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฒ๋ค ์ฌ์ด์ฆ๋ฅผ ๊ฐ์.
-
-
์ด๋ฏธ์ง ๋ ์ด์ง ๋ก๋ฉ์ ํตํ ์ด๋ฏธ์ง ๋ก๋ฉ ์ต์ ํ
-
loading=lazy
๋ฅผ ํ์ฉํ๊ณ , ์ด๋ฅผ ์ง์ํ์ง ์๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ํด IntersectionObserver๋ฅผ ์ฌ์ฉํ LazyImg ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ์ฌ์ฉ.useObserver
ํ ์์ ์ต์ ๋ฒ๋ฅผ ์์ฑํ์ฌ ๊ณต์ ํ๊ณ , ๋ทฐํฌํธ์ intersectingํ๋ ๊ฒฝ์ฐ, ์ ํด์๋ ์ด๋ฏธ์ง๋ฅผ ๊ณ ํด์๋ ์ด๋ฏธ์ง๋ก ๋ณ๊ฒฝ. -
์ด๋, ์ ์ํ ์ ์ ์ด๊ธฐ ํ๋ฉด์ ๋์ค๋ ์ด๋ฏธ์ง๋ฅผ ๋ ์ด์ง ๋ก๋ฉํ์ง ์์์ผํ๋ค๋ ๊ฒ. ๋ถํ์ํ ๋ฆฌ์์ค ๋ก๋ ์ง์ฐ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์บ๋ฌ์ ์ ์ฒซ ํ์ด์ง์๋ EagerLoad ์ด๋ฏธ์ง๋ฅผ, ์ดํ์๋ LazyLoad ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉ.
-
-
๋ฐ์ดํฐ Prefetch ๋ฐ Preload๋ฅผ ํตํ render-as-you-fetch
-
React Router์
loader
๋ฅผ ํ์ฉํด ๋ผ์ฐํธ ์ง์ ์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ prefetchํ๊ณ , ์ดํ TanStack Query์useQuery
๋ฅผ ํ์ฉํด ์บ์ฑ ๋ฐ ๋ฌดํจํ. -
prefetchQuery
๋ฅผ ํตํด ์ ์ ์ธํฐ๋์ (e.g. ๊ฒ์ ํค์๋ hover) ๋ฐ์ ์ ๋ฐ์ดํฐ๋ฅผ prefetchํ์ฌ ์ต๋ํ ๋น ๋ฅด๊ฒ ๋ก๋ฉ์ ์์ํ๊ณ ,useQuery
์์ ์บ์ฑ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉ
-
๐ญ ์น ์ฑ๋ฅ ๊ฐ์ ์ ํตํด FCP 0.6์ด, LCP 1.5์ด ๊ฐ์ ํ์ฌ ์ด๊ธฐ ๋ก๋ฉ ์๋๋ฅผ ๋จ์ถํ์ต๋๋ค. ์ด ๊ณผ์ ์์ ๋คํธ์ํฌ ์์ฒญ ์ ๋ก๋ฉ์ ์ต์ ํํ๊ธฐ ์ํด ๊ณ ๋ คํด์ผ ํ ์์๋ค์ ์๊ณ , ์ํฉ์ ๋ฐ๋ฅธ ์ ์ ํ ์ต์ ํ์ ์ค์์ฑ์ ๊นจ๋ฌ์์ต๋๋ค.
์์ฌ์ ๋ ์ ์ ํ์ฌ third-party api๋ฅผ ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ ํฐ ์ํฅ์ ๋ฏธ์น ์ ์๋ ์ด๋ฏธ์ง ์์ถ, WebP, AVIF์ ๊ฐ์ ์น ํ์ด์ง์ ์ต์ ํ๋ ํ์์ ์ฌ์ฉํ์ง ๋ชปํ๋ ์ ์ ๋๋ค. ์ถํ ๋ฐฑ์๋์์ ๊ฐ๋จํ ์์ ๋ฟ๋ง ์๋๋ผ ์ด๋ฏธ์ง๋ฅผ ์ง์ ๊ด๋ฆฌํ๋ค๋ฉด ๋ ํจ์จ์ ์ธ ๊ฐ์ ์ด ๊ฐ๋ฅํ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค.
2. ์ ๊ทผ์ฑ ๋ฐ SEO ์ต์ ํ
์ฌ์ฉ์๊ฐ ์ด๋ค ๋ธ๋ผ์ฐ์ ๋ ๊ธฐ๊ธฐ๋ฅผ ์ฌ์ฉํ๋๋ผ๋ ํ๋ฉด์ ๋์ผํ๊ฒ ๋ณด๊ณ , ์ ์ฒด์ , ํ๊ฒฝ์ ์กฐ๊ฑด์ ๊ด๊ณ ์์ด ์ ๋ณด์ ์ ๊ทผํ ์ ์๋ ์๋น์ค๋ฅผ ๋ง๋ค๊ณ ์ ํ์์ต๋๋ค.
-
์๋งจํฑ ๋งํฌ์ ์ ์ฉ (๋ธ๋ก๊ทธ)
header, h, section, article, button๊ณผ ๊ฐ์ ์ญํ ์ ๋ช ์์ ์ผ๋ก ๋๋ฌ๋ด๋ ์๋งจํฑ ํ๊ทธ๋ฅผ ์ฌ์ฉํ ๋งํฌ์ .
-
aria ๋ฐ image alt ํ๊ทธ ์ฌ์ฉ
section๊ณผ article ํ๊ทธ์ ๊ฒฝ์ฐ ๋ณด์ฌ์ง๋ ์ ๋ชฉ์ด ์๋ ๊ฒฝ์ฐ aria-labelledby๋ฅผ, ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ aria-label์ ์ฌ์ฉํด ์ญํ ์ ๋ช ์.
-
Open Graph ๋ฐ ๋ฉํ ํ๊ทธ ํ์ฉ
title, description, author, keywords ๋ฑ์ ๋ฉํ ํ๊ทธ ๋ฐ OpenGraph๋ฅผ ํ์ฉํ์ฌ SEO๋ฅผ ์ต์ ํ.
์น ํ์ค ๋ฐ ์น ์ ๊ทผ์ฑ์ ๊ณ ๋ คํ ๋งํฌ์ ๋ฐ SEO ๊ฐ์ ์์ ์ ํตํด ์น ์ ๊ทผ์ฑ๊ณผ SEO์ ์ค์์ฑ์ ์ดํดํ๊ณ , LightHouse ๊ธฐ์ค ํ๊ท ์งํ 19.76% ํฅ์์ด๋ผ๋ ์ฑ๊ณผ๋ฅผ ๋์ถํ์์ต๋๋ค.
3. AWS ๋ฐฐํฌ
-
๋คํธ์ํฌ ์์ฒญ ๋ฌธ์
- CORS ์๋ฌ
- ๊ฐ๋ฐ ํ๊ฒฝ์์๋ ํ๋ก์๋ฅผ ์ฌ์ฉํด ์์ฒญ์ redirectํ์ง๋ง, ๋ฐฐํฌ ํ๊ฒฝ์์๋ ์๋ฒ์์ cors ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํด CORS ํค๋ ์ค์ ํ์ฌ ํด๊ฒฐ.
- Mixed Content:
- ํ๋ก ํธ์๋ ์๋ฒ ์์ฒญ์ CloudFront๋ฅผ ์ฌ์ฉํด HTTPS๋ก redirectํ์ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ฌ ๋ฐฑ์๋ ์๋ฒ ์์ฒญ๋ LoadBalancer์ SSL/TLS๋ฅผ ์ค์ ํ์ฌ ํด๊ฒฐ.
- CORS ์๋ฌ
-
S3 ๋ฒํท ์ ๋ฐ์ดํธ์ ๋ฐฐํฌ ํ๊ฒฝ ๋ถ์ผ์น
-
๋์ importํ ์ฝ๋๋ฅผ ๋ฐฐํฌํ์ ๋,
Failed to fetch dynamically loaded module
์๋ฌ๊ฐ ๋ฐ์. -
๋ฒํท์ ๋ด์ฉ์ ์ญ์ ํ๊ณ ๋ด์ฉ์ ์ ๋ฐ์ดํธํ์ง๋ง, ๋ฐฐํฌ ํ๊ฒฝ์ ๋ฐ์๋์ง ์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. CloudFront์ ๋ก๊ทธ๋ฅผ ํ์ธํ์ฌ ์บ์ฑ ๋ฌธ์ ์ธ ๊ฒ์ ํ์ธํ๊ณ , ๋ธ๋ผ์ฐ์ ์บ์ ์ญ์ ๋ฐ ๊ฐ์ ์๋ก๊ณ ์นจ์ ํ์ง๋ง ํด๊ฒฐ๋์ง ์์์.
-
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฝ๋ ๋ถํ ์ด ๋์ง ์์ ์ด์ ๋ฒ์ ์ ๋จผ์ ์ ๋ก๋ํ๊ณ CloudFront์์ ์บ์๋ฅผ ์ ์ฒด ๋ฌดํจํํ ํ ์ฝ๋ ๋ถํ ํ ์ฝ๋๋ฅผ ์ ๋ก๋ํ์ฌ ํด๊ฒฐ.
-
-
ํ๋ก ํธ์๋ ๋ฐ ๋ฐฑ์๋ HTTPS ๊ตฌ์ฑ
-
Route53์์ ์ฌ์ฉํ๋ ํ๋์ ๋๋ฉ์ธ์ผ๋ก ์๋ฒ ๊ตฌ์กฐ๋ฅผ ๊ตฌ์ฑ์ ์ด๋ ค์.
-
[ํ๋ก ํธ] Route53์ ๋๋ฉ์ธ์ S3๋ก ์ฐ๊ฒฐํ๊ณ , CloudFront์์ https๋ก redirect.
-
[๋ฐฑ์๋] ์ฌ์ฉํ๊ณ ์๋ ๋๋ฉ์ธ์ ์๋ธ ๋๋ฉ์ธ์ ๋ง๋ค์ด LoadBalancer์์ https๋ก redirectํ๊ณ , ์ด๋ฅผ target group์ ๋ค์ด์จ ์์ฒญ์ ์ฒ๋ฆฌํ EC2 ํฌํธ๋ฅผ ๋ช ์ํด ์ฐ๊ฒฐ.
-
SSL/TLS๋ฅผ ์ ์ฉํ ์์ ํ ์ฐ๊ฒฐ์ ๋ณด์ฅํ๊ณ , ์พ์ ํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ํ ๊ธฐ๋ณธ์ ์ธ ํด๋ผ์ฐ๋ ํ๊ฒฝ ๊ตฌ์ฑ์ ํ ์ ์๊ฒ ๋์์ต๋๋ค. ๋ฐฐํฌ ๊ณผ์ ์์ ์บ์ ๋ฐ ๋ฒ์ ๊ด๋ฆฌ์ ์ค์์ฑ์ ์ดํดํ๊ณ , ๋ก๊ทธ ๋ถ์์ ํตํ ๋ฌธ์ ํด๊ฒฐ ๋ฅ๋ ฅ์ ํค์ ์ต๋๋ค.
NutriNotes๋ฅผ ๋ก์ปฌ์์ ์คํํ๊ธฐ:
- Node 20.5.1
- Npm 10.0.0
-
ํด๋ก
git clone https://github.com/minjidev/react-ts-diet-frontend.git
-
๋๋ ํ ๋ฆฌ๋ก ์ด๋
cd react-ts-diet-frontend
-
์์กด์ฑ ์ค์น
npm install
-
.env
ํ์ผ์ ์์ฑํ์ธ์.VITE_EDAMAM_APP_ID = YOUR_EDAMAM_APP_ID; VITE_EDAMAM_APP_KEY = YOUR_EDAMAM_APP_KEY; VITE_API_BASE_URL = BACKEND_ENDPONT;
-
๊ฐ๋ฐ ์๋ฒ ์์:
npm run dev
-
ํด๋ก
git clone https://github.com/minjidev/react-ts-diet-backend.git
-
๋๋ ํ ๋ฆฌ๋ก ์ด๋
cd react-ts-diet-backend
-
์์กด์ฑ ์ค์น
npm install
-
.env
ํ์ผ์ ์์ฑPORT = BACKEND_PORT; JWT_SECRET_KEY = YOUR_JWT_SECRET_KEY;
-
nodemon ์คํ:
npm start
ํ๊ฒฝ
ํ๋ก ํธ์๋
๋ฐฑ์๋
๋ฐฐํฌ
Type | ์ค๋ช |
---|---|
Feat | ์๋ก์ด ๊ธฐ๋ฅ ์ถ๊ฐ |
Fix | ๋ฒ๊ทธ ์์ |
Refactor | ์ฝ๋ ๋ฆฌํฉํ ๋ง, ํ์ผ ํน์ ํด๋๋ช ์ ์์ ํ๊ฑฐ๋ ์ฎ๊ธฐ๋ ์์ ๋ง์ธ ๊ฒฝ์ฐ, ํ์ผ์ ์ญ์ ํ๋ ์์ ๋ง ์ํํ ๊ฒฝ์ฐ |
Style | CSS ๋ฐ ๋ ์ด์์ ์์ ์์ |
Docs | ๋ฌธ์ ์์ |
Chore | ์ ์ง๋ณด์ |