Skip to content

๐Ÿ… ์ปค๋ฐ‹ ํ€„๋ฆฌํ‹ฐ๋ฅผ ์ ์ˆ˜๋กœ, ๋ฑƒ์ง€๋กœ ์ž๋ž‘ํ•˜์„ธ์š”! Show off your commit quality with scores and a badge!

Notifications You must be signed in to change notification settings

git-marvel/commit-guardians-client

Repository files navigation

Commit Guardians

ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

project_intro.png


๋ชฉ์ฐจ


ํ˜„์žฌ ๊นƒํ—™ ๋ ˆํฌ์ง€ํ† ๋ฆฌ์˜ ์ปค๋ฐ‹๋“ค์€ ๊ณผ์—ฐ ๊ฑด๊ฐ•ํ•œ ์ƒํƒœ์ผ๊นŒ์š”?

์ด ์งˆ๋ฌธ์—์„œ ์‹œ์ž‘๋œ Commit Guardians ํŒ€ ํ”„๋กœ์ ํŠธ๋Š”, ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์™€ ์ฝ”๋“œ ๋ณ€๊ฒฝ ๊ฐ„์˜ ์ผ์น˜์„ฑ์„ ์ ๊ฒ€ํ•˜๊ณ , ๋ณด๋‹ค ๋‚˜์€ ์ปค๋ฐ‹ ๋ฌธํ™”๋ฅผ ํ˜•์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž์˜ ์ผ์ƒ์€ ์ฝ”๋“œ๋งŒ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ โ€˜๊ธฐ๋กโ€™์„ ๋‚จ๊ธฐ๊ณ  ๊ณต์œ ํ•˜๋Š” ๊ณผ์ •๊นŒ์ง€๋„ ํฌํ•จ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ํŒ€ ํ”„๋กœ์ ํŠธ๋‚˜ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์˜คํ”ˆ์†Œ์Šค์—์„œ๋„ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋Š” ์ž‘์—… ํ๋ฆ„์„ ์ดํ•ดํ•˜๊ณ  ์ง€๋‚œ ์ž‘์—…์„ ๋˜๋Œ์•„๋ณด๋ฉฐ ํ”„๋กœ์ ํŠธ์˜ ๋งฅ๋ฝ์„ ํŒŒ์•…ํ•˜๋Š” ๋ฐ์— ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ปค๋ฐ‹๋ฉ”์‹œ์ง€๋Š” ์ฝ”๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ์š”์•ฝํ•ด ์ค„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, โ€˜์™œโ€™ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋‚˜ ๋””๋ฒ„๊น…์„ ํ•  ๋•Œ ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋น ๋ฅด๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋Š” ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ์ปค๋ฐ‹ ํƒ€์ž…์— ๋”ฐ๋ผ ๋ฆด๋ฆฌ์ฆˆ ๋…ธํŠธ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ์–ด์„œ ์ž‘์—… ๋‹จ์œ„๋ฅผ ์ž˜๊ฒŒ ์ชผ๊ฐœ์–ด ์ปค๋ฐ‹์„ ํ•˜๋Š” ๊ฒƒ์€ ํ˜‘์—…์— ์žˆ์–ด์„œ ์ข‹์€ ์Šต๊ด€์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ์— ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์— ๋”ฐ๋ฅธ ์ฝ”๋“œ ์ˆ˜์ •์ด ์„œ๋กœ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์ข‹์€ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์˜ ๋‚ด์šฉ์€ ์˜๋ฏธ ์žˆ๋Š” ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋ฅผ ์“ฐ๋Š” ๊ฒƒ์ด๋ฉฐ, ์ตœ๋Œ€ํ•œ ๋…ผ๋ฆฌ์ ์ธ ๋‹จ์œ„๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋…ผ๋ฆฌ ๋‹จ์œ„๋ณ„๋กœ ๋‚˜๋ˆ„์–ด ์ปค๋ฐ‹์„ ํ•˜๋Š” ๊ฒƒ์ด ๊ฐœ๋ณ„ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์œผ๋กœ ๋˜๋Œ๋ฆฌ๊ธฐ ํŽธํ•˜๊ณ  ์–ด๋Š ๋ถ€๋ถ„์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋‚ฌ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์ˆ˜์›”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ผผ๊ผผํ•œ ์ปค๋ฐ‹๋“ค์ด ๋ชจ์—ฌ์„œ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•˜๊ณ  ํ˜‘์—…ํ•˜๊ธฐ ์ข‹์€ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ธฐ์ดˆ๊ฐ€ ๋  ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.


1-1. ๊นƒํ—ˆ๋ธŒ ๋กœ๊ทธ์ธ

  • ๋กœ๊ทธ์ธ ์‹œ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ๋ ˆํฌ์ง€ํ† ๋ฆฌ URL ์ž…๋ ฅ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋กœ๊ทธ์ธ ์ „์—๋Š” ์˜ˆ์‹œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋กœ ์„œ๋น„์Šค๋ฅผ ๋ฏธ๋ฆฌ ์ด์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1-2. ์„œ๋น„์Šค ์ด์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธํ•˜๊ธฐ

  • ํ—ค๋”์˜ ์šฐ์ธก ์ƒ๋‹จ ๋ถ€๋ถ„์—๋Š” Github API์˜ ์ƒํƒœ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ , ์ƒํƒœ๊ฐ€ ์ •์ƒ์ธ ๊ฒฝ์šฐ์—๋งŒ URL ์ž…๋ ฅ(์ปค๋ฐ‹ ๋ถ„์„)์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • Github API status ๋ฒ„ํŠผ ์„ ํƒ ์‹œ ์ƒ์„ธ ๋‚ด์—ญ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1-3. ํ˜„์žฌ ๋Œ€์‘ ๊ฐ€๋Šฅํ•œ ์ปค๋ฐ‹ ํƒ€์ž… ํ™•์ธํ•˜๊ธฐ

  • remove docs style test
  • ๋กœ๊ณ  ์ƒ๋‹จ์—๋Š” ์ด ํ”„๋กœ์ ํŠธ์—์„œ ๋ถ„์„ํ•˜๊ณ  ์žˆ๋Š” 4๊ฐœ์˜ ์ปค๋ฐ‹ ํƒ€์ž…์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1-4. ์ปค๋ฐ‹ ๋ถ„์„ ์‹œ์ž‘ํ•˜๊ธฐ

  • ๋งจ ์ฒ˜์Œ ๋ณด์ด๋Š” ํ™”๋ฉด์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ปค๋ฐ‹์„ ๋ถ„์„ ๋ฐ›๊ณ  ์‹ถ์€ ๊นƒํ—ˆ๋ธŒ ๋ ˆํฌ์ง€ํ† ๋ฆฌ์˜ URL์„ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • URL ์ž…๋ ฅํ•˜์—ฌ ์ œ์ถœํ•˜๋ฉด ๊ธฐ๋ณธ ๋ธŒ๋ Œ์น˜์˜ ์ปค๋ฐ‹ ๋ถ„์„์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

commit-badge.png

๋ฉ”์ธ ํŽ˜์ด์ง€์—์„œ ์ปค๋ฐ‹ ํ€„๋ฆฌํ‹ฐ ๋ถ„์„์ด ๋๋‚œ ํ›„ ๋ณด์—ฌ์ง€๋Š” ํŽ˜์ด์ง€์ž…๋‹ˆ๋‹ค.

2-1. ์ ์ˆ˜์— ๋”ฐ๋ฅธ ๋ฑƒ์ง€ ์ฐจ๋ณ„ํ™”

  • ์‚ฌ์šฉ์ž์˜ ์ ์ˆ˜์— ๋”ฐ๋ผ ๊ฐ๊ฐ ๋‹ค๋ฅธ ๋ฑƒ์ง€๊ฐ€ ์ฃผ์–ด์ง€๋ฉฐ 4๊ฐœ์˜ ๋ฑƒ์ง€๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ ์ˆ˜ ๊ตฌ๊ฐ„์€ 80์  ์ด์ƒ, 50์  ์ด์ƒ, 30์  ์ด์ƒ, 30์  ๋ฏธ๋งŒ์œผ๋กœ ์ฑ„์ ๋ฉ๋‹ˆ๋‹ค.

  • Copy your Badge ๋ฒ„ํŠผ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ README ์— ๋ฑƒ์ง€๋ฅผ ๋ถ™์—ฌ ๋„ฃ๊ธฐ ํ•  ์ˆ˜ ์žˆ๋Š” HTML ํƒœ๊ทธ๋ฅผ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2-2. ์ปค๋ฐ‹ ํ†ต๊ณ„ ๊ทธ๋ž˜ํ”„

  • ๋„๋„› ๊ทธ๋ž˜ํ”„
    • ์ค‘์•™์—” ๊ฒ€์‚ฌํ•œ ์ปค๋ฐ‹์˜ ์ด ๊ฐœ์ˆ˜๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ฒ€์‚ฌํ•œ ์ปค๋ฐ‹๋“ค์„ ์ปค๋ฐ‹ ํƒ€์ž…๋ณ„๋กœ ๋ถ„๋ฅ˜ํ•˜์—ฌ ๋น„์œจ์„ ๋‚˜ํƒ€๋ƒˆ์Šต๋‹ˆ๋‹ค.
  • ๋ง‰๋Œ€ ๊ทธ๋ž˜ํ”„
    • ๊ฐ€์žฅ ๋งŽ์ด ๊ธฐ์—ฌํ•œ ์ƒ์œ„ 3๋ช…์„ ์„ ์ •ํ•˜์—ฌ ๊ฐ์ž์˜ ์ปค๋ฐ‹์„ ์ปค๋ฐ‹ ํƒ€์ž…๋ณ„๋กœ ๋ถ„๋ฅ˜ํ•ด ๋‚˜ํƒ€๋ƒˆ์Šต๋‹ˆ๋‹ค.

2-3. ์ปค๋ฐ‹ ํ€„๋ฆฌํ‹ฐ ์ตœ์ข… ์ ์ˆ˜

  • 100์  ๋งŒ์ ์„ ๊ธฐ์ค€์œผ๋กœ ์‚ฌ์šฉ์ž์˜ ์ ์ˆ˜๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • View All Results ๋ฒ„ํŠผ์„ ํ†ตํ•ด ์ปค๋ฐ‹ ๋ถ„์„ ๊ฒฐ๊ณผ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฐ๊ฐ์˜ ์ปค๋ฐ‹๋งˆ๋‹ค์˜ ์ ์ˆ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2-4. FAQ

  • ๋ฉ”์ธ ํŽ˜์ด์ง€์—์„œ ์ž…๋ ฅ ๊ฐ€๋Šฅํ•œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ํ˜•์‹์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด ํ”„๋กœ์ ํŠธ์—์„œ ํ™•์ธํ•˜๋Š” ์ปค๋ฐ‹ ํƒ€์ž…๊ณผ ์ฑ„์  ๋ฐฉ์‹์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2-5. ์‚ฌ์šฉ์ž์™€์˜ ์†Œํ†ต์„ ์œ„ํ•œ ์ด๋ฉ”์ผ์ฃผ์†Œ์™€ ๊นƒํ—ˆ๋ธŒ ๋งํฌ

  • ํ‘ธํ„ฐ์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์•„์ด๋””์–ด๋ฅผ ์ œ์•ˆํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ฉ”์ผ ์ฃผ์†Œ์™€ ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์˜ ๊นƒํ—ˆ๋ธŒ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋งํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

scoreboard.png

์ปค๋ฐ‹ ํ€„๋ฆฌํ‹ฐ๋ฅผ ๋ถ„์„ํ•œ ๊ฐ ์ปค๋ฐ‹์— ๋Œ€ํ•œ ์ƒ์„ธ ์ •๋ณด๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊นƒํ—ˆ๋ธŒ ์†Œ์œ ์ž์™€ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ์ด๋ฆ„

  • ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ํ˜•์‹๋ณ„๋กœ ๋ถ„๋ฅ˜๋œ ๋น„์œจ

    1. Prefix Style
    2. Simple Text
    3. Template Based Style
  • ๊ฐ ์ปค๋ฐ‹์˜ ์ •๋ณด

    • COMMIT MESSAGE : ์„ ํƒ ์‹œ ํ•ด๋‹น ์ปค๋ฐ‹์˜ ๊นƒํ—ˆ๋ธŒ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ํŽ˜์ด์ง€๊ฐ€ ์—ด๋ฆฝ๋‹ˆ๋‹ค.
    • CHANGES : ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ ๊ฐœ์ˆ˜๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, -/+ ์˜ ๋ฌถ์Œ์„ Change ๋กœ ์ •์˜ํ•˜์—ฌ ๋ง‰๋Œ€๊ทธ๋ž˜ํ”„๋ฅผ ํ†ตํ•ด ์ผ์น˜์œจ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      • Change ๋‹จ์œ„ ์˜ˆ์‹œ

        - change 2๊ฐœ

    • DATE : ๋กœ์ปฌ๋‚ ์งœ์™€ ์‹œ๊ฐ„์„ ๊ธฐ์ค€์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • SHA : ์ „์ฒด SHA ๊ฐ’์„ ๋ณต์‚ฌํ•˜๊ฑฐ๋‚˜ 7์ž๋ฆฌ๋งŒ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

JavaScript React tailwindcss

Axios zustand

VITE ESLint Prettier npm Git GitHub

๊ธฐํƒ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • diff-match-patch : ๊ตฌ๊ธ€์˜ Neil Fraser๊ฐ€ ๊ฐœ๋ฐœํ•œ ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ํ…์ŠคํŠธ์˜ ์ฐจ์ด์ (diffs)์„ ๊ณ„์‚ฐํ•˜๊ณ  ํŒจ์น˜๋ฅผ ์ƒ์„ฑ ๋ฐ ์ ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋Ÿ‰์˜ ์ปค๋ฐ‹์„ ์ •ํ™•ํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ๋ถ„์„ํ•˜์—ฌ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ™•์ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • idb-keyval : IndexedDB๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฒฝ๋Ÿ‰ ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, key-value ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐ ์กฐํšŒ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. zustand ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์ƒํƒœ๋ฅผ ๋ธŒ๋ผ์šฐ์ €์˜ IndexedDB์— ์ €์žฅํ•  ์ˆ˜ ์žˆ์–ด ๋Œ€๋Ÿ‰์˜ ์ƒํƒœ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ , ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


1๏ธโƒฃ Problem

REST API๋ฅผ ์ด์šฉํ•˜์—ฌ ์š”์ฒญํ•  ๊ฒฝ์šฐ, ์—”๋“œํฌ์ธํŠธ๋งˆ๋‹ค ์ „๋‹ฌ๋ฐ›๋Š” ๋ฐ์ดํ„ฐ ํ˜•์‹์ด ๊ณ ์ •๋˜์–ด ์žˆ์–ด ๋ถˆํ•„์š”ํ•œ ์ •๋ณด๋„ ํ•จ๊ป˜ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ๋„คํŠธ์›Œํฌ, ๋ฉ”๋ชจ๋ฆฌ, ํ”„๋กœ์„ธ์„œ ๋“ฑ์˜ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋‚ญ๋น„๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ, facebook/react์™€ ๊ฐ™์€ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋ถ„์„ํ•  ๊ฒฝ์šฐ ๋Œ€๋žต 1,500๋ฒˆ์˜ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์‘๋‹ต์„ ๋ฐ›์•„ 2๋งŒ ๊ฐœ ์ •๋„์˜ ์ปค๋ฐ‹์„ ๊ฒ€์‚ฌํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ตœ์†Œ 5~10์ดˆ ์ •๋„์˜ ๋กœ๋”ฉ ์‹œ๊ฐ„์˜ ๋ฐœ์ƒ๊ณผ ๋ ‰์„ ์ฒด๊ฐํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

2๏ธโƒฃย Action

๊นƒํ—ˆ๋ธŒ๋Š” ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ๋”์šฑ ์œ ์—ฐํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก GraphQL์ด๋ผ๋Š” ๋ฐ์ดํ„ฐ ์ฟผ๋ฆฌ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•œ API๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ์ •๋ณด๋งŒ ์Šคํ‚ค๋งˆ์— ๋ช…์‹œํ•˜์—ฌ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‚ฌ์šฉ์ž๋Š” ๋Œ€์—ญํญ๊ณผ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ GraphQL์€ ์‚ฌ์šฉํ•  ๋•Œ ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ์ฐจ์ด์ ์ด ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค.

  1. ํ† ํฐ ๊ธฐ๋ฐ˜ ํŽ˜์ด์ง€๋„ค์ด์…˜ (Token-Based Pagination)

    GraphQL์€ ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ์ง€์›ํ•˜์ง€๋งŒ, ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ ๊ธฐ๋ฐ˜์ด ์•„๋‹Œ ํ† ํฐ ๊ธฐ๋ฐ˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ์ˆœ์ฐจ์ ์œผ๋กœ ๋‹ค์Œ ํŽ˜์ด์ง€์˜ ๋‚ด์šฉ์„ ์š”์ฒญํ•ด์•ผ ํ–ˆ๊ณ , REST API์ฒ˜๋Ÿผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ปค๋ฐ‹ ๋ชฉ๋ก์„ ๋ณ‘๋ ฌ๋กœ ์š”์ฒญํ•  ์ˆ˜ ์—†์–ด ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์‹œ๊ฐ„์ด ๋งŽ์ด ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

  2. ์ปค๋ฐ‹ ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๋ฏธ์ œ๊ณต

    GraphQL์€ ์ปค๋ฐ‹์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ œ๊ณตํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

3๏ธโƒฃย Result

๋ฐ์ดํ„ฐ๋ฅผ ์ฟผ๋ฆฌ์–ธ์–ด์ธ GraphQL๋กœ ์ „ํ™˜ํ•˜์—ฌ ๋ฆฌ์†Œ์Šค์˜ ์‚ฌ์šฉ์„ ์ตœ์ ํ™”ํ•˜๋ ค ํ–ˆ์—ˆ์ง€๋งŒ, ์œ ์ € ์‚ฌ์šฉ์„ฑ์„ ์œ„ํ•ด ๊ธฐ์กด REST API๋กœ ์š”์ฒญํ•˜๋˜ ๋ฐฉ์‹์„ ์œ ์ง€ํ•˜๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.


Github API Rate Limit ์ฐธ๊ณ  ๋งํฌ

1๏ธโƒฃ Problem

Github API ํ˜ธ์ถœ ์ธ์ฆ๋œ ํ† ํฐ ์‹œ๊ฐ„๋‹น 5,000ํšŒ ์ œํ•œ

Github API ์— ์˜์กด๋„๊ฐ€ ๋†’์€ ํ”„๋กœ์ ํŠธ์˜€๊ธฐ์— Github API ์š”์ฒญ ์ œํ•œ ์ˆ˜๋Š” ์ €ํฌ ํ”„๋กœ์ ํŠธ์—์„œ ์น˜๋ช…์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ปค๋ฐ‹ ๋ถ„์„ ๋กœ์ง์€ API ํ˜ธ์ถœ์„ ํ†ตํ•ด ํ•„์š”ํ•œ ๊ฐ’๋“ค์„ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์˜ ์ปค๋ฐ‹ ํƒ€์ž…์„ ๋ถ„์„ํ•œ ์ดํ›„, ๊ฒ€์‚ฌ ๊ฐ€๋Šฅํ•œ ์ปค๋ฐ‹ ํƒ€์ž…๋“ค๋งŒ์„ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค. ํ•„ํ„ฐ๋งํ•œ ์ปค๋ฐ‹์˜ owner, repo, sha ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ API ํ˜ธ์ถœ์„ ํ†ตํ•ด ์ฝ”๋“œ์˜ ์ˆ˜์ • ์ •๋ณด์ธ diff ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

ํŠนํžˆ๋‚˜ ํ•œ ์ธ์ฆ๋œ ํ† ํฐ ์‹œ๊ฐ„๋‹น 5,000ํšŒ๊ฐ€ ์ตœ๋Œ€์˜€๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ๋ฅผ ๋“ค์–ด, facebook/react ์™€ ๊ฐ™์ด ์ปค๋ฐ‹ ๊ฐฏ์ˆ˜๊ฐ€ 19,000๊ฐœ ์ด์ƒ์˜ ๊ฒฝ์šฐ 19,000/100 = 190ํšŒ API ํ˜ธ์ถœ์„ ํ†ตํ•ด ์ „์ฒด ์ปค๋ฐ‹์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ๊ฒ€์‚ฌ ๊ฐ€๋Šฅํ•œ ์ปค๋ฐ‹์„ ์ถ”์ถœํ•˜๋ฉด (2024.12.25 ์ผ ๊ธฐ์ค€์œผ๋กœ) 1450 ๊ฐœ์ด๋ฏ€๋กœ, 1,450ํšŒ์˜ diff API ํ˜ธ์ถœ์„ ๋” ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ฆ‰, facebook/react ๋Š” 190 + 1,450 = 1,640ํšŒ์˜ API ํ˜ธ์ถœ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์‚ฌ์‹ค 2, 3๋ฒˆ์˜ facebook/react ์ •๋„์˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋งŒ ์กฐํšŒํ•˜๋”๋ผ๋„ GitHub API Rate Limit๋ฅผ ๋ชจ๋‘ ์†Œ์ง„ํ•˜๊ฒŒ ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ, ๊ฒ€์‚ฌ ๊ฐ€๋Šฅํ•œ ์ปค๋ฐ‹ ํƒ€์ž…์ด ์ถ”๊ฐ€๊ฐ€ ๋œ๋‹ค๋ฉด ๋” ๋งŽ์€ API ํ˜ธ์ถœ์„ ์˜ˆ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋ชจ๋“  ์ปค๋ฐ‹์ด ๊ฒ€์‚ฌ ๋Œ€์ƒ์ด๋ผ๋ฉด ์ปค๋ฐ‹ ๊ฐœ์ˆ˜์˜ 101%๋งŒํผ API ํ˜ธ์ถœ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ธ์ฆ๋œ ํ† ํฐ ๋กœํ…Œ์ด์…˜ ๋ฐฉ์‹ ๊ฒ€ํ† 

GitHub API ์š”์ฒญ ์ œํ•œ์€ ํ† ํฐ๋งˆ๋‹ค ๋…๋ฆฝ์ ์œผ๋กœ ์ ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. API ํ˜ธ์ถœ์ด ๋งŽ์€ ์ž‘์—…์—์„œ Rate Limit๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ–ˆ๊ณ , ํ•˜๋‚˜์˜ ํ† ํฐ๋งŒ์œผ๋กœ๋Š” ํ”„๋กœ์ ํŠธ ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ถฉ์กฑํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ Personal Access Token(PAT)์„ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„ ์ด๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๋กœํ…Œ์ด์…˜ํ•˜๋Š” ๋ฐฉ์‹์„ ์ฐจ ์šฐ์„ ์œผ๋กœ ๊ฒ€ํ† ํ–ˆ์Šต๋‹ˆ๋‹ค.

2๏ธโƒฃย Action

ํ† ํฐ ๋กœํ…Œ์ด์…˜ ๋กœ์ง ๊ตฌํ˜„ํ•˜์—ฌ ์ผ์‹œ์ ์œผ๋กœ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ํ† ํฐ์„ tokenStates์ด๋ผ๋Š” ๋ฐฐ์—ด๋กœ ๊ด€๋ฆฌํ•˜๋ฉฐ, ๊ฐ ํ† ํฐ์˜ ๋‚จ์€ ํ˜ธ์ถœ ๊ฐ€๋Šฅ ํšŸ์ˆ˜(remaining)๋ฅผ ์ถ”์ ํ•˜๋„๋ก ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค. API ํ˜ธ์ถœ ์‹œ, ๋‚จ์€ ์š”์ฒญ๋Ÿ‰์ด ๊ฐ€์žฅ ๋งŽ์€ ํ† ํฐ์„ ์„ ํƒํ•ด Rate Limit ์ดˆ๊ณผ๋ฅผ ๋ฐฉ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜ธ์ถœ ํ›„, GitHub API์˜ ์‘๋‹ต ํ—ค๋”์—์„œ ๋ฐ˜ํ™˜๋˜๋Š” X-RateLimit-Remaining ๊ฐ’์„ ์‚ฌ์šฉํ•ด ํ† ํฐ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. getBestGithubToken() ํ˜„์žฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ† ํฐ ์ค‘ ๊ฐ€์žฅ ๋งŽ์€ ๋‚จ์€ ์š”์ฒญ ํšŸ์ˆ˜๋ฅผ ๊ฐ€์ง„ ํ† ํฐ์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. updateTokenState() ํ˜ธ์ถœ ํ›„, ์‚ฌ์šฉํ•œ ํ† ํฐ์˜ ์ƒํƒœ๋ฅผ ์ตœ์‹  ์ƒํƒœ๋กœ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ํ† ํฐ์„ ๋“ค๊ณ  ์˜ฌ ๋•Œ ๋‚จ์€ ํ˜ธ์ถœ ๊ฐ€๋Šฅ ํšŸ์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

const GITHUB_REQUEST_LIMIT = 5000;

const tokenStates = [
  {
    token: import.meta.env.VITE_GITHUB_TOKEN,
    remaining: GITHUB_REQUEST_LIMIT,
  },
  ...
];

const getBestGithubToken = () => {
  tokenStates.sort((a, b) => b.remaining - a.remaining);

  return tokenStates[0].token;
};

const updateTokenState = (token, remaining) => {
  const tokenState = tokenStates.find((t) => t.token === token);

  if (tokenState) {
    tokenState.remaining = remaining;
  }
};

export { getBestGithubToken, updateTokenState };

3๏ธโƒฃย Result

์—ฌ๋Ÿฌ ํ† ํฐ์„ ํ™œ์šฉํ•œ ๋กœํ…Œ์ด์…˜ ๋ฐฉ์‹์œผ๋กœ, ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ facebook/react์ฒ˜๋Ÿผ ์ปค๋ฐ‹์ด ๋งŽ์€ ๋ ˆํฌ์ง€ํ† ๋ฆฌ์—์„œ๋„ ๋ถ„์„์ด ์ค‘๋‹จ๋˜์ง€ ์•Š๊ณ  ์™„๋ฃŒ๋  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํ† ํฐ์ด ์ถ”๊ฐ€๋  ๊ฒฝ์šฐ tokenStates ๋ฐฐ์—ด์—๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ ์šฉ๋˜๋„๋ก ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค.


1๏ธโƒฃ Problem

๊ฒ€์‚ฌํ•  ์ปค๋ฐ‹์ด ๋‹จ์ผ ํ† ํฐ์˜ ์š”์ฒญ๋Ÿ‰์ธ 5,000๊ฐœ ์ด์ƒ์˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋„ ์ •์ƒ์ ์œผ๋กœ ๋ชจ๋‘ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ† ํฐ ๋กœํ…Œ์ด์…˜ ๋ฐฉ์‹์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋ฐฐํฌํ•˜์ง€ ์•Š๊ณ  ๋กœ์ปฌ์—์„œ๋งŒ ์šด์˜ํ•œ๋‹ค๋ฉด ํ† ํฐ ๋กœํ…Œ์ด์…˜ ๋ฐฉ์‹์œผ๋กœ๋„ ๋ฌธ์ œ๊ฐ€ ์—†๊ฒ ์ง€๋งŒ, ๋ฐฐํฌํ•˜์—ฌ ์„œ๋น„์Šคํ•œ๋‹ค๋ฉด ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ด์šฉํ•˜๋Š” API ์‚ฌ์šฉ๋Ÿ‰์ด ์ €ํฌ๊ฐ€ ์ˆ˜๋™์œผ๋กœ ์ถ”๊ฐ€ํ•œ ํ† ํฐ์˜ ์š”์ฒญ๋Ÿ‰์„ ๊ฐ๋‹นํ•  ์ˆ˜ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์œ ์ €์˜ ์ ‘๊ทผ์„ฑ์„ ์œ„ํ•ด ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์œผ๋ ค ํ–ˆ์ง€๋งŒ, ๋ฐฐํฌ๋œ ์„œ๋น„์Šค๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋Œ์•„๊ฐ€๋ ค๋ฉด ๊ฐ ์œ ์ €์˜ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ตœ์„ ์ด๊ณ  ๊ฒฐ๊ตญ ๋กœ๊ทธ์ธ์€ ํ•„์ˆ˜ ๋ถˆ๊ฐ€๊ฒฐ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š๊ณ  ์„œ๋น„์Šค๋ฅผ ๊ฒฝํ—˜ํ•˜๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•˜๋‹ค ์ƒ๊ฐํ•˜์—ฌ ๋ฐฉ๋ฒ•์„ ์ฐพ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

2๏ธโƒฃย Action

- ๋ฐ๋ชจ ๋ฒ„์ „ ์ œ๊ณต ๊ณ ๋ ค

์ฒ˜์Œ์—๋Š” ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋งํฌ๋ฅผ ์ œ์ถœํ•˜๋ฉด ๊ธฐ๋ณธ ํ† ํฐ์˜ ์š”์ฒญ๋Ÿ‰(์‹œ๊ฐ„๋‹น 60๊ฐœ)์„ ์ด์šฉํ•˜์—ฌ ์ผ๋ถ€๋งŒ ๋ณด์—ฌ์ฃผ๋„๋ก ํ•˜๊ณ  ๋กœ๊ทธ์ธ์„ ์œ ๋„ํ•˜๋ ค ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ •๋ง ์ผ๋ถ€์˜ ์ปค๋ฐ‹ ๋ถ„์„๋งŒ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๊ณ  ํ†ต๊ณ„ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ํ† ํฐ์˜ ์š”์ฒญ๋Ÿ‰์„ ๋น ๋ฅด๊ฒŒ ์†Œ์ง„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋ถ„์„ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ผ๋ถ€ ๊ฒฝ์šฐ์—๋Š” API์— ์ ‘๊ทผ ์ž์ฒด๊ฐ€ ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋„ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

- ๋ชฉ์—… ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•œ ๋™์ผํ•œ ๊ฒฝํ—˜ ์ œ๊ณต

๋”ฐ๋ผ์„œ ์ผ๋ถ€ ์œ ๋ช…ํ•œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ๋ชฉ์—… ๋ฐ์ดํ„ฐ๋กœ ์ œ๊ณตํ•˜๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•œ ์œ ์ €์™€ ์ตœ๋Œ€ํ•œ ๋น„์Šทํ•œ ์ฒดํ—˜์„ ํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋Šฅ๊ณผ ์ธํ„ฐํŽ˜์ด์Šค์  ์š”์†Œ๋ฅผ ๋˜‘๊ฐ™์ด ์ด์šฉํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

3๏ธโƒฃย Result

๋น„๋กœ๊ทธ์ธ ์ƒํƒœ์—์„œ๋Š” ํ…์ŠคํŠธ ์ž…๋ ฅ ๋ฐ•์Šค๋ฅผ ์„ ํƒ ๋ฐ•์Šค๋กœ ๋ณ€๊ฒฝํ•˜๊ณ , ์ œ๊ณต๋˜๋Š” ์„ ํƒ์ง€๋ฅผ ์ด์šฉํ•ด ์ œ์ถœํ•˜๊ฒŒ ๋˜๋ฉด ๋ชฉ์—… ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•ด ์‹ค์ œ ๊ธฐ๋Šฅ๊ณผ ๋™์ผํ•œ ๊ฒฝํ—˜์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ๋ฌธ๊ตฌ๋ฅผ ๋ฐ•์Šค ์œ„์— ๋‘์–ด ๋กœ๊ทธ์ธ ์‹œ ์ง์ ‘ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ์ ์„ ์•Œ๊ฒŒ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

without_login_selection_box

login_input

ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฑฐ์˜ ๋˜‘๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š๊ณ  ์ฒดํ—˜ํ•˜๋ฉด์„œ ํŠœํ† ๋ฆฌ์–ผ์˜ ๊ธฐ๋Šฅ๋„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


1๏ธโƒฃ Problem

- ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์‹œ ์—๋Ÿฌ ๋ฐœ์ƒ

์ปค๋ฐ‹์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ๋กœ ํŽ˜์ด์ง€ ๋ฆฌ๋กœ๋“œ ์‹œ ์ƒํƒœ๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด sessionStorage์— ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.

GitHub API๋ฅผ ํ†ตํ•ด ์ปค๋ฐ‹๋“ค์˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ(diff)์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ณผ์ •์—์„œ ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋งŽ์„ ๊ฒฝ์šฐ ์ €์žฅ๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ๋งค์šฐ ์ปค์กŒ๊ณ  ์ด์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ ์ €์žฅ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

sessionStorage๋Š” ๋Œ€์šฉ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜์ง€ ์•Š๊ณ  ์šฉ๋Ÿ‰์ด ์ดˆ๊ณผํ•˜์˜€๋‹ค๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

sessionStorage๋Š” ๋ธŒ๋ผ์šฐ์ €๋งˆ๋‹ค ์•ฝ 5MiB์˜ ์šฉ๋Ÿ‰ ์ œํ•œ์ด ์žˆ์—ˆ๊ณ  ์ด ์šฉ๋Ÿ‰ ์ด์ƒ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. GitHub API๋กœ ์‘๋‹ต๋ฐ›๋Š” ์ปค๋ฐ‹ diff ๋ฐ์ดํ„ฐ๋Š” ๋ณ€๊ฒฝ๋œ ์ฝ”๋“œ์–‘์— ๋”ฐ๋ผ ๋งค์šฐ ํฐ ํฌ๊ธฐ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด์˜ sessionStorage๋กœ๋Š” ๋ฐ์ดํ„ฐ ์ €์žฅ ์‹คํŒจ๋กœ ์ธํ•œ ์—๋Ÿฌ ๋ฐœ์ƒ ๊ฐ€๋Šฅ์„ฑ์ด ์ปค์กŒ์Šต๋‹ˆ๋‹ค.

2๏ธโƒฃย Action

์ด ๋ฌธ์ œ์˜ ํ•ด๊ฒฐ์„ ์œ„ํ•ด sessionStorage๋Œ€์‹  IndexedDB๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

  • IndexedDB ๋ธŒ๋ผ์šฐ์ € ๋‚ด์—์„œ ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ณ ์„ฑ๋Šฅ ๊ฒ€์ƒ‰์„ ์œ„ํ•ด ์ธ๋ฑ์‹ฑํ•˜๋Š” ์›น API์ž…๋‹ˆ๋‹ค.

idb-keyval ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํ•œ API(get(), set(), del() ๋“ฑ)์„ ์จ์„œ IndexedDB๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ zustand๋ฅผ ํ†ตํ•ด ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉด์„œ ๋ฐ์ดํ„ฐ๋ฅผ IndexedDB์— ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ „ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • zustand์˜ persist ๋ฏธ๋“ค์›จ์–ด(storage: createJSONStorage(() => IndexedDB))๋ฅผ ํ™œ์šฉํ•˜์—ฌ zustand ์ƒํƒœ๋ฅผ IndexedDB์— ์ €์žฅํ•˜๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • IndexedDB์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•ด ์ฃผ๋Š” ๋ถ€๋ถ„์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";
import { get, set, del } from "idb-keyval";
import { throwIndexedDBErrorMessage } from "../../../shared/error/throwCustomErrorMessage";

const IndexedDB = {
  getItem: async (name) => {
    try {
      const value = await get(name);
      return value || null;
    } catch (error) {
      throwIndexedDBErrorMessage(error);
    }
  },
  setItem: async (name, value) => {
    try {
      await set(name, value);
    } catch (error) {
      throwIndexedDBErrorMessage(error);
    }
  },
  removeItem: async (name) => {
    try {
      await del(name);
    } catch (error) {
      throwIndexedDBErrorMessage(error);
    }
  },
};

const initialState = {};

const useCommitStore = create(
  persist(
    (set) => ({
      ...initialState,
    }),
    {
      name: "commit-storage",
      storage: createJSONStorage(() => IndexedDB),
    }
  )
);

export default useCommitStore;

3๏ธโƒฃย Result

- sessionStorage์—์„œ ๋ฐœ์ƒํ•˜๋˜ ์ €์žฅ ์šฉ๋Ÿ‰ ์ดˆ๊ณผ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ

IndexedDB๋Š” 5MiB๋ณด๋‹ค ํ›จ์”ฌ ํฐ ์šฉ๋Ÿ‰(GB ๋‹จ์œ„)์„ ์ง€์›ํ•˜์—ฌ ์ปค๋ฐ‹ diff ๋ฐ์ดํ„ฐ์™€ ๊ฐ™์€ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ  ์›ํ™œํ•˜๊ฒŒ ์ €์žฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

zustand์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ์ปค๋ฐ‹ ๊ด€๋ จ ์ƒํƒœ๋ฅผ ์ง€์†์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๊ณ  idb-keyval ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ๋ณต์žก๋„๋ฅผ ์ค„์ด๊ณ  ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


virtual scroll ๋„์ž…ํ•œ PR ๋งํฌ

1๏ธโƒฃ Problem

- INP ์ง€์ˆ˜ ์ƒ์Šน ๋ฐ ํ™”๋ฉด ๋ฒ„๋ฒ…์ž„

์ด๋ฏธ ๊ฒ€์‚ฌ๊ฐ€ ๋๋‚œ ๋ชจ๋“  ์ปค๋ฐ‹๋“ค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋””ํ…Œ์ผ ๋ทฐ์—๋Š” ํ™”๋ฉด ์„ฑ๋Šฅ์— ๊ด€ํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ ์€ ์–‘์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์Šคํฌ๋กค ํ•  ๋•Œ๋Š” ํฐ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์ง€๋งŒ, ๋งŽ์€ ์–‘์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์„ (๋Œ€๋žต 1์ฒœ ๊ฐœ ์ด์ƒ์˜ ์ปค๋ฐ‹ ์ปดํฌ๋„ŒํŠธ) ๊ฐ€์ง„ ๋””ํ…Œ์ผ ํ™”๋ฉด์— ์ฒซ ์ง„์ž… ์‹œ ํ™”๋ฉด ๋ Œ๋”๋ง์˜ ์‹œ๊ฐ„์ด ์ง€์—ฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ํผํฌ๋จผ์Šค ํƒญ์„ ํ™•์ธํ•ด ๋ณด๋‹ˆ INP(Interaction to Next Paint) ์ง€์ˆ˜๊ฐ€ ๊ธ‰๊ฒฉํžˆ ์ƒ์Šนํ•˜๊ณ , ํ™”๋ฉด์ด ๋™์ ์œผ๋กœ ๋ณ€ํ•  ๋•Œ, ํŠนํžˆ๋‚˜ ๋ฒ„๋ฒ…์ด๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ์‚ฌ์šฉ์ž๋Š” ํ™”๋ฉด ์ „ํ™˜ ์‹œ์˜ ๋Š๋ฆฐ ๋ฐ˜์‘ ์†๋„์™€ ์ง€์—ฐ์œผ๋กœ ์ธํ•ด ๋‹ต๋‹ตํ•จ์„ ๋Š๋ผ๊ฒŒ ํ•˜๊ณ , ์ „์ฒด์ ์ธ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ €ํ•˜ํ•˜๊ณ , ์•ฑ ์„ฑ๋Šฅ์— ๋Œ€ํ•œ ๋ถ€์ •์ ์ธ ์˜ํ–ฅ์„ ๋ผ์น  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•œ ๋ฒˆ์— ๋ Œ๋”๋งํ•˜๋ ค๋Š” ๊ณผ์ •์—์„œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๊นŒ์ง€ ๋ชจ๋‘ DOM์— ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ์‹์ด ๋ณ‘๋ชฉํ˜„์ƒ์˜ ์ฃผ์š” ์›์ธ์ž„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กค์ด ํ•„์š”ํ•œ ๋””ํ…Œ์ผ ํ™”๋ฉด์—์„œ ์Šคํฌ๋กค ์‚ฌ์šฉ ์‹œ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋”์šฑ ์‹ฌ๊ฐํ•˜๊ฒŒ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ INP ์ง€์ˆ˜๋ฅผ ๊ฐœ์„ ํ•˜๊ณ , ์Šคํฌ๋กค ์‹œ ๋ถ€๋“œ๋Ÿฌ์šด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ๋ฐฉ๋ฒ•์„ ์ฐพ์•„์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

2๏ธโƒฃย Action

- Virtual Scroll ๋„์ž…

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ €ํฌ๋Š” Virtual Scroll ๊ธฐ์ˆ ์„ ๋„์ž…ํ•˜์˜€์Šต๋‹ˆ๋‹ค. Virtual Scroll ์€ ์‚ฌ์šฉ์ž๊ฐ€ ํ˜„์žฌ ํ™”๋ฉด์—์„œ ๋ณด๊ณ  ์žˆ๋Š” ๋ถ€๋ถ„์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋งŒ DOM์— ๋ Œ๋”๋งํ•˜๊ณ , ๋ณด์ด์ง€ ์•Š๋Š” ๋ถ€๋ถ„์€ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Œ์œผ๋กœ์จ ๋ธŒ๋ผ์šฐ์ €์˜ ๋ถˆํ•„์š”ํ•œ ์ž‘์—…์„ ์ค„์—ฌ์ฃผ๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ฐฉ์‹์„ ํ†ตํ•ด ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์‹œ ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ณ , ๋ Œ๋”๋ง ์†๋„๋ฅผ ํฌ๊ฒŒ ํ–ฅ์ƒํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋”๋ถˆ์–ด ๋ฌดํ•œ ์Šคํฌ๋กค์ฒ˜๋Ÿผ ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ํ†ตํ•œ ๋ฐ์ดํ„ฐ ์š”์ฒญ์„ ํ†ตํ•ด์„œ๋„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ, ์ด๋ฏธ ์ปค๋ฐ‹๋“ค์ด ๋ถ„์„๋œ ๋‹ค์Œ ๋””ํ…Œ์ผ ํ™”๋ฉด ํŽ˜์ด์ง€๋ฅผ ๋ณด๋Š” ๊ฒƒ์ด๊ธฐ์— ๋ฌดํ•œ ์Šคํฌ๋กค ๊ธฐ๋Šฅ์€ ํ•„์š” ์—†๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค. Virtual Scroll์„ ๋„์ž…ํ•˜๊ณ  ๋ Œ๋”๋ง ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ ๋ฐ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ์ ์šฉํ•˜์—ฌ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

3๏ธโƒฃย Result

์ดˆ๊ธฐ ๋ Œ๋”๋ง ์‹œ ๋ถˆํ•„์š”ํ•œ DOM ์ž‘์—…์„ ์ค„์ด๊ณ , ์Šคํฌ๋ฆฐ์— ๋ณด์—ฌ์ฃผ๋Š” ๋ถ€๋ถ„๋งŒ DOM์— ๊ทธ๋ฆฌ๋„๋ก ํ•˜๋ฉด์„œ INP ์ง€์ˆ˜๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ์จ, ๋‘ ๊ฐ€์ง€ ์ด์ ์„ ๋” ์–ป์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  1. ์Šคํฌ๋กค ์„ฑ๋Šฅ ํ–ฅ์ƒ: ๋Œ€๊ทœ๋ชจ ์ปค๋ฐ‹ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง„ ํ™”๋ฉด์—์„œ๋„ ์Šคํฌ๋กค์ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ž‘๋™ํ•˜๊ณ  ์ฆ‰๊ฐ์ ์ธ ๋ฐ˜์‘์„ฑ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  2. ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ๊ฐœ์„ : ํ™”๋ฉด ์ „ํ™˜ ์†๋„๊ฐ€ ๋นจ๋ผ์ง€๊ณ , ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์€ ํ™”๋ฉด์—์„œ๋„ ๋†’์€ ์„ฑ๋Šฅ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ, ๋Œ€๊ทœ๋ชจ ์ปค๋ฐ‹ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ๋•Œ์—๋„ ์•ˆ์ •์ ์ธ ์„ฑ๋Šฅ๊ณผ ์›ํ™œํ•œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๋‹ฌ์„ฑํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


์ข‹์€ ์ปค๋ฐ‹์ธ์ง€๋ฅผ ํŒ๋‹จํ•˜๊ธฐ ์œ„ํ•ด ์ปค๋ฐ‹์˜ ๋ฉ”์‹œ์ง€์™€ ์‹ค์ œ ๋ณ€๊ฒฝ ๋‚ด์šฉ์˜ ๋งฅ๋ฝ์ด ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌ๊ฐ€ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์— โ€œtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ˆ˜์ •โ€์ด๋ผ๊ณ  ์ ํ˜€์žˆ์œผ๋‚˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ์—” ํ•ด๋‹น ๋‚ด์šฉ๊ณผ ๊ด€๋ จ ์—†๋Š” ๋ถ€๋ถ„์ด ํฌํ•จ๋˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ปค๋ฐ‹์˜ ์งˆ์„ ๋‚ฎ์ถ˜๋‹ค๊ณ  ํŒ๋‹จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

1๏ธโƒฃ Problem

  1. ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ํ˜•์‹์˜ ๋น„์ผ๊ด€์„ฑ

    ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•œ ์ปจ๋ฒค์…˜์ด ์กด์žฌํ•˜์ง€๋งŒ, ํ”„๋กœ์ ํŠธ๋งˆ๋‹ค ๋‹ค๋ฅธ ๊ทœ์น™์„ ์ ์šฉํ•˜๊ฑฐ๋‚˜ ์ปจ๋ฒค์…˜์„ ๊ฐ•์ œํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•˜๊ณ  ๋™์ผํ•œ ์ปค๋ฐ‹ ํƒ€์ž…์ด์–ด๋„ ์ž‘์„ฑ์ž์˜ ์Šคํƒ€์ผ์— ๋”ฐ๋ผ ๋ฉ”์‹œ์ง€ ํ˜•์‹์ด ๋‹ฌ๋ž์Šต๋‹ˆ๋‹ค.

  2. ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์™€ ์ฝ”๋“œ ๋ณ€๊ฒฝ ๋‚ด์šฉ ๊ฐ„์˜ ๋ชจํ˜ธํ•œ ๊ธฐ์ค€

    ์˜ˆ๋ฅผ ๋“ค์–ด, ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ํƒ€์ž…์ด fix์ด๊ณ  CSS ๊ด€๋ จ UI ๋ณ€๊ฒฝ์ด ๋œ ๊ฒฝ์šฐ์—๋Š” fix์ธ์ง€ design์ธ์ง€ ํŒ๋‹จํ•˜๋Š” ๊ธฐ์ค€์ด ๋ชจํ˜ธํ–ˆ์Šต๋‹ˆ๋‹ค. refactor, feat ๋“ฑ์˜ ๊ฒฝ์šฐ์—๋„ ํ•ด๋‹น ์ปค๋ฐ‹์˜ ์ฝ”๋“œ ๋ณ€๊ฒฝ ๋‚ด์šฉ๋งŒ์„ ๋ณด๊ณ  ์ •ํ˜•ํ™”๋œ ๊ทœ์น™๋งŒ์œผ๋กœ ์ผ์น˜์„ฑ์„ ํŒ๋‹จํ•˜๊ธฐ์—๋Š” ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค.

  3. ๋™์ผํ•œ ํƒ€์ž…์ด์ง€๋งŒ ๋‹ค์–‘ํ•œ ํ•ด์„

    ๊ฐ™์€ ๋‹จ์–ด์ด์ง€๋งŒ ๋‹ค์–‘ํ•œ ์˜๋ฏธ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋นˆ๋ฒˆํ–ˆ์Šต๋‹ˆ๋‹ค. ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ํƒ€์ž…์ด style์ผ ๋•Œ ์ฝ”๋“œ ํฌ๋งท ๋ณ€๊ฒฝ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์ง€๋งŒ ๋””์ž์ธ์ ์ธ ์Šคํƒ€์ผ ๋ณ€๊ฒฝ์— ์‚ฌ์šฉ๋˜๊ธฐ๋„ ํ–ˆ์œผ๋ฉฐ chore์ธ ๊ฒฝ์šฐ์—๋„ ๋นŒ๋“œ์— ๊ด€๋ จ ์ˆ˜์ •๋งŒ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์˜๋ฏธ๋กœ ์“ฐ์ด๊ฑฐ๋‚˜ ์ž์ž˜ํ•œ ์ˆ˜์ •์˜ ์˜๋ฏธ๊นŒ์ง€ ํฌํ•จํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


2๏ธโƒฃย Action

1. ์ž‘์„ฑ์ž์˜ ์Šคํƒ€์ผ์— ๋”ฐ๋ฅธ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ํ˜•์‹ ๋ถ„์„

์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋ฅผ ์„ธ ๊ฐ€์ง€ ์ฃผ์š” ํ˜•์‹์œผ๋กœ ๋ถ„๋ฅ˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ํ˜•์‹์˜ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๊ฐ€ ์ž…๋ ฅ๋˜๋”๋ผ๋„ ์ง€์ •๋œ ํ˜•์‹์„ ๋”ฐ๋ฅผ ๊ฒฝ์šฐ ์ปค๋ฐ‹ ํ€„๋ฆฌํ‹ฐ๋ฅผ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ํ˜•์‹ ์ง€์ •

    ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„์ด ์—†์Šต๋‹ˆ๋‹ค. (Case-insensitive)

    1. ํ”„๋ฆฌ ํ”ฝ์Šค ์Šคํƒ€์ผ (Prefix Style)

      type(scope): subject

      ์˜ˆ์‹œ: feat(auth): ๋กœ๊ทธ์ธ API ์—ฐ๋™

    2. ์ผ๋ฐ˜ ํ…์ŠคํŠธ ์Šคํƒ€์ผ (Simple Text Style)

      type subject

      ์˜ˆ์‹œ: Add ๋กœ๊ทธ์ธ API ์—ฐ๋™

    3. ํ…œํ”Œ๋ฆฟ ๊ธฐ๋ฐ˜ ์Šคํƒ€์ผ (Template Based Style)

      [type] subject

      ์˜ˆ์‹œ: [ADD] ๋กœ๊ทธ์ธ API ์—ฐ๋™


2. ๋ชจํ˜ธํ•œ ์ปค๋ฐ‹ ํƒ€์ž…์˜ ๋ฌธ์ œํ•ด๊ฒฐ์„ ์œ„ํ•œ ํ•„ํ„ฐ๋ง

์ปค๋ฐ‹ ๋‚ด์šฉ[์นดํ…Œ๊ณ ๋ฆฌ] ํƒ€์ž… ์ถ”์ /๋ถ„์„ ์š”์ธ
1. ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ feat, make, implement
2. ํŒŒ์ผ์„ ์‚ญ์ œ remove, removed, removes, delete, deletes, deleted, erase, erases, erased, discard,
3. ๋ฌธ์„œ ์ž‘์—…๋งŒ docs, doc, documentation, readme ํŒŒ์ผ ํ™•์žฅ์ž๋ช… (.md, .mdx, .docs, ...)
4. ๋ฒ„๊ทธ ์ˆ˜์ • fix, fixed
5. ๋ฆฌํŒฉํ† ๋ง refactor
6. ์ฝ”๋“œ ํฌ๋ฉงํŒ… style, format, beautify, "reformatโ€
7. ๋””์ž์ธ ์Šคํƒ€์ผ๋ง๋งŒ design, css ํŒŒ์ผ ํ™•์žฅ์ž๋ช… (.css, .scss) / tailwind (โ€ฆ)
8. ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ test, tests, verify, unittest ํŒŒ์ผํ™•์žฅ์ž ๋ฐ ์ƒ๋Œ€๊ฒฝ๋กœ (.jest, ...)
9. ๋นŒ๋“œ ๋ฐ ์„ค์ • ํŒŒ์ผ ์ˆ˜์ •(ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ๋Šฅ๊ณผ ์ง์ ‘์ ์œผ๋กœ ์—ฐ๊ด€ x) chore

fix, feat, refactor์™€ ๊ฐ™์€ ์ปค๋ฐ‹ ํƒ€์ž…์€ ์ฝ”๋“œ ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์—ˆ์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์€ ๋ช…ํ™•ํ•œ ๊ธฐ์ค€์„ ๊ฐ€์ง€๊ณ  ํŒ๋‹จํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•˜์Šต๋‹ˆ๋‹ค. ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์˜ ๋‚ด์šฉ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ „์ฒด ์ฝ”๋“œ์˜ ๋‚ด์šฉ๋„ ํŒŒ์•…์ด ๋˜์–ด์•ผ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์™€ ์ฝ”๋“œ ๋ณ€๊ฒฝ ๋‚ด์šฉ์˜ ์ผ์น˜์„ฑ์„ ์•Œ ์ˆ˜ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ ์ปค๋ฐ‹์˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ(diff)์œผ๋กœ๋Š” ์ข‹์€ ์ปค๋ฐ‹์ธ์ง€ ์•Œ๊ธฐ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ถ„์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์€ ์ปค๋ฐ‹ ํƒ€์ž…์„ ํ•„ํ„ฐ๋งํ•˜์—ฌ ๋ชจํ˜ธ์„ฑ์„ ์ตœ์†Œํ™”ํ•˜๊ณ  ์ผ๊ด€๋œ ํ‰๊ฐ€๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ์—์„œ ์˜๋ฏธ๊ฐ€ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„๋˜๊ณ  ์‹ค์ œ ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ๊ณผ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ๊ฐ„์˜ ์ผ์น˜์„ฑ์„ ํŒ๋‹จํ•˜๋Š” ๊ธฐ์ค€์„ ์„ธ์šธ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ style, remove, docs, test 4๊ฐ€์ง€ ํƒ€์ž…์œผ๋กœ ๋ถ„์„ ๋Œ€์ƒ์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.


3. ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ํƒ€์ž…๊ณผ ์˜๋ฏธ์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ๊ธฐ์ค€ ์„ค์ •

๋™์ผํ•œ ํƒ€์ž…์ด์ง€๋งŒ ๋‹ค์–‘ํ•œ ํ•ด์„์ด ๋  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด 4๊ฐ€์ง€ ํƒ€์ž…์ด ์‹ค์ œ๋กœ ์–ด๋–ค ์˜๋ฏธ๋กœ ์“ฐ์ด๊ณ  ๊ทธ์— ๋”ฐ๋ฅธ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€ ๋ถ„์„ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํƒ€์ž…๋งˆ๋‹ค ๊ณตํ†ต๋œ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ฐพ๊ณ  ์ผ๋ฐ˜์ ์œผ๋กœ ์ž์ฃผ ์“ฐ์ด๋Š” ์˜๋ฏธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ช…ํ™•ํ•œ ๊ธฐ์ค€์„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, style ํƒ€์ž…์€ HTML ํƒœ๊ทธ์— ์–ธ์–ด ์†์„ฑ ์ถ”๊ฐ€, configํŒŒ์ผ ์ˆ˜์ •, ์“ฐ์ด์ง€ ์•Š์€ ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•œ ๊ฒฝ์šฐ ๋“ฑ ํŒ๋‹จ ๊ธฐ์ค€์„ ์„ธ์šฐ๊ธฐ ์–ด๋ ค์šด ์ผ€์ด์Šค๋ณด๋‹ค๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์“ฐ์ด๋Š” ์ฝ”๋“œ ํฌ๋งท์— ๊ด€ํ•œ ์ˆ˜์ •์— ๋Œ€ํ•ด ๋ถ„์„ํ•˜์—ฌ ๊ธฐ์ค€์„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.


3๏ธโƒฃย Result

ํ˜„์žฌ๋Š” ๋ณ€๊ฒฝ ๋‚ด์šฉ๊ณผ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋ฅผ ํŒ๋‹จํ•  ๋•Œ ๋ช…ํ™•ํ•œ ๋Œ€์‘์ด ๊ฐ€๋Šฅํ•œ ํƒ€์ž…๋งŒ์„ ์šฐ์„ ์ ์œผ๋กœ ์„ ํƒํ–ˆ์œผ๋ฉฐ ์ถ”ํ›„ ํ•„ํ„ฐ๋ง ๊ธฐ์ค€์„ ํ™•์žฅํ•˜์—ฌ feat, fix ๋“ฑ์„ ํฌํ•จํ•˜๊ธฐ ์œ„ํ•œ ์ถ”๊ฐ€ ๊ฐœ์„ ์„ ์ง„ํ–‰ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

- ์ด ํ”„๋กœ์ ํŠธ์—์„œ ํ™•์ธํ•˜๋Š” ์ปค๋ฐ‹ ํƒ€์ž…๊ณผ ๊ธฐ์ค€

  • remove
    • ํŒŒ์ผ ๋ฐ ํด๋”, ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•œ ์ปค๋ฐ‹
      • ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ์‚ญ์ œํ•œ ๋ถ€๋ถ„๋งŒ ํฌํ•จ๋๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    • ํ•ด๋‹นํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์‹œ
      • ํŒŒ์ผ ์‚ญ์ œ์™€ ์ฝ”๋“œ ์ˆ˜์ •์„ ๊ฐ™์ด ์ปค๋ฐ‹ํ–ˆ์„ ๊ฒฝ์šฐ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
      • ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ์ฝ”๋“œ์˜ ์ถ”๊ฐ€๋œ ๋ถ€๋ถ„์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • docs
    • ๋ฌธ์„œ ์ž‘์—…๋งŒ์„ ํ•œ ์ปค๋ฐ‹
      • ๋ฌธ์„œ์— ์‚ฌ์šฉ๋˜๋Š” ํŒŒ์ผ๋งŒ ํฌํ•จ๋๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
        • ์ด๋ฏธ์ง€ ํŒŒ์ผ -ย .img,ย .png,ย .jpeg,ย .svg,ย .ai
        • ๊ธฐํƒ€ ๋ฌธ์„œ ํŒŒ์ผ - .pdf ,.docs,ย .md,ย .mdx,ย .rst
    • ํ•ด๋‹นํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์‹œ
      • ๋ฌธ์„œ ํŒŒ์ผ๊ณผ ์†Œ์Šค ์ฝ”๋“œ ํŒŒ์ผ์˜ ์ˆ˜์ • ์‚ฌํ•ญ์„ ๊ฐ™์ด ์ปค๋ฐ‹ํ–ˆ์„ ๊ฒฝ์šฐ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • style
    • ์ฃผ๋กœ ์ฝ”๋“œ ํฌ๋งคํŒ…, ๋“ค์—ฌ์“ฐ๊ธฐ, ์ฝ”๋“œ ์ •๋ ฌ ๋“ฑ ์ฝ”๋“œ์˜ ๋™์ž‘์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š” ์ˆ˜์ •์„ ํ•œ ์ปค๋ฐ‹
      • ํŒŒ์ผ๋ช…์— style์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋‹จ์–ด ํ™•์ธ ("prettier", "eslint", "configโ€)
      • ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ํŠน์ˆ˜๋ฌธ์ž(, , ' , " , \n , ; ๋“ฑ)๋งŒ ์ˆ˜์ •๋๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
      • ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด console.log ์™€ ๊ด€๋ จ๋๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
      • ์š”์†Œ๋“ค์˜ ์œ„์น˜ ๋ณ€๊ฒฝ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
        • Tailwind CSS className์˜ ์†์„ฑ ์ˆœ์„œ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
        • ๊ฐ์ฒด ์†์„ฑ๋“ค์˜ ์ˆœ์„œ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    • ํ•ด๋‹นํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์‹œ
      • ๋ณ€์ˆ˜๋ช… ๋ณ€๊ฒฝ ๋“ฑ style ์ฒดํฌ ์‚ฌํ•ญ์— ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • test
    • ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•œ ์ปค๋ฐ‹
      • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ ํŒŒ์ผ๋งŒ ํฌํ•จ๋๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
        • test, tests, spec, mock
    • ํ•ด๋‹นํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์‹œ
      • test ๊ฒ€์ฆ ํ‚ค์›Œ๋“œ๊ฐ€ ํŒŒ์ผ๋ช…์— ์—†๊ฑฐ๋‚˜ ๋์— ์œ„์น˜ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
        • a/src/compiler-worker.ts
        • a/mock_feed_repository_impl.dart
      • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๊ด€๋ จ ํŒŒ์ผ์ด ์•„๋‹Œ ์„ค์ • ํŒŒ์ผ ๋“ฑ์˜ ์ˆ˜์ • ์‚ฌํ•ญ์„ ๊ฐ™์ด ์ปค๋ฐ‹ํ–ˆ์„ ๊ฒฝ์šฐ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

์ œ๋ชฉ ๋‚ด์šฉ
feat ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ปค๋ฐ‹
fix ๋ฒ„๊ทธ ์ˆ˜์ •์— ๋Œ€ํ•œ ์ปค๋ฐ‹
chore ๋นŒ๋“œ ์ˆ˜์ •์— ๋Œ€ํ•œ ์ปค๋ฐ‹
docs ๋ฌธ์„œ ์ˆ˜์ •์— ๋Œ€ํ•œ ์ปค๋ฐ‹
style ์ฝ”๋“œ ์Šคํƒ€์ผ ํ˜น์€ ํฌ๋งท ๋“ฑ์— ๊ด€ํ•œ ์ปค๋ฐ‹
refactor ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง์— ๋Œ€ํ•œ ์ปค๋ฐ‹
design CSS ๋””์ž์ธ์— ๋Œ€ํ•œ ์ปค๋ฐ‹
test ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€, ์‚ญ์ œ, ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์ปค๋ฐ‹
remove ๋ถˆํ•„์š”ํ•œ ํŒŒ์ผ์ด๋‚˜ ๋กœ์ง ์‚ญ์ œ์— ๊ด€ํ•œ ์ปค๋ฐ‹

์‹ ์ฒ ํ™˜ (๊นƒํ—ˆ๋ธŒ ์ฃผ์†Œ)

์„œ๋น„์Šค์˜ ๋ชฉ์ ์„ ๊ฐ€์ง„ ํ”„๋กœ์ ํŠธ์˜ ํ˜‘์—…์€ ์ด๋ฒˆ์ด ์ฒ˜์Œ์ž…๋‹ˆ๋‹ค. ๊ทธ์ „์—๋Š” ํŒ€์›๋“ค๊ณผ ๊ฐ™์ด ์ฝ”๋”ฉํ•˜๋ฉด์„œ ํ˜‘์—…์ด๋ž€ ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•ด ์ด๋ก ์ ์œผ๋กœ ์ ‘๊ทผํ–ˆ์ง€, ํฌ๊ฒŒ ์™€๋‹ฟ์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๋ช‡ ์ฃผ ๋™์•ˆ ์—ญํ• ์„ ๋‚˜๋ˆ„๊ณ , ๋งŽ์€ ์‹œ๊ฐ„์„ ํ•˜๋‚˜์˜ ๋ชฉํ‘œ์— ๋Œ€ํ•ด ์ง‘์ค‘ํ•˜๊ฒŒ ๋˜๋ฉด์„œ ํ˜‘์—…์— ๋Œ€ํ•ด ๋งŽ์ด ์ƒ๊ฐํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ €ํฌ ํ”„๋กœ์ ํŠธ ์ฃผ์ œ๋กœ ์ปค๋ฐ‹์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์กฐ์‚ฌํ•˜๋ฉด์„œ ๋‹จ์ˆœํžˆ ์ปค๋ฐ‹์ด ๊ธฐ๋ก์˜ ์ˆ˜๋‹จ์ด ์•„๋‹ˆ๋ผ ์ €ํฌ๊ฐ€ ํ•˜๋Š” ํ˜‘์—…์˜ โ€˜์–ธ์–ดโ€™๋ผ๋Š” ๋Š๋‚Œ์„ ๋งŽ์ด ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Š” ๋ง์ด ๊ณ ์™€์•ผ ์˜ค๋Š” ๋ง์ด ๊ณฑ๋‹ค๋Š” ์†๋‹ด์ฒ˜๋Ÿผ ์ปค๋ฐ‹๋„ ์ž˜ ์ž‘์„ฑํ•˜๊ณ  ์ „๋‹ฌํ•ด์•ผ ์†Œํ†ต์ด ์ž˜ ์ง„ํ–‰๋˜๋Š” ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ €์—๊ฒŒ ํ˜‘์—…์„ ์ž˜ํ–ˆ๋ƒ๊ณ  ๋ฌผ์œผ๋ฉด ์ €๋Š” ์ด๋ฒˆ์—๋Š” ์ปค๋ฐ‹์„ ์ž˜ ์“ฐ์ง€ ๋ชปํ•ด์„œ ์•„์‰ฝ๋‹ค๊ณ  ๋Œ€๋‹ตํ•  ๊ฒ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚˜์ค‘์—๋Š” ๋ฉ‹์ง„ ์ปค๋ฐ‹์„ ์“ฐ๊ณ  ๋‹น๋‹นํ•˜๊ฒŒ โ€œ๋„คโ€๋ผ๊ณ  ๋‹ตํ•  ๊ฒ๋‹ˆ๋‹ค.

ํ™์œ ์ง„ (๊นƒํ—ˆ๋ธŒ ์ฃผ์†Œ)

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์ปค๋ฐ‹์ด ๋‹จ์ˆœํ•œ ๊ธฐ๋ก์ด ์•„๋‹ˆ๋ผ, ํ”„๋กœ๋•ํŠธ์˜ ๊ธฐ๋ฐ˜์„ ์ด๋ฃจ๋Š” ์ค‘์š”ํ•œ ์š”์†Œ๋ผ๋Š” ์‚ฌ์‹ค์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์‹ค๊ฐํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ์ปค๋ฐ‹์˜ ์ค‘์š”์„ฑ์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋Š” ์ž์ฃผ ๋“ค์—ˆ์—ˆ์ง€๋งŒ, ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฒฝํ—˜ํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š” ๊นŠ์ด ๊ณต๊ฐํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ ๊ฒฝํ—˜์„ ํ†ตํ•ด, ์ข‹์€ ์ปค๋ฐ‹์ด ๋™๋ฃŒ ๊ฐœ๋ฐœ์ž์˜ ์ƒ์‚ฐ์„ฑ์„ ์–ผ๋งˆ๋‚˜ ํฌ๊ฒŒ ํ–ฅ์ƒํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ์ฒด๊ฐํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋˜, ํŒ€ ํ”„๋กœ์ ํŠธ๋กœ ํ•จ๊ป˜ ํ˜‘์—…ํ•˜๋ฉด์„œ ์„œ๋กœ์˜ ์ƒ๊ฐ์„ ๋งž์ถฐ๋‚˜๊ฐ€๋Š” ๊ณผ์ •์ด ์ฆ๊ฑฐ์› ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ์ €ํฌ ํ”„๋กœ์ ํŠธ๊ฐ€ style, remove, test, docs์˜ ์ปค๋ฐ‹ํƒ€์ž…๋งŒ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ดํ›„ ํ•˜๋‚˜์”ฉ ํ•˜๋‚˜์”ฉ ๋” ์ถ”๊ฐ€ํ•˜์—ฌ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์—ˆ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค!

๊น€์ˆ˜ํ•œ (๊นƒํ—ˆ๋ธŒ ์ฃผ์†Œ)

ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ์ดˆ๊ธฐ์—๋Š” ์ปค๋ฐ‹๋ฉ”์‹œ์ง€์— ๊ด€ํ•œ ๊ธฐ์ค€์„ ์ •ํ•˜๋Š” ๊ณผ์ •์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ์ž‘์„ฑ๋œ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์™€ ๋ณ€๊ฒฝ ๋‚ด์šฉ์˜ ์ผ์น˜์„ฑ์„ ๊ทœ๊ฒฉํ™”๋œ ๊ธฐ์ค€์„ ์ •ํ•ด ํŒ๋‹จํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ์šด ์ผ€์ด์Šค๊ฐ€ ๋‚˜์˜ฌ ๋•Œ๋งˆ๋‹ค ์–ด๋–ค ์‹์œผ๋กœ ๊ทœ๊ฒฉํ™”๋ฅผ ์‹œ์ผœ์•ผ ํ• ์ง€ ๊ณ ๋ฏผ์„ ๋งŽ์ด ํ–ˆ๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ API๋กœ ์‘๋‹ต๋ฐ›์€ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ด€๋ จํ•ด์„œ ๋‹ค์–‘ํ•œ ๋ฌธ์ œ๋“ค์„ ๋งˆ์ฃผํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ณผ์ •์—์„œ IndexedDB ํ™œ์šฉ๊ณผ ๋งŽ์€ ์–‘์˜ ๋ฐ์ดํ„ฐ๋ฅผ API ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ํšจ์œจ์ ์œผ๋กœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์‹ ๋“ฑ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๋ฅผ ๋ฐฐ์šฐ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ์„ ๋•Œ ํŒ€์›๋“ค๊ณผ ๊ฐ์ž์˜ ์˜๊ฒฌ์„ ๊ณต์œ ํ•˜๊ณ  ํšŒ์˜๋ฅผ ํ•˜๋‹ค ๋ณด๋ฉด ์ƒˆ๋กœ์šด ๋ฐฉํ–ฅ์˜ ํ•ด๊ฒฐ์ฑ…๋“ค์ด ๋‚˜์™€์„œ ๋‹ค์–‘ํ•œ ์‹œ๋„๋ฅผ ํ•ด๋ณผ ๊ธฐํšŒ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์งง์€ ๊ธฐ๊ฐ„์ด์—ˆ์ง€๋งŒ ์ƒˆ๋กœ์šด ๊ฐœ๋…๋“ค์„ ๋ฐฐ์šฐ๊ฒŒ ๋˜์—ˆ๊ณ  ํšจ์œจ์ ์ธ ์†Œํ†ต ๋ฐฉ์‹์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด ๋ณด๊ณ  ์ ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋˜ ์ข‹์€ ๊ฒฝํ—˜์ด์—ˆ์Šต๋‹ˆ๋‹ค.

About

๐Ÿ… ์ปค๋ฐ‹ ํ€„๋ฆฌํ‹ฐ๋ฅผ ์ ์ˆ˜๋กœ, ๋ฑƒ์ง€๋กœ ์ž๋ž‘ํ•˜์„ธ์š”! Show off your commit quality with scores and a badge!

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages