κ΅λ΄ 500λ§ μ΄μμ μ΄μ©μκ° μ¦κΈ°λ μΉμμ€!
μ¬λ°κ² κΈμ μ½λ€ 보면 "μ! μ΄λ μ΄λ κ² μ§νλλ©΄ μ¬λ°μ κ² κ°μλ°!" μ΄λ° μκ° ν λ²μ―€ ν΄λ³Έμ μμΌμ κ°μ?
βμ°½μμ μ΄λ ΅κ³ λΆλ΄μ€λ½λ€βλ νΈκ²¬μ κΉ¨κ³ ,
λꡬλ μ½κ² μ’μνλ μ΄μΌκΈ°λ₯Ό λ§λ€μ΄κ° μ μλ 창ꡬλ₯Ό λ§λ€μλ μμ΄λμ΄μμ μ΄ νλ‘μ νΈλ μμλμμ΅λλ€.
WeWriteλ λꡬλ μκ°κ° λμ΄, λ€λ₯Έ μ¬λλ€κ³Ό ν¨κ» μ΄μΌκΈ°λ₯Ό μ΄μ΄ μ°λ©° λ§λ€μ΄κ°λ μ°Έμ¬ν μ€ν 리ν λ§ νλ«νΌμ λλ€.
- π’ λ°°ν¬ μ£Όμ
- β κΈ°μ μ€ν
- π© νμ
- π¬ νλ°ν μν΅κ³Ό ν λ‘ λ¬Έν
- π Front Endμ λν΄μ λ°±μλμ λμμΈκΉμ§
- π λΌμ΄λΈλ¬λ¦¬λ₯Ό μ΅μννκ³ UI μ»΄ν¬λνΈλ₯Ό μ€κ³
- πββοΈ μ¬μ©μ νΌλλ°± λ°μ
- π¨βπ» ν₯ν μ λ°μ΄νΈ κ³ν
- β λΌμ΄μ μ€
| μΈμ΄ | TypeScript |
| νλ μμν¬ | Next.js15 |
| λΌμ΄λΈλ¬λ¦¬ | React19, TailWindCSS, TipTap, etc. |
| μνκ΄λ¦¬ | Context API, Tanstack Query, React Hook Form, Zustand |
| λ°μ΄ν°λ² μ΄μ€ | Codeit API, Supabase |
| νμ λꡬ | Notion, StoryBook, Husky |
| ν μ€νΈ | Jest |
νλͺ ν(myeongheonhong) |
κ°μμ(swimmingRiver) |
κΉμ§ν(juyesu) |
μ₯νμ₯(hoxey2Front) |
νλ‘μ νΈλ₯Ό μμνλ©΄μ κ°μμ λͺ©νκ° μμμ§λ§, 곡ν΅μ μΌλ‘ 곡κ°μ νμ±ν λͺ©νλ
"μ κ·Ήμ μΌλ‘ μν΅νκ³ ν νλ‘μ νΈμμλ§ κ²½νν μ μλ κ²λ€μ λ§μ΄ μ»μ΄κ°μ" μμ΅λλ€.
μ΄λ₯Ό μ§ν€κΈ° μν΄ λ€μκ³Ό κ°μ κ·μΉλ€μ μννμ΅λλ€.
- λ§€μΌ μ΅μ 1νμ λ°μΌλ¦¬ μ€ν¬λΌμ λ°λμ μ§ννλ©΄μ κ°μΈμ μ§ν μ¬νκ³Ό κ³ν, μ΄μλ₯Ό 곡μ νκΈ°
- κ·Όκ±° μλ 컨벀μ μ λ§λ€κΈ°. κ·Έλ¦¬κ³ μλ‘μ΄ νμ λ£°μ΄ νμνλ€λ©΄ μμ λ‘κ² μ μνκΈ°
- λ€λ₯Έ μ¬λμ΄ μμ±ν μ½λλ λ΄κ° μ΄ μ½λμ²λΌ. κΌΌκΌΌν PR리뷰 μμ±νκΈ°
νλ‘μ νΈλ₯Ό μ§ννλ©΄μ κ²ͺλ μ΄μ°λ³΄λ©΄ μ¬μν μ μλ κ³ λ―Όλ κ°λ³κ² λμ΄κ°μ§ μκ³
νλ°νκ² ν λ‘ νλ©° μλ―Έμλ κ²°μ μ λ΄λ¦¬λ λ¬Ένλ₯Ό μ‘°μ±νμμ΅λλ€.
νλ‘μ νΈ μ§ν μ€ ν λ‘ μ΄ μ΄λ£¨μ΄μ§ μμ λ‘λ λ€μκ³Ό κ°μ μμλ€μ΄ μμμ΅λλ€.
- λ―Έλμ νμ₯μ±μ κ³ λ €ν κ°λ° vs νμ¬μ μꡬμ¬νμ λΆν©νλ κ°λ°
- μ μ μνλ₯Ό ν΅ν μΈμ¦ μ 보 κ΄λ¦¬ vs useQueryμ μΊμ±μ ν΅ν μΈμ¦ μ 보 κ΄λ¦¬
- ν¨μμ λ¨μΌ μ± μ μμΉ(SRP) μ€μ vs μ¬μ¬μ©λ³΄λ€λ μ½λλ₯Ό λΆλ¦¬νκΈ° μν ν¨μ μ μΈμ μ΅μν
- TypeScriptμ νμ μλ μΆλ‘ μ΄ μ΄λ£¨μ΄μ§ λμ νμ λͺ μλ λͺ νμ±μ μ¦κ° vs λΆνμν μ€λ³΅
μ΄μ²λΌ μ λ΅μ΄ μ ν΄μ Έ μμ§ μμ μ£Όμ λΌλ, λ¨μν λμ΄κ°μ§ μκ³
κ° μ νμ κ·Όκ±°λ₯Ό κ°μ§κ³ νλ¨νλ € λ
Έλ ₯νμ΅λλ€.
νλ‘μ νΈ μ΄κΈ° μ€κ³ κ³Όμ μμ λ€μνκ³ μ¬λ°λ μμ΄λμ΄λ€μ΄ μ μλμμ§λ§
μ΄λ₯Ό ꡬννκΈ° μν΄μλ UI λμμΈκ³Ό λ°μ΄ν° λ² μ΄μ€κ° νμνμ΅λλ€.
νμ λμμ΄λλ μκ³ , λ°±μλ κ°λ°μλ μμΌλ κΈ°λ³ΈμΌλ‘ μ 곡λλ λͺ
μΈλ§ λ°λΌκ° μλ μμμ§λ§
μ°λ¦¬κ° νκ³ μΆμκ±Έ ν΄μΌ λ μ¦κ²κ³ , λͺ¨λκ° μ κ·Ήμ μΌλ‘ κ°λ°μ μ°Έμ¬ν μ μλ€κ³ μκ°νμ΅λλ€.
μ΄μ νμ λ μκ°μ΄μ§λ§ μΌκ³Ό νμ μ£Όλ§μ ννν νμ©νμ¬ Figmaμ Supabaseλ₯Ό 곡λΆνκ³
μ΄λ² νλ‘μ νΈμ λμ
νκ² λμμ΅λλ€.
μ€ν 리λ₯Ό νμλ€κ³Ό μ΄μ΄μ°κΈ° μν΄, κΈμ λκΈ° μν, μΉμΈ λ§κ° μκ°, μΉμΈμ μ 보λ₯Ό
μ κΈ°μ μΌλ‘ κ΄λ¦¬ν μ μλ μ€ν€λ§ μ€κ³μ 곡μ λ€μμ΅λλ€.
μλͺ»λ μ€ν€λ§λ μ 체 μμ² κ΅¬μ‘° μμ μΌλ‘ μ΄μ΄μ Έ κ°λ° μμμ λλΉν μ μκΈ° λλ¬Έμ,
νμλ€κ³Ό μΆ©λΆν λ
Όμνκ³ νμ
λ©ν λμ μ‘°μΈλ λ°μΌλ©° μ μ€ν μ€κ³νμ΅λλ€.
λν DBλ‘ λΆν° λ°μ΄ν°λ₯Ό μμ² λ° μμ νλ κ³Όμ μ ν¨μ¨μ μΌλ‘ μ§ννκΈ° μν΄μ
μλ¬ νΈλ€λ§μ μν κ³΅ν΅ μ νΈλ¦¬ν° ν¨μλ₯Ό λ§λ€μκ³ , CLIλ‘ ν
μ΄λΈ κΈ°λ° νμ
μλ μμ± κΈ°λ₯μ νμ©νμμ΅λλ€.
| μ€ν€λ§ | νμλ€μκ² μ§μ 곡μ |
|---|---|
![]() |
![]() |
μλ‘μ΄ νμ΄μ§μ νλ‘μ νΈ λͺ
μΈμ λ§λ μ»΄ν¬λνΈ UIλ₯Ό μ€κ³νκΈ° μν΄ Figmaλ₯Ό νμ©νμ΅λλ€.
μ κ΅ν λ μ΄μμμ΄λ λμμΈκΉμ§λ μ μνκΈ° μ΄λ €μ μ§λ§,
λ¬νν μμμ λ°νμΌλ‘λ νμλ€κ³Ό λ°©ν₯μ±μ λ
Όμνκ³ μλλ₯Ό 곡μ νλ λ° λμμ΄ λμμ΅λλ€.
νμ κ°μκ° Figmaλ₯Ό 곡λΆνκΈ° 보λ€λ κΈ°μ‘΄μ μ¬μ©ν΄λ³Έ κ²½νμ΄ μκ±°λ,
μ΄λ² κΈ°νμ 곡λΆλ₯Ό μ§νν νμμ΄ νμν λ¨μΆν€λ κΈ°λ₯μ 곡μ ν΄μ£Όλ λ°©μμ μ±ννμμ΅λλ€.
| UI μμ | νμλ€μκ² μ§μ 곡μ |
|---|---|
![]() |
![]() |
κ°λ° μ΄κΈ°, κ³΅ν΅ μ»΄ν¬λνΈ κ΅¬νμ μν΄ headlessUIλ shadcnκ³Ό κ°μ λΌμ΄λΈλ¬λ¦¬ λμ
μ κ³ λ―Όνμ΅λλ€.
λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ©΄ κ°λ° μκ°μ΄ λ¨μΆλκ³ μμ±λλ₯Ό λμΌ μ μλ€κ³ μκ°νμ§λ§,
μ£Όλμ΄ κ°λ°μλ‘μ μ§μ ꡬννλ©° λ°μνλ λ¬Έμ λ€μ κ²½ννλ κ²λ κ°μΉ μλ νμ΅ κΈ°νκ° λ κ²μ΄λΌ
νλ¨ν΄ μ§μ κ°λ°νκΈ°λ‘ κ²°μ νμ΅λλ€.
μ»΄ν¬λνΈλ€μ μ€κ³ νλ©΄μ νμ₯μ±κ³Ό μ¬μ¬μ©μ±μ κ³ λ €νλ©° μλ‘μ΄ κΈ°νμ΄ μΆκ°λλλΌλ μ½κ² λμλ μ μλλ‘ νμμ΅λλ€.
λν κ³΅ν΅ μ»΄ν¬λνΈλ₯Ό ꡬν νμλ λ€λ₯Έ νμλ€μ΄ μ½κ² UIλ₯Ό νμΈνκ³ λμμ ν
μ€νΈν΄λ³Ό μ μλλ‘ StoryBook νμΌμ ν¨κ»
μμ±νμ¬ κ³΅μ νμμ΅λλ€.
λλΆλΆμ μ»΄ν¬λνΈλ₯Ό λΌμ΄λΈλ¬λ¦¬μμ΄ κ΅¬ννμ§λ§, ν κ°μ§ λ¦¬μΉ ν
μ€νΈ μλν°(WYSIWYG)μ κ²½μ°
μ¬μ΄νΈμ νΉμ§μ μ¬μ©μκ° κΈμ μμ±νλ λΆλΆμ΄ λμ μ€μλλ₯Ό κ°μ§κΈ°λ νκ³ ,
λΌμ΄λΈλ¬λ¦¬ μμ΄ κ΅¬ννλ
λ°μ λμ κ°λ° μμμ΄ μλͺ¨λ κ²μ΄λΌκ³ νλ¨νμ¬ TipTap λΌμ΄λΈλ¬λ¦¬λ₯Ό λμ
νκ³ ν΄λΉ λΌμ΄λΈλ¬λ¦¬μ
컀μ€ν
Extension μ νμ©νμ¬ μλν°μ νμν κΈ°λ₯μ μ§μ ꡬννλ λ°©μμ μ±ννμμ΅λλ€.
κ°λ°μ μ§ννλ μ¬λμ΄ νμλ€μκ² νΉμ λΌμ΄λΈλ¬λ¦¬λ₯Ό λμ νλ λ°°κ²½κ³Ό κ·Όκ±°λ₯Ό μ€λͺ νλ νλ‘μΈμ€λ₯Ό κ±°μ³μ
λͺ¨λκ° νλ‘μ νΈ λ΄μ μ΄λ€ λΌμ΄λΈλ¬λ¦¬κ°, μ μ¬μ©λμλμ§λ₯Ό μ΄ν΄νκ³ λμ΄κ° μ μλλ‘ νμμ΅λλ€.
κ°μ₯ λ§μ νΌλλ°±μ λ°μ λΆλΆμ΄μ, κ°λ°νλ κ³Όμ μμλ νμ λͺ¨λκ° μ²΄κ°νλ λ¬Έμ λ λ°λ‘ λλ¦° λ‘λ© μλμμ΅λλ€.
μ ν¬λ μ΄ λ¬Έμ μ μμΈμ λ€μ 2κ°μ§λ‘ μΆμΈ‘νμμ΅λλ€.
- 첫 νμ΄μ§ λ λλ§ μμ λ무 λ§μ API νΈμΆμ΄ λ°μνλ€.
- μ€ν 리그룹, 곡κ°λ μ€ν 리 νμ΄μ§μμ λ§μ μ΄λ―Έμ§λ₯Ό μλ²μμ λΆλ¬μ€λ κ³Όμ μμ μ§μ°μ΄ λ°μνλ€.
λ¨Όμ 첫 λ²μ§Έ μμΈμ μλ‘ λ€λ₯Έ 2κ°μ APIλ₯Ό νΌμ©ν΄μ μ¬μ©νλ ꡬ쑰μμ λΉλ‘―λμμ΅λλ€.
μ μ μ 보λ Dallaem APIμμ, μ€ν 리 μ€μ μ 보λ Supabase DBμμ κ°κ° κ°μ ΈμμΌ νκ³
ν νΈμΆ κ²°κ³Όλ₯Ό λ€λ₯Έ νΈμΆμ νλΌλ―Έν°λ‘ μ¬μ©νλ€λ³΄λ μ¬λ¬κ°μ νΈμΆμ΄ λλ λκΉμ§
νλ©΄μ΄ νμλμ§ μλ κ²μ
λλ€.
μ΄λ₯Ό 보μνκΈ° μν΄ μ μλ λ°©μμ λ€μκ³Ό κ°μ΅λλ€.
- Dallaem API μμ‘΄λλ₯Ό μ€μ΄κ³ , μ체 Supabase ν μ΄λΈλ‘ λ°μ΄ν°λ₯Ό μ΄μ &κ΄λ¦¬νμ¬ νΈμΆ νμλ₯Ό κ°μ (μ§ν μ€)
- Server Side Rendering μμ μ΄κΈ° νλ©΄μ κ·Έλ €μ§ λ°μ΄ν°λ₯Ό prefetchνμ¬ μ²« λ λλ§ μλλ₯Ό ν₯μ (μ§ν μ€)
- μ€μΌλ ν€ UI, Spinner, loading.tsx λ±μ μ‘°ν©νμ¬ λ‘λ© μμ μ¬μ©μ κ²½νμ κ°μ (μ§ν μ€)
- νμν μ¬λ¬κ°μ μμ²μ νλμ λ€νΈμν¬ μμ²μ λ¬Άλ λ€μ€ 쿼리, RPC λ±μ λμ (μμ μ )
λ λ²μ§Έλ‘ λ§μ μ΄λ―Έμ§λ₯Ό λΆλ¬μ€λ κ³Όμ μμ λ°μνλ μ§μ° λ¬Έμ λ₯Ό 보μνκΈ° μν΄ μ μλ λ°©μμ λ€μκ³Ό κ°μ΅λλ€.
- next/imageμ priority μμ±μ νμ©νμ¬ μ²« νλ©΄μ 보μ΄λ μ΄λ―Έμ§λ₯Ό μ°μ μΌλ‘ κ°μ Έμ€κ³ , μ€ν¬λ‘€ μλμ μ΄λ―Έμ§λ lazy-loadingλ±μ μ μ© (μλ£)
- next/imageμ sizes, quality, placeholder μμ± λ±μ νμ©νμ¬ μ΄λ―Έμ§λ₯Ό μ΅μ ννκ±°λ UXκ°μ (μ§ν μ€)
- sharp λΌμ΄λΈλ¬λ¦¬ λ±μ λμ νμ¬ μλ²μμ λ€μ΄μ€λ μ΄λ―Έμ§ ν¬κΈ°λ₯Ό μμΆν νμ ν΄λΌμ΄μΈνΈ λ λλ§ (μμ μ )
next/imageλ‘ sizes, priorityμμ±μ μ μ©ν λΈλμΉλ₯Ό κΈ°μ€μΌλ‘
lightHouse ν
μ€νΈ κ²°κ³Ό FCP, LCP λ±μ΄ μν κ°μ λ κ²μΌλ‘ νμΈνμμ΅λλ€.
| κΈ°μ‘΄ | next/image κ°μ ν | |
|---|---|---|
| Performace(DeskTop) μ μ νκ· | 79.5 | 84 |
| Performace(Mobile) μ μ νκ· | 63 | 71 |
| First Contentful Paint (FCP) νκ· | 0.35s | 0.2s |
| Largest Contentful Paint (LCP) μ μ νκ· | 3.95s | 2.95s |
| Speed Index νκ· | 0.45s | 0.4s |
λ¨, Lighthouse κΈ°λ°μ μ±λ₯ μΈ‘μ μ μΈλΆ νκ²½μ μν₯μ λ°μΌλ©°, μ¬μ ν λ λλ§ μλκ° λ리기 λλ¬Έμ μ΄λ₯Ό 보μνκΈ° μν΄μ
λ€μν μ±λ₯ μΈ‘μ λ°©λ²μ λμ
ν μμ μ
λλ€. λν μ΄λ―Έμ§ μ΅μ ν λ°©μμ λν΄μλ μΆκ° λ
Όμ μ€μ
λλ€.
λ‘λ© μλ μΈμ κ°μ₯ λ§μ νΌλλ°±μ λ°μ λΆλΆμ 'λͺ¨μ'κ³Ό 'μ€ν 리'μ κ°λ
μ ꡬλΆνκΈ° μ΄λ ΅λ€λ κ²μ΄μμ΅λλ€.
μ΄λ¬ν νΌλλ°±μ λ°μ λ°μλ μ¬λ¬κ°μ§ μ΄μ κ° μμ κ²μ΄λΌ λΆμνκ³ μμ§λ§,
κ·Έ μ€ νλλ 'λͺ¨μ μ°ΎκΈ°'μ 'μ€ν 리 μ°ΎκΈ°' λΌλ νμ΄μ§λͺ
μ΄ μ§κ΄μ μ΄μ§ μλ€κ³ νλ¨νμ¬ κ°μ μ μ§ννμ΅λλ€.
λ€μ΄λ°μ μ₯κΈ°μ μΌλ‘ κ³ λ―Όνμ¬ λ κ°μ ν κ³νμ΄μ§λ§, μΌλ¨ 'λͺ¨μ μ°ΎκΈ°'λ 'μ€ν 리그룹' μΌλ‘,
'μ€ν 리 μ°ΎκΈ°'λ '곡κ°λ μ€ν 리' λ‘ λ³κ²½νκ³ μμ΄μ½μ μΆκ°νμ¬ μ¬μ©μκ° μλ―Έλ₯Ό νμ
νκΈ°μ λ³΄λ€ μ©μ΄νλλ‘ κ°μ νμμ΅λλ€.
μ΄κΈ°μλ νμκ°μ
μ΄λ λ‘κ·ΈμΈ μ±κ³΅ μ λͺ¨λ ν νλ©΄μΌλ‘ μ΄λνλλ‘ κ΅¬ννμΌλ,
μ¬μ©μ νΌλλ°±μ ν΅ν΄ μ΄λ¬ν μ νμ΄ λ€μ λΆμμ°μ€λ½κ² λκ»΄μ§λ€λ μ μ μΈμ§νκ³
κ°μ μ μ§ννμμ΅λλ€.
λ¨Όμ , νμκ°μ
ν μλ¬΄λ° νΌλλ°± μμ΄ ν νλ©΄μΌλ‘ μ΄λλλ νλ¦μ κ°μ νμ¬,
κ°μ
μ±κ³΅ λ©μμ§λ₯Ό ν μ€νΈλ‘ 보μ¬μ€ λ€ λ‘κ·ΈμΈ νλ©΄μΌλ‘ μ νλλλ‘ λ³κ²½νμ΅λλ€.
λν, λ‘κ·ΈμΈ μ±κ³΅ μμλ μ¬μ©μκ° λ‘κ·ΈμΈ μ λ¨Έλ¬Όλ λ νμ΄μ§λ‘ λλμκ° μ μλλ‘
리λλ μ
λ‘μ§μ κ°μ νμ΅λλ€. μ΄λ₯Ό μν΄ useReferer 컀μ€ν
ν
μ λ§λ€μ΄, μ΄μ νμ΄μ§μ URLμ μΈμ½λ©ν΄
refererλ‘ μ μ₯νκ³ , λ‘κ·ΈμΈ μ±κ³΅ μ μ΄λ₯Ό λμ½λ©νμ¬ ν΄λΉ νμ΄μ§λ‘ μ΄λμν€λλ‘ κ΅¬ννμμ΅λλ€.
/auths/signin?referer=...
- νμλ€κ° μμ λ‘κ² μν΅νκ³ , κΈ νΌλλ°±μ μ£Όκ³ λ°μ μ μλ μ±ν μμ€ν μ μΆκ°ν μμ μ λλ€.
- μ±
νμ§λ₯Ό λ§λ€ λ μ΄λ ν μ΄μΌκΈ°λ₯Ό λ§λ€ μμ μΈμ§ λΆμκΈ°λ ν€μλλ₯Ό λ£μΌλ©΄
AIλ₯Ό ν΅ν΄ νμ§ μ΄λ―Έμ§λ₯Ό λ§λ€μ΄μ£Όλ κΈ°λ₯μ μΆκ°ν μμ μ λλ€. - λ§μΆ€λ²μ΄ νλ¦° κΈμ΄ μ΄μΌκΈ°μ ν¬ν¨λμ§ μλλ‘ AIλ₯Ό ν΅ν΄ λ§μΆ€λ²μ κ²μ¬ν΄μ£Όλ κΈ°λ₯μ
μΆκ°ν μμ μ λλ€.
- νμλ€μ μμΈ νλ‘νμ νμΈν μ μλ κΈ°λ₯μ λ§λ€μ΄μ μλ‘μ κ΄μ¬μ¬λ μ±ν₯μ νμ
ν μ μλλ‘
νμ νλ‘ν 보기 κΈ°λ₯μ μΆκ°ν μμ μ λλ€.
- λ§μ½μ λͺ¨μμ₯μ΄ λͺ¨μμμ νν΄νλ€λ©΄? λκ΅°κ° μ
μμ μΌλ‘ κΈμ κ³μ μ¬λ¦°λ€λ©΄?
μ΄λ¬ν λ€μν μν©μμ λ°μν μ μλ λΆνΈμ ν΄κ²°ν μ μλλ‘ μ§κΈμ μ΄μ΄μ°κΈ° μμ€ν μ
λμ± κ°μ ν μμ μ λλ€.
Β© 2025 WeWrite. Licensed under the MIT License.


