Skip to content

Latest commit

Β 

History

History
207 lines (158 loc) Β· 6.45 KB

File metadata and controls

207 lines (158 loc) Β· 6.45 KB

폴더ꡬ쑰/넀이밍 μ»¨λ²€μ…˜

⚠️ 이 ν”„λ‘œμ νŠΈλŠ” FSD (Feature-Sliced Design) μ•„ν‚€ν…μ²˜λ₯Ό λ”°λ¦…λ‹ˆλ‹€.
μžμ„Έν•œ μ„€λͺ…은 FSD_ARCHITECTURE.mdλ₯Ό μ°Έκ³ ν•˜μ„Έμš”.

πŸ“‚ 폴더 ꡬ쑰 (FSD 기반)

src/
β”œβ”€β”€ app/                   # μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ ˆμ΄μ–΄
β”‚   β”œβ”€β”€ index.js          #   - μ§„μž…μ 
β”‚   β”œβ”€β”€ App.jsx           #   - 메인 μ»΄ν¬λ„ŒνŠΈ
β”‚   β”œβ”€β”€ routes/           #   - λΌμš°νŒ… μ„€μ •
β”‚   β”œβ”€β”€ providers/        #   - μ „μ—­ ν”„λ‘œλ°”μ΄λ”
β”‚   └── styles/           #   - μ „μ—­ μŠ€νƒ€μΌ
β”‚
β”œβ”€β”€ pages/                 # νŽ˜μ΄μ§€ λ ˆμ΄μ–΄
β”‚   └── <page-name>/      #   - λΌμš°νŠΈμ™€ 1:1 λ§€μΉ­
β”‚       β”œβ”€β”€ index.js      #   - Public API
β”‚       └── ui/           #   - νŽ˜μ΄μ§€ μ»΄ν¬λ„ŒνŠΈ
β”‚
β”œβ”€β”€ widgets/               # μœ„μ ― λ ˆμ΄μ–΄
β”‚   └── <widget-name>/    #   - 큰 독립적인 UI 블둝
β”‚       β”œβ”€β”€ index.js      #   - Public API
β”‚       └── ui/           #   - μœ„μ ― μ»΄ν¬λ„ŒνŠΈ
β”‚
β”œβ”€β”€ features/              # κΈ°λŠ₯ λ ˆμ΄μ–΄
β”‚   └── <domain>/         #   - μ‚¬μš©μž μ‹œλ‚˜λ¦¬μ˜€/κΈ°λŠ₯
β”‚       └── <feature-name>/
β”‚           β”œβ”€β”€ index.js  #   - Public API
β”‚           β”œβ”€β”€ ui/       #   - UI μ»΄ν¬λ„ŒνŠΈ
β”‚           └── model/    #   - λΉ„μ¦ˆλ‹ˆμŠ€ 둜직
β”‚
β”œβ”€β”€ entities/              # μ—”ν‹°ν‹° λ ˆμ΄μ–΄
β”‚   └── <entity-name>/    #   - λΉ„μ¦ˆλ‹ˆμŠ€ μ—”ν‹°ν‹°
β”‚       β”œβ”€β”€ index.js      #   - Public API
β”‚       β”œβ”€β”€ api/          #   - API ν•¨μˆ˜
β”‚       β”œβ”€β”€ model/        #   - μƒνƒœ 관리
β”‚       └── ui/           #   - UI μ»΄ν¬λ„ŒνŠΈ
β”‚
└── shared/                # 곡유 λ ˆμ΄μ–΄
    β”œβ”€β”€ ui/               #   - μž¬μ‚¬μš© UI μ»΄ν¬λ„ŒνŠΈ
    β”œβ”€β”€ api/              #   - HTTP ν΄λΌμ΄μ–ΈνŠΈ
    β”œβ”€β”€ lib/              #   - μœ ν‹Έλ¦¬ν‹°, ν›…
    β”œβ”€β”€ config/           #   - μƒμˆ˜, μ„€μ •
    └── assets/           #   - 정적 μžμ›

슬라이슀(Slice) ꡬ쑰 μ˜ˆμ‹œ

각 λ ˆμ΄μ–΄λŠ” 슬라이슀(κΈ°λŠ₯ λ‹¨μœ„)둜 κ΅¬μ„±λ˜κ³ , 각 μŠ¬λΌμ΄μŠ€λŠ” μ„Έκ·Έλ¨ΌνŠΈλ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€.

entities/shop/
β”œβ”€β”€ index.js              # Public API (μ™ΈλΆ€ λ…ΈμΆœμš©)
β”œβ”€β”€ api/                  # API 호좜
β”‚   └── shopApi.js
β”œβ”€β”€ model/                # μƒνƒœ 관리, λΉ„μ¦ˆλ‹ˆμŠ€ 둜직
β”‚   └── shopAtom.js
└── ui/                   # UI μ»΄ν¬λ„ŒνŠΈ
    └── ShopCard.jsx

νŽ˜μ΄μ§€ ꡬ쑰 μ˜ˆμ‹œ

pages/shop-list/
β”œβ”€β”€ index.js              # Public API
└── ui/
    └── ShopListPage.jsx  # νŽ˜μ΄μ§€ μ»΄ν¬λ„ŒνŠΈ

πŸ“Œ Assets μœ„μΉ˜ κ°€μ΄λ“œ

  • public/: λ²ˆλ“€λŸ¬κ°€ κ΄€λ¦¬ν•˜μ§€ μ•Šκ³  κ·ΈλŒ€λ‘œ 볡사됨 β†’ URL둜 직접 μ ‘κ·Ό (/logo.png)
    • favicon, manifest.json, robots.txt
    • μ™ΈλΆ€μ—μ„œ μ ˆλŒ€ 경둜 접근이 ν•„μš”ν•œ 파일
  • src/shared/assets/: importν•΄μ„œ μ‚¬μš©ν•˜λŠ” 정적 μžμ› β†’ λΉŒλ“œμ‹œ ν•΄μ‹œ 처리, 캐싱 관리
    • μ»΄ν¬λ„ŒνŠΈ μ•ˆμ—μ„œ μ‚¬μš©ν•˜λŠ” 이미지, μ•„μ΄μ½˜, SVG, 폰트
    • μ½”λ“œμ™€ ν•¨κ»˜ 버전 κ΄€λ¦¬λ˜μ–΄μ•Ό ν•˜λŠ” λ¦¬μ†ŒμŠ€

κ²°λ‘ : UI에 μ“°μ΄λŠ” λŒ€λΆ€λΆ„μ˜ 이미지/μ•„μ΄μ½˜μ€ shared/assets/에 두고, SEO/λ©”νƒ€λ°μ΄ν„°μš©μ€ public/ μœ μ§€


πŸ“¦ Public API νŒ¨ν„΄ (Barrel File)

FSDμ—μ„œλŠ” 각 μŠ¬λΌμ΄μŠ€λ§ˆλ‹€ index.jsλ₯Ό Public API둜 μ‚¬μš©ν•©λ‹ˆλ‹€.

λͺ©μ 

  • 슬라이슀 λ‚΄λΆ€ κ΅¬ν˜„μ„ μΊ‘μŠν™”
  • μ™ΈλΆ€μ—μ„œ μ‚¬μš©ν•  κ²ƒλ§Œ λͺ…μ‹œμ μœΌλ‘œ export
  • import 경둜λ₯Ό κ°„κ²°ν•˜κ²Œ μœ μ§€

μ˜ˆμ‹œ

entities/shop/
β”œβ”€β”€ index.js              # Public API
β”œβ”€β”€ api/
β”‚   └── shopApi.js
└── ui/
    └── ShopCard.jsx
// entities/shop/index.js
export { fetchShops, fetchShopById } from './api/shopApi';
export { ShopCard } from './ui/ShopCard';
// μ‚¬μš©ν•˜λŠ” κ³³μ—μ„œ
import { fetchShops, ShopCard } from '@/entities/shop';

κ·œμΉ™

  • βœ… ν—ˆμš©: 각 슬라이슀의 Public API (entities/shop/index.js)
  • βœ… ν—ˆμš©: Shared UI의 배럴 파일 (shared/ui/index.js)
  • ❌ κΈˆμ§€: λ ˆμ΄μ–΄ 전체λ₯Ό λͺ¨μœΌλŠ” 배럴 파일 (entities/index.js)

πŸ“ 넀이밍 κ·œμΉ™

  • μ»΄ν¬λ„ŒνŠΈ/ν›…/Provider/Context/파일λͺ…: PascalCase
    • 예) Button.jsx, UserCard.jsx, useToggle.js, AuthProvider.js
  • ν•¨μˆ˜/μœ ν‹Έ: camelCase
    • 예) formatDate, parseQueryString
  • μƒμˆ˜: UPPER_SNAKE_CASE - 예) API_BASE_URL

πŸ”„ Export κ·œμΉ™

κΈ°λ³Έ 원칙

  • κΈ°λ³Έ: named export μ‚¬μš©.
  • μ˜ˆμ™Έ: νŽ˜μ΄μ§€ μ—”νŠΈλ¦¬(pages//index.jsx)λ‚˜ 루트 μ—”νŠΈλ¦¬(App.jsx, main.jsx) 같은 μ§„μž…μ  νŒŒμΌμ—μ„œλ§Œ default export ν—ˆμš©.

Named Export μ˜ˆμ‹œ

// Button.jsx
export function Button() {
  return <button>Click</button>;
}

export const BUTTON_SIZE = 'large';

// μ‚¬μš©
import { Button, BUTTON_SIZE } from './Button';

Default Export μ˜ˆμ‹œ (μ§„μž…μ  μ „μš©)

// pages/Home/index.jsx
export default function HomePage() {
  return <div>ν™ˆ</div>;
}

// App.jsx
export default function App() {
  return <RouterProvider router={router} />;
}

// μ‚¬μš©
import HomePage from './pages/Home';
import App from './App';

μ™œ 이런 κ·œμΉ™μ„ λ‘λŠ”κ°€?

Named Export의 μž₯점

  • μ—¬λŸ¬ 개 export κ°€λŠ₯ β†’ 관리 μœ μ—°ν•¨.
  • import μ‹œ 이름 κ°•μ œ β†’ 좔적이 쉬움, IDE μžλ™μ™„μ„± 지원.
  • λ¦¬νŒ©ν† λ§ μ‹œ 이름 λ³€κ²½ 좔적이 확싀함.

Default Export의 단점

  • νŒŒμΌλ‹Ή ν•˜λ‚˜λ§Œ export κ°€λŠ₯.
  • import μ‹œ 이름을 λ§ˆμŒλŒ€λ‘œ λ°”κΏ€ 수 μžˆμ–΄ 좔적이 어렀움.
  • λ¦¬νŒ©ν† λ§ μ‹œ 뢈일치 문제 λ°œμƒ κ°€λŠ₯ (Button을 PrimaryButton으둜 바꿔도 import Foo from './Button'은 κ·ΈλŒ€λ‘œ λ™μž‘).

그런데 μ™œ μ§„μž…μ λ§Œ ν—ˆμš©ν• κΉŒ?

  • νŽ˜μ΄μ§€ μ—”νŠΈλ¦¬(pages//index.jsx)
    • λΌμš°ν„°μ™€ λ°”λ‘œ μ—°κ²°λ˜λŠ” νŒŒμΌμ€ 무쑰건 1개 μ»΄ν¬λ„ŒνŠΈλ§Œ 내보냄.
    • export default Pageκ°€ 직관적이고 κ΄€λ‘€μ μž„.
  • 루트 μ—”νŠΈλ¦¬(App.jsx, main.jsx) - μ•± 전체λ₯Ό κ°μ‹ΈλŠ” 단일 μ»΄ν¬λ„ŒνŠΈ. - μ—­μ‹œ default exportκ°€ μžμ—°μŠ€λŸ½κ³  λͺ…확함.

κ²°λ‘ : μ—¬λŸ¬ 개 export될 수 μžˆλŠ” νŒŒμΌμ—μ„œλŠ” named export만 μ‚¬μš©ν•΄ 좔적성과 일관성을 μœ μ§€ν•˜κ³ , β€œμ΄ νŒŒμΌμ€ 무쑰건 ν•˜λ‚˜λ§Œ 내보낸닀”가 보μž₯λ˜λŠ” μ§„μž…μ μ—μ„œλŠ” default exportλ₯Ό ν—ˆμš©ν•œλ‹€.