β οΈ μ΄ νλ‘μ νΈλ FSD (Feature-Sliced Design) μν€ν μ²λ₯Ό λ°λ¦ λλ€.
μμΈν μ€λͺ μ FSD_ARCHITECTURE.mdλ₯Ό μ°Έκ³ νμΈμ.
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 # νμ΄μ§ μ»΄ν¬λνΈ
- public/: λ²λ€λ¬κ° κ΄λ¦¬νμ§ μκ³ κ·Έλλ‘ λ³΅μ¬λ¨ β URLλ‘ μ§μ μ κ·Ό (/logo.png)
- favicon, manifest.json, robots.txt
- μΈλΆμμ μ λ κ²½λ‘ μ κ·Όμ΄ νμν νμΌ
- src/shared/assets/: importν΄μ μ¬μ©νλ μ μ μμ β λΉλμ ν΄μ μ²λ¦¬, μΊμ± κ΄λ¦¬
- μ»΄ν¬λνΈ μμμ μ¬μ©νλ μ΄λ―Έμ§, μμ΄μ½, SVG, ν°νΈ
- μ½λμ ν¨κ» λ²μ κ΄λ¦¬λμ΄μΌ νλ 리μμ€
κ²°λ‘ : UIμ μ°μ΄λ λλΆλΆμ μ΄λ―Έμ§/μμ΄μ½μ
shared/assets/μ λκ³ , SEO/λ©νλ°μ΄ν°μ©μpublic/μ μ§
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
κΈ°λ³Έ μμΉ
- κΈ°λ³Έ: 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λ₯Ό νμ©νλ€.