Skip to content

πŸ’ƒ 35κΈ° Dash μ›Ή 파트 repo πŸ•Ί

Notifications You must be signed in to change notification settings

SOPT-all/35-APPJAM-WEB-DASH

Repository files navigation

DASH

πŸ’ƒ μ„œλΉ„μŠ€ μ†Œκ°œ

image

πŸ’ƒ β€œλ‹Ήμ‹ μ—κ²Œ 좀을 더 κ°€κΉŒμ΄, μ„Έμƒμ˜ λͺ¨λ“  λŒ„μ„œμ™€ 클래슀λ₯Ό λͺ¨μ€ μ„œλΉ„μŠ€"

Da/shβ€™λŠ” μ„œλΉ„μŠ€μ˜ 핡심 ν‚€μ›Œλ“œμΈ Dance(μΆ€)와 Share(곡유)λ₯Ό κ²°ν•©ν•œ μ΄λ¦„μœΌλ‘œ, λŒ„μŠ€ ν΄λž˜μŠ€μ™€ κ°•μ‚¬λŒ„μ„œμ— λŒ€ν•œ 정보λ₯Ό 자유둭게 νƒμƒ‰ν•˜κ³  μ›ν•˜λŠ” 클래슀λ₯Ό κ°„νŽΈν•˜κ²Œ μ‹ μ²­ν•  수 μžˆλŠ” ν”Œλž«νΌμž…λ‹ˆλ‹€. 이 μ„œλΉ„μŠ€λŠ” μˆ˜κ°•μƒκ³Ό 강사λ₯Ό μ—°κ²°ν•˜λŠ” 닀리 역할을 함과 λ™μ‹œμ— μ„Έμƒμ˜ λͺ¨λ“  λŒ„μ„œλ“€μ΄ ν•¨κ»˜ μ†Œν†΅ν•˜κ³  μ„±μž₯ν•  수 μžˆλŠ” 곡간을 μ œκ³΅ν•©λ‹ˆλ‹€.



πŸ’ƒμ„œλΉ„μŠ€ ν”Œλ‘œμš°

image


DASH의 웨비듀을 μ†Œκ°œν•©λ‹ˆλ‹€!

Image


🎈 νŒ€μ›

ν”„λ‘œν•„μ‚¬μ§„ ν”„λ‘œν•„μ‚¬μ§„ ν”„λ‘œν•„μ‚¬μ§„ ν”„λ‘œν•„μ‚¬μ§„ ν”„λ‘œν•„μ‚¬μ§„
μ΄μ§„ν˜
κΉ€κ·œν™
박희선
ν•œμˆ˜μ •
κΉ€κ±΄νœ˜
@constantly-dev @rtttr1 @heesunee @hansoojeongsj @KIMGEONHWI


πŸ›  기술 μŠ€νƒ 및 μ„ μ • 이유 (Tech Stack)

μ—­ν•  기술 μ„ μ • 이유
Library React DASH μ„œλΉ„μŠ€λŠ” 동적인 μ‚¬μš©μž κ²½ν—˜κ³Ό λΉ λ₯Έ μΈν„°λž™μ…˜μ— 쀑점을 두고 있기 λ•Œλ¬Έμ— CSR 기반으둜 μž‘λ™ν•˜λ©°,
초기 λ Œλ”λ§ 이후 λͺ¨λ“  νŽ˜μ΄μ§€κ°€ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ λ™μž‘ν•˜λ„λ‘ 섀계할 수 μžˆλŠ” SPA 쀑심 κ°œλ°œμ„ ν•  수 μžˆλŠ” λ¦¬μ•‘νŠΈλ₯Ό μ„ νƒν•˜κ²Œ λ˜μ—ˆλ‹€.
Programming Language TypeScript νƒ€μž…μ„ 보μž₯ν•˜μ—¬ μ½”λ“œμ˜ μ•ˆμ •μ„±μ„ 높이고 μžλ™ 완성을 ν†΅ν•œ μœ μ§€ 보수λ₯Ό μ’‹κ²Œ ν•˜κΈ° μœ„ν•¨.
Styling Vanilla Extract CSS CSS-in-TS λ°©μ‹μœΌλ‘œ 기쑴의 CSS-in-JS 방식과 λ‹€λ₯΄κ²Œ νƒ€μž… μ•ˆμ „μ„±μ„ μ œκ³΅ν•˜μ—¬ μžλ™ μ™„μ„±, λŸ°νƒ€μž„ μ˜€λ²„ν—€λ“œ 없이 λΉŒλ“œ μ‹œ 정적 CSS둜 μΆ”μΆœν•  수 μžˆλ‹€. λ˜ν•œ λΉŒλ“œ μ‹œκ°„μ— CSSλ₯Ό μƒμ„±ν•˜λŠ” zero-runtime의 μž₯점 λ˜ν•œ ν•΄λ‹Ή μŠ€νƒμ˜ 선택 기쀀이 λ˜μ—ˆλ‹€.
Data Fetching Axios TanStack Query Axios: μžλ™μœΌλ‘œ JSON ν˜•νƒœμ˜ 데이터λ₯Ό νŒŒμ‹±ν•΄μ£Όλ©°, HTTP μš”μ²­μ— λŒ€ν•΄ 효율적인 처리λ₯Ό μ œκ³΅ν•œλ‹€. λ˜ν•œ 우리 ν”„λ‘œμ νŠΈμ—μ„œ token을 ν™œμš©ν•  λ•Œ interceptorλ“±μ˜ κΈ°λŠ₯을 ν™œμš©ν•  수 있기 λ•Œλ¬Έμ— μ„ νƒν•˜μ˜€λ‹€.
TanStack Query: 캐싱 κΈ°λŠ₯을 ν™œμš©ν•œ λ‹€μ–‘ν•œ λ™μž‘μ„ κ΅¬ν˜„ν•  수 있고, API μš”μ²­ μˆ˜ν–‰μ„ μœ„ν•œ κ·œκ²©ν™”λœ 방식을 μ œκ³΅ν•˜κΈ° λ•Œλ¬Έμ— 가독성을 λ†’μ—¬μ€€λ‹€. μ„œλ²„ μƒνƒœ 관리에 νŠΉν™”λ˜μ–΄ μœ μ§€ 보수 μΈ‘λ©΄ λ“± DXκ°€ ν–₯μƒλœλ‹€.
UI Development Storybook UI μ»΄ν¬λ„ŒνŠΈ 개발 및 ν…ŒμŠ€νŠΈ νŽΈμ˜μ„± 제곡, λ””μžμ΄λ„ˆμ™€μ˜ μ›ν™œν•œ μ†Œν†΅ κ°€λŠ₯
Formatting ESLint Prettier μ½”λ“œ 일관성을 μœ μ§€ν•˜κ³ , 가독성을 높이며, μŠ€νƒ€μΌ μ»¨λ²€μ…˜μ„ ν†΅ν•©μ μœΌλ‘œ 관리
Package Manager Pnpm 기쑴에 μ‚¬μš©ν•˜λ˜ yarn의 node_modules에 νŒ¨ν‚€μ§€κ°€ 쀑볡 μ €μž₯λ˜μ–΄ μš©λŸ‰μ΄ μ ˆκ°λ˜λŠ” 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€. λ˜ν•œ μ˜μ‘΄μ„± μ„€μΉ˜ 없이 (zero-install) μ‚¬μš©ν•˜κ²Œ λ˜λ©΄μ„œ λΉŒλ“œμ™€ 배포 μ‹œκ°„μ„ 크게 λ‹¨μΆ•μ‹œμΌœμ€€λ‹€.
Version Control Git GitHub ν˜‘μ—…μ—μ„œ ν•„μš”ν•œ 버전 관리 μ‹œμŠ€ν…œμ„ λ„μž…ν•˜κΈ° μœ„ν•¨.
Deployment Vercel 짧은 기간에 λ°°ν¬ν•˜κΈ° μœ„ν•΄ λŸ¬λ‹ μ»€λΈŒκ°€ μž‘κ³  초기 배포에 μ ν•©ν•œ ν”Œλž«νΌμ΄κΈ° λ•Œλ¬Έμ— μ„ νƒν•˜μ˜€λ‹€.


πŸ“’ Git/GitHub μ»¨λ²€μ…˜

Git 브랜치 μ „λž΅ (GIit Flow)

  1. main(=master) : 였직 배포λ₯Ό μœ„ν•œ 브랜치 β†’ νŠΉλ³„ν•œ 상황이 μ•„λ‹ˆλΌλ©΄ 배포만 진행
  2. develop : μž‘μ—…ν•œ λ‚΄μš©μ„ μ·¨ν•©ν•˜λŠ” κ³³ (default branch)
  3. feat(=feature) : 각 μž‘μ—…λ¬Όμ„ λΆ„κΈ°ν•΄ μƒˆλ‘œ λ§Œλ“€μ–΄ μ‚¬μš©ν•  브랜치
git flow

컀밋 넀이밍 μ»¨λ²€μ…˜

Commit λ©”μ‹œμ§€ μ’…λ₯˜ μ„€λͺ…

제λͺ© λ‚΄μš©
init 초기 μ„ΈνŒ… (초기 μ΄ν›„λŠ” setting μ‚¬μš©)
setting νŒ¨ν‚€μ§€ μ„€μΉ˜, 개발 μ„€μ •
feat μƒˆλ‘œμš΄ κΈ°λŠ₯ μΆ”κ°€ / 퍼블리싱
fix 버그 μˆ˜μ •
style CSS λ“± μ‚¬μš©μž UI λ””μžμΈ λ³€κ²½
api API μ—°κ²° 둜직 μž‘μ„±
refactor ν”„λ‘œλ•μ…˜ μ½”λ“œ λ¦¬νŒ©ν† λ§ 및 QA 반영
chore λΉŒλ“œ ν…ŒμŠ€νŠΈ μ—…λ°μ΄νŠΈ, νŒ¨ν‚€μ§€ λ§€λ‹ˆμ € μ„€μ • (ν”„λ‘œλ•μ…˜ μ½”λ“œ λ³€κ²½ X)
deploy 배포 μž‘μ—…
comment ν•„μš”ν•œ 주석 μΆ”κ°€ 및 λ³€κ²½
test ν…ŒμŠ€νŠΈ μΆ”κ°€, ν…ŒμŠ€νŠΈ λ¦¬νŒ©ν† λ§ (ν”„λ‘œλ•μ…˜ μ½”λ“œ λ³€κ²½ X)
rename 파일 λ˜λŠ” 폴더 이름 μˆ˜μ • 및 이동 μž‘μ—…
remove 파일 μ‚­μ œ μž‘μ—…λ§Œ μˆ˜ν–‰
docs λ¬Έμ„œ μˆ˜μ •
!HOTFIX κΈ‰ν•˜κ²Œ 치λͺ…적인 버그 μˆ˜μ •
!BREAKING CHANGE μ»€λ‹€λž€ API λ³€κ²½


πŸ“’ 폴더 ꡬ쑰

  1. src/ μ•„λž˜ ν΄λ”λŠ” μ „λΆ€ common(곡톡)의 의미둜 μƒκ°ν•œλ‹€.
  2. pages/ μ•„λž˜ μ„ΈλΆ€ 폴더(components, constants λ“±λ“±)κ°€ 각각 μœ„μΉ˜ν•œλ‹€.
|-- πŸ“ .github
|-- πŸ“ node_modules
|-- πŸ“ public
|-- πŸ“ src // src λ°”λ‘œ ν•˜μœ„ ν΄λ”λŠ” λͺ¨λ‘ common(곡톡)의 의미
  |-- πŸ“ apis
    |-- πŸ“ common
    |-- πŸ“ νŽ˜μ΄μ§€1
    |-- πŸ“ νŽ˜μ΄μ§€2
  |-- πŸ“ assets
	    |-- πŸ“ images
	    |-- πŸ“ svg
  |-- πŸ“ components // 곡톡 μ»΄ν¬λ„ŒνŠΈ
	  |-- πŸ“ Button
		  |-- πŸ“„ex) Button.tsx
		  |-- πŸ“„ex) Button.style.ts
  |-- πŸ“ constants
  |-- πŸ“ hooks
	  |-- πŸ“„ex) useOutsideClick.ts
  |-- πŸ“ pages
    |-- πŸ“ components
    |-- πŸ“ constants
    |-- πŸ“ types λ“± // (νŽ˜μ΄μ§€μ— ν•΄λ‹Ήν•˜λŠ” κ°œλ³„ 데이터 폴더 λ”°λ‘œ 쑴재)
  |-- πŸ“ styles
  |-- πŸ“ types
  |-- πŸ“ utils
  |-- πŸ“ routes
|-- index.html λ“± ETC


πŸ“’ 넀이밍 μ»¨λ²€μ…˜

1. κΈ°λ³Έ (Default)

  1. μ»΄ν¬λ„ŒνŠΈ / class PascalCase
  2. 폴더λͺ… carmelCase
  3. 파일 λͺ… (μ»΄ν¬λ„ŒνŠΈ μ œμ™Έ) carmelCase
  4. λ³€μˆ˜, ν•¨μˆ˜ carmelCase
  5. νŒŒλΌλ―Έν„° carmelCase
  6. μƒμˆ˜ BIG_SNAKE_CASE

2. νƒ€μž… (Type)

  1. interfaceλŠ” ν•„μˆ˜λ‘œ PascalCase μ‚¬μš©ν•œλ‹€.
  2. Props νƒ€μž… β†’ μ»΄ν¬λ„ŒνŠΈλͺ…+PropTypes
    • μ˜ˆμ‹œ
      interface PostPagePropTypes {
      		title: string | undefined;
      		setTitle: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
      		tempContent: string;
      		editContent: string;
      		setEditorContent: (content: string) => void;
      		setContentWithoutTag: (content: string) => void;
      }
      
      const PostPage = (props: PostPagePropTypes) => {
      		const {title, setTitle, tempContent, editContent, setEditorContent,
      		setContentWithoutTag
      		...
      }
  3. 일반 νƒ€μž… β†’ … + Types
  4. PropsTypesλŠ” μ»΄ν¬λ„ŒνŠΈ 파일 λ‚΄ / κ·Έ μ™Έ νƒ€μž…μ€ pages/…/types 폴더에 λ”°λ‘œ 뢄리

3. μŠ€νƒ€μΌ (Style)

  1. μ»΄ν¬λ„ŒνŠΈ Wrapper 넀이밍 κ·œμΉ™ : Wrapper β†’ (Layout)β†’ Container β†’ Box (λ―Έμ •)
  2. semantic tagλŠ” 적극 ν™œμš©ν•œλ‹€.
    1. **aria-label**도 적극적 ν™œμš©!
  3. SVG 파일 μ‚¬μš©μ‹œ
    1. svgr둜 μ»΄ν¬λ„ŒνŠΈν™” ν›„ μ‚¬μš©ν•˜λ―€λ‘œ svg이름을 κ·ΈλŒ€λ‘œ λ³€ν™˜ν•˜μ—¬ μ‚¬μš©ν•œλ‹€.

4. ν•¨μˆ˜

  1. 이벀트 ν•Έλ“€λŸ¬ 넀이밍 handle + κΈ°λŠ₯ + 이벀트

    • μ˜ˆμ‹œ
      const handleBtnClick = () => {};
      const handleTabChange = () => {};

    β†’ props둜 λ„˜κΈΈ λ•Œ key값은 on + 이벀트

    • μ˜ˆμ‹œ
      const BoxComponent = () => {
        return <memoComponent onClick={handleBtnClick} />;
      };
  2. μœ ν‹Έ(utils) ν•¨μˆ˜ 넀이밍 동사(κΈ°λŠ₯) + λͺ…사(λŒ€μƒ)

  3. 값이 boolean일 κ²½μš°λŠ” is + μƒνƒœ (default)

    • μ˜ˆμ‹œ
      const [isLogined, setIsLogined] = useState(false);

    β†’ μΆ”κ°€μ μœΌλ‘œ can / should / has 정도λ₯Ό 상황에 맞게 μΆ”κ°€ν•œλ‹€.

  4. api ν•¨μˆ˜ HTTP λ©”μ„œλ“œ + λͺ…사

    • μ˜ˆμ‹œ
      const getList = () => {};
      const getMovie = () => {};
  5. 넀이밍 μ‹œ λ‹¨μˆ˜λ₯Ό 기본으둜 μ‚¬μš©ν•˜κ³  / 볡수면 뒀에 List ν‚€μ›Œλ“œλ₯Ό 뢙인닀.


5. 기타

  1. assets (Iconμ΄λ‚˜ Img)의 경우 ν”Όκ·Έλ§ˆ 넀이밍을 적극 ν™œμš©ν•œλ‹€.

    β†’ Ic + ν”Όκ·Έλ§ˆ 넀이밍 (icon의 경우)으둜 μ‚¬μš©

  2. URL, HTML 같은 λ²”μš©μ μΈ λŒ€λ¬Έμž μ•½μ–΄λŠ” λŒ€λ¬Έμž κ·ΈλŒ€λ‘œ μ‚¬μš©ν•œλ‹€.

  3. λ³€μˆ˜/μ΅œλŒ€ν•œ μ§κ΄€μ μœΌλ‘œ μž‘μ„±ν•˜μ—¬ 넀이밍을 보고도 무슨 데이터, ν–‰μœ„μΈμ§€ λ°”λ‘œ μœ μΆ”ν•  수 μžˆλ„λ‘ ν•œλ‹€.

    • 주석이 ν•„μš”ν•œ κ²½μš°μ—λŠ” μ–΄λ–€ 역할을 ν•˜λŠ”μ§€ λ‹€λ₯Έ μ‚¬λžŒμ΄ 이해할 수 μžˆλ„λ‘ μž‘μ„±ν•œλ‹€.
    • λ³€μˆ˜/ν•¨μˆ˜ λͺ…은 20자 미만, μ£Όμ„μœΌλ‘œ λ³€μˆ˜ μ„€λͺ…
  4. 주석은 μž‘μ„±ν•˜λ €κ³  ν•˜λŠ” λŒ€μƒ λ°”λ‘œ μœ„μ— μž‘μ„±



πŸ“’ μ½”λ”© (개발) μ»¨λ²€μ…˜

λ³€μˆ˜

  • var κΈˆμ§€.
  • const β†’ let μˆœμ„œλ‘œ μœ„λΆ€ν„° μ„ μ–Έ.
  • λ³€μˆ˜λ₯Ό μ‘°ν•©ν•˜μ—¬ λ¬Έμžμ—΄ μƒμ„±μ‹œ β€œ+ β€œ κΈˆμ§€. β†’ λ¦¬ν„°λŸ΄ μ‚¬μš©(λ°±ν‹± ```)
  • λ³€μˆ˜λͺ… : 의미λ₯Ό ν™•μ‹€νžˆ λ‚˜νƒ€λ‚Ό 수 μžˆλ„λ‘
    • μ˜ˆμ‹œ : 배열에 Arr λ³΄λ‹€λŠ” λ³€μˆ˜s = fruits, userlists λ“±λ“±
  • μ€„μž„λ§ 쓰지말기. 이름이 길어지더라도 μ–΄λ–€ λ³€μˆ˜μΈμ§€ μ •ν™•ν•˜κ²Œ
    • μ˜ˆμ‹œ : Btn X β†’ Button으둜 μ‚¬μš©
  • map μ‚¬μš©μ‹œ λ³€λ™λ˜λŠ” 리슀트라면 key값을 κ³ μœ ν•˜κ²Œ 잘 μ„€μ •ν•΄μ£ΌκΈ° index μ‚¬μš© κΈˆμ§€
    • μ„œλ²„μ—μ„œ λ‚΄λ €μ£ΌλŠ” idκ°’ or uuid μ‚¬μš©
  • μ „μ—­ λ³€μˆ˜λŠ” λ˜λ„λ‘ μ‚¬μš©ν•˜μ§€ μ•ŠκΈ°

ν•¨μˆ˜

  • ν™”μ‚΄ν‘œ ν•¨μˆ˜. function ν‚€μ›Œλ“œ 쓰지말기
  • μ€‘λ³΅ν•¨μˆ˜λŠ” utils 폴더에 λͺ¨μ•„μ„œ μž¬μ‚¬μš©ν•œλ‹€.
  • λ³€μˆ˜/ν•¨μˆ˜ λͺ…은 20자 미만.
    • μ΅œλŒ€ν•œ 넀이밍에 의미λ₯Ό λ‹΄μ•„μ„œ μž‘μ„±ν•˜κ³  ν•„μš” μ‹œμ— μ£Όμ„μœΌλ‘œ μ„€λͺ… μΆ”κ°€
  • ν•„μš”ν•˜λ‹€λ©΄ early return νŒ¨ν„΄μ„ 적극적으둜 ν™œμš©
    • μ˜ˆμ‹œ
      **// early return νŒ¨ν„΄**
      function processUser(user) {
        if (!user || !user.isActive) return; // **쑰건이 λ§žμ§€ μ•ŠμœΌλ©΄ 일찍 λ°˜ν™˜**
        // λ‚˜λ¨Έμ§€ 처리 μ½”λ“œ...
      }

μ»΄ν¬λ„ŒνŠΈ

  • rafce β†’ κ³ μ •
  • μ˜λ―Έμ—†λŠ” div λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ μ΅œμƒλ‹¨μ€ fragment μ‚¬μš©ν•˜κΈ°
const InfoText = () => {
  return (
    <>
      <h1>Welcome!</h1>
      <p>This our new page, we're glad you're are here!</p>
    </>
  );
};
  • children이 λΆˆν•„μš”ν•  땐 selfClosingμ‚¬μš©ν•˜κΈ° <Component/>
  • children 적극적으둜 ν™œμš©ν•˜κΈ°!

νƒ€μž…

  • object β†’ interface
  • 단일 λ³€μˆ˜ β†’ type alias
  • μ»΄ν¬λ„ŒνŠΈ μΈμžμ— λŒ€ν•œ νƒ€μž…μ€ μ»΄ν¬λ„ŒνŠΈ 상단에
  • κ·Έ μ™Έμ˜ νƒ€μž…λ“€μ€ types 폴더에
  • api response νƒ€μž…λͺ…은 OOOResponseTypes

λ©”μ†Œλ“œ

  • λ°°μ—΄ 볡사 μ‹œ β†’ μŠ€ν”„λ ˆλ“œ μ—°μ‚°μž(…) μ‚¬μš©

    • const copys = […originals]
  • for 보단, forEach/map을 μ‚¬μš©

  • ꡬ쑰 λΆ„ν•΄ 할당을 적극 이용

    interface userDataProps {
      userName: string;
      userBirth: string;
    }
    
    function checkIsUser({ userName, userBirth }: userDataProps) {}
  • λΆˆν•„μš”ν•œ 반볡문 지양 : filter, array.include() λ“±

    • μ‘°κ±΄λΆ€λ‘œ 데이터λ₯Ό ν™•μΈν•˜κ±°λ‚˜ λ½‘μ•„μ•Όν•˜λŠ” λ‘œμ§μ„ μ‚¬μš©ν•  λ•Œμ—λŠ” Map μ΄λ‚˜ Object처럼 key값을 μ΄μš©ν•΄μ„œ μ›μ†Œλ₯Ό μ°ΎλŠ” μžλ£Œν˜•μ„ μ΄μš©ν•˜λŠ”κ²ƒμ„ κ³ λ €ν•΄λ³΄κ±°λ‚˜, 배열을 μˆœνšŒν•˜μ§€ μ•Šκ³  index둜 λ°”λ‘œ μ ‘κ·Όν•  수 μžˆλŠ” 방법이 μ—†λŠ”μ§€ κ³ λ €.

Style β†’ X

mozila μΆ”μ²œ css μˆœμ„œ (μ°Έκ³ )

β†’ μΆ”κ°€ μ˜ˆμ •

기타

  • button νƒœκ·Έμ— **type**은 λͺ…μ‹œμ μœΌλ‘œ μž‘μ„±

  • 비ꡐ μ—°μ‚°μžλŠ” **===**와 **!==**λ§Œμ„ μ‚¬μš©

  • axios μ•ˆμ—μ„œ then/catch λŒ€μ‹  async/await 지ν–₯

About

πŸ’ƒ 35κΈ° Dash μ›Ή 파트 repo πŸ•Ί

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published