메인 μ½˜ν…μΈ λ‘œ κ±΄λ„ˆλ›°κΈ°
pnpm dev λͺ…λ Ήμ–΄λŠ” **Hot Module Replacement(HMR)**λ₯Ό μ§€μ›ν•˜λŠ” 개발 μ„œλ²„λ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€. μ½”λ“œλ₯Ό μˆ˜μ •ν•˜λ©΄ μ„œλ²„λ₯Ό μž¬μ‹œμž‘ν•˜μ§€ μ•Šκ³ λ„ 변경사항이 μ¦‰μ‹œ λ°˜μ˜λ©λ‹ˆλ‹€.

κΈ°λ³Έ μ‚¬μš©λ²•

pnpm dev
개발 μ„œλ²„κ°€ μ‹œμž‘λ˜λ©΄ λ‹€μŒ κΈ°λŠ₯을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€:
  • μžλ™ μž¬μ‹œμž‘: μ½”λ“œ λ³€κ²½ μ‹œ μžλ™μœΌλ‘œ μ„œλ²„ μž¬μ‹œμž‘
  • TypeScript 지원: .ts νŒŒμΌμ„ λ°”λ‘œ μ‹€ν–‰
  • μ†ŒμŠ€λ§΅ 지원: μ—λŸ¬ λ°œμƒ μ‹œ μ •ν™•ν•œ 쀄 번호 ν‘œμ‹œ
  • ν‚€λ³΄λ“œ 단좕킀: λΉ λ₯Έ μž‘μ—…μ„ μœ„ν•œ 단좕킀

λ™μž‘ 원리

pnpm devλŠ” λ‚΄λΆ€μ μœΌλ‘œ λ‹€μŒ 도ꡬ듀을 μ‚¬μš©ν•©λ‹ˆλ‹€:
λ„κ΅¬μ—­ν• μ œκ³΅
@sonamu-kit/hmr-runnerHMR μ‹€ν–‰ μ—”μ§„Sonamu
@sonamu-kit/ts-loaderTypeScript λ‘œλ”Sonamu
@sonamu-kit/hmr-hookHMR ν›…Sonamu
μ€‘μš”: 이 νŒ¨ν‚€μ§€λ“€μ€ Sonamuκ°€ μžλ™μœΌλ‘œ μ œκ³΅ν•˜λ―€λ‘œ λ³„λ„λ‘œ μ„€μΉ˜ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

μ‹€ν–‰ κ³Όμ •

  1. src/index.tsλ₯Ό μ—”νŠΈλ¦¬ν¬μΈνŠΈλ‘œ μ‹€ν–‰
  2. TypeScript νŒŒμΌμ„ μ¦‰μ‹œ λ³€ν™˜ν•˜μ—¬ μ‹€ν–‰
  3. 파일 λ³€κ²½ 감지
  4. λ³€κ²½λœ λͺ¨λ“ˆλ§Œ ꡐ체 (HMR)
  5. 전체 μž¬μ‹œμž‘μ΄ ν•„μš”ν•œ κ²½μš°μ—λ§Œ μž¬μ‹œμž‘

ν‚€λ³΄λ“œ 단좕킀

개발 μ„œλ²„ μ‹€ν–‰ 쀑 λ‹€μŒ 단좕킀λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€:
단좕킀기λŠ₯μ„€λͺ…
rμž¬μ‹œμž‘μ„œλ²„λ₯Ό μˆ˜λ™μœΌλ‘œ μž¬μ‹œμž‘ν•©λ‹ˆλ‹€
fκ°•μ œ μž¬μ‹œμž‘sonamu.lock νŒŒμΌμ„ μ‚­μ œν•˜κ³  μž¬μ‹œμž‘ν•©λ‹ˆλ‹€
Enterν…ŒμŠ€νŠΈν‚€ 바인딩 ν…ŒμŠ€νŠΈμš©
Ctrl+F Ctrl+Fμ—…λ°μ΄νŠΈGit pull, νŒ¨ν‚€μ§€ μ„€μΉ˜, λΉŒλ“œ ν›„ μž¬μ‹œμž‘

단좕킀 μ‚¬μš© μ˜ˆμ‹œ

μ„œλ²„ μž¬μ‹œμž‘:
# ν„°λ―Έλ„μ—μ„œ 개발 μ„œλ²„ μ‹€ν–‰ 쀑
[μ„œλ²„ μ‹€ν–‰ 쀑...]

# 'r' ν‚€ μž…λ ₯
r

# μ„œλ²„ μž¬μ‹œμž‘λ¨
πŸ”„ Restarting server...
κ°•μ œ μž¬μ‹œμž‘ (μΊμ‹œ μ΄ˆκΈ°ν™”):
# 'f' ν‚€ μž…λ ₯
f

# sonamu.lock μ‚­μ œ ν›„ μž¬μ‹œμž‘
πŸ—‘οΈ  Removing sonamu.lock...
πŸ”„ Restarting server...

ν™˜κ²½ λ³€μˆ˜

개발 μ„œλ²„λŠ” λ‹€μŒ ν™˜κ²½ λ³€μˆ˜λ₯Ό μžλ™μœΌλ‘œ μ„€μ •ν•©λ‹ˆλ‹€:
λ³€μˆ˜κ°’μ„€λͺ…
NODE_ENVdevelopment개발 λͺ¨λ“œ ν‘œμ‹œ
HOTyesHMR ν™œμ„±ν™” ν”Œλž˜κ·Έ
API_ROOT_PATHν”„λ‘œμ νŠΈ 경둜HMR 루트 디렉토리
μ½”λ“œμ—μ„œ ν™˜κ²½ λ³€μˆ˜λ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€:
if (process.env.NODE_ENV === 'development') {
  console.log('개발 λͺ¨λ“œμž…λ‹ˆλ‹€');
}

if (process.env.HOT === 'yes') {
  console.log('HMR이 ν™œμ„±ν™”λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€');
}

HMR λ™μž‘ 방식

μžλ™ μž¬μ‹œμž‘λ˜λŠ” 경우

λ‹€μŒ νŒŒμΌμ„ μˆ˜μ •ν•˜λ©΄ μ„œλ²„κ°€ μžλ™μœΌλ‘œ μž¬μ‹œμž‘λ©λ‹ˆλ‹€:
  • Entity 파일 (*.entity.ts)
  • Model 파일 (*.model.ts)
  • Config 파일 (sonamu.config.ts)
  • Migration 파일
// user.model.ts μˆ˜μ •
class UserModelClass extends BaseModel {
  @api({ httpMethod: "GET" })
  async findById(id: number) {
    return this.getPuri("r").where("id", id).first();
  }
}

// 파일 μ €μž₯ β†’ μ„œλ²„ μžλ™ μž¬μ‹œμž‘

μ¦‰μ‹œ λ°˜μ˜λ˜λŠ” 경우 (HMR)

λ‹€μŒ νŒŒμΌμ„ μˆ˜μ •ν•˜λ©΄ μ„œλ²„ μž¬μ‹œμž‘ 없이 μ¦‰μ‹œ λ°˜μ˜λ©λ‹ˆλ‹€:
  • 일반 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직
  • μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜
  • μ„œλΉ„μŠ€ λ ˆμ΄μ–΄
// utils/helper.ts μˆ˜μ •
export function formatDate(date: Date) {
  return date.toISOString();
}

// 파일 μ €μž₯ β†’ μ¦‰μ‹œ 반영 (μž¬μ‹œμž‘ μ—†μŒ)

문제 ν•΄κ²°

μ„œλ²„κ°€ μ‹œμž‘λ˜μ§€ μ•ŠλŠ” 경우

문제: ν¬νŠΈκ°€ 이미 μ‚¬μš© 쀑
Error: listen EADDRINUSE: address already in use :::3000
ν•΄κ²°:
# 포트 μ‚¬μš© 쀑인 ν”„λ‘œμ„ΈμŠ€ μ’…λ£Œ
lsof -ti:3000 | xargs kill -9

# λ‹€μ‹œ μ‹œμž‘
pnpm dev

HMR이 μž‘λ™ν•˜μ§€ μ•ŠλŠ” 경우

문제: μ½”λ“œ 변경이 λ°˜μ˜λ˜μ§€ μ•ŠμŒ ν•΄κ²°:
# 1. κ°•μ œ μž¬μ‹œμž‘ (f ν‚€)
f

# 2. λ˜λŠ” μˆ˜λ™ μž¬μ‹œμž‘
pnpm dev

TypeScript 였λ₯˜κ°€ λ°œμƒν•˜λŠ” 경우

문제: νƒ€μž… μ—λŸ¬λ‘œ μ„œλ²„ μ‹€ν–‰ μ‹€νŒ¨ ν•΄κ²°:
# νƒ€μž… 체크
pnpm tsc --noEmit

# 문제 μˆ˜μ • ν›„ λ‹€μ‹œ μ‹œμž‘
pnpm dev

μ‹€μ „ 팁

1. λΉ λ₯Έ 개발 사이클

μ½”λ“œλ₯Ό μˆ˜μ •ν•˜κ³  λ°”λ‘œ ν…ŒμŠ€νŠΈν•  수 μžˆμŠ΅λ‹ˆλ‹€:
// API μ—”λ“œν¬μΈνŠΈ μˆ˜μ •
@api({ httpMethod: "GET" })
async getUsers() {
  return this.findMany({ num: 10, page: 1 });
}

// μ €μž₯ β†’ μžλ™ μž¬μ‹œμž‘ β†’ λ°”λ‘œ ν…ŒμŠ€νŠΈ

2. 둜그 확인

개발 μ„œλ²„λŠ” λͺ¨λ“  둜그λ₯Ό μ½˜μ†”μ— 좜λ ₯ν•©λ‹ˆλ‹€:
console.log('μ‚¬μš©μž 쑰회:', user);
logger.info('API 호좜', { method, path });
logger.error('μ—λŸ¬ λ°œμƒ', { error });

3. 디버깅

μ†ŒμŠ€λ§΅μ΄ ν™œμ„±ν™”λ˜μ–΄ μžˆμ–΄ μ •ν™•ν•œ 쀄 번호λ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€:
Error: User not found
    at UserModel.findById (user.model.ts:42:15)
    at API.handler (index.ts:28:20)

ν”„λ‘œλ•μ…˜κ³Όμ˜ 차이점

κΈ°λŠ₯개발 μ„œλ²„ν”„λ‘œλ•μ…˜
HMRβœ… ν™œμ„±ν™”βŒ λΉ„ν™œμ„±ν™”
TypeScriptμ¦‰μ‹œ μ‹€ν–‰μ»΄νŒŒμΌ ν•„μš”
μ†ŒμŠ€λ§΅μ›λ³Έ νŒŒμΌμ••μΆ•λœ 파일
μ„±λŠ₯λŠλ¦ΌλΉ λ¦„
μ—λŸ¬ ν‘œμ‹œμƒμ„Έν•¨κ°„λž΅ν•¨
개발 μ„œλ²„λŠ” ν”„λ‘œλ•μ…˜μ—μ„œ μ‚¬μš©ν•˜μ§€ λ§ˆμ„Έμš”!
  • μ„±λŠ₯이 느림
  • λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ΄ 많음
  • λ³΄μ•ˆμ— μ·¨μ•½
ν”„λ‘œλ•μ…˜μ—μ„œλŠ” pnpm build ν›„ pnpm startλ₯Ό μ‚¬μš©ν•˜μ„Έμš”.

λ‹€μŒ 단계