React | ๐Ÿ› ๋Ÿฌ์‰ฌ(LUSH) 1st Team Project ํšŒ๊ณ  ๋ฐ ๋งˆ๋ฌด๋ฆฌ

๋ฏธ์—ฐยท2021๋…„ 10์›” 17์ผ
2

LUSH-clone

๋ชฉ๋ก ๋ณด๊ธฐ
1/1

LUSH Clone Project

๋น„๊ฑด ํ”„๋ ˆ์‰ฌ ์ฝ”์Šค๋ฉ”ํ‹ฑ ๋ธŒ๋žœ๋“œ - ๋Ÿฌ์‰ฌ(LUSH) ์‚ฌ์ดํŠธ ํด๋ก .

HHYYY - ํ›ˆํ›ˆํ•œ ์—ฐ๋“คโ“

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

๊ฐœ๋ฐœ ๊ธฐ๊ฐ„ ๋ฐ ๊ฐœ๋ฐœ ์ธ์›

  • ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„ : 2021-10-04 ~ 2021-10-15 (๊ณตํœด์ผ ํฌํ•จ)
  • ๊ฐœ๋ฐœ ์ธ์›
    โœ”๏ธ Front-End 3๋ช… : ๋ฐ•๋ฏธ์—ฐ, ๋ฐ•์„ธ์—ฐ, ์œค์ˆ˜์—ฐ
    โœ”๏ธ Back-End 2๋ช… : ๊น€์ง€ํ›ˆ, ๋ฐ•์น˜ํ›ˆ

ํ”„๋กœ์ ํŠธ ๊ตฌํ˜„ ์˜์ƒ / Github

๐Ÿ“Ž ์œ ํŠœ๋ธŒ ์˜์ƒ ๋งํฌ
๐Ÿ“Ž Front-end Github
๐Ÿ“Ž Back-end Github

์ ์šฉ ๊ธฐ์ˆ  / ๋‚˜์˜ ๊ธฐ์ˆ  ๊ตฌํ˜„ ๋ชฉ๋ก

โœ”๏ธ Front-End : React, SASS, JSX
โœ”๏ธ Back-End : Django, Python, MySQL, jwt, bcypt, AWS RDS, AWS EC2
โœ”๏ธ Common : Git, Github, Slack, Trello, Postman

  • ๋ฐ”๋”” ๋ ˆ์ด์•„์›ƒ ๊ตฌํ˜„
  • ์ƒํ’ˆ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ๊ตฌํ˜„
    • ๋™์  ๋ผ์šฐํŒ…์„ ํ†ตํ•œ ์ƒํ’ˆ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ฐ ์ƒ์„ธ ํŽ˜์ด์ง€ ์—ฐ๊ฒฐ
    • ์ƒํ’ˆ ๋ชฉ๋ก์˜ ์„œ๋ธŒ ์นดํ…Œ๊ณ ๋ฆฌ์ธ Nav๋ฐ”๋ฅผ ๋ฐฑ์—”๋“œ API์™€ ๋™์  ๋ผ์šฐํŒ…์œผ๋กœ ์—ฐ๊ฒฐ
  • ์ƒํ’ˆ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ๊ตฌํ˜„
    • ๋ฐฑ์—”๋“œ API๋กœ๋ถ€ํ„ฐ ์ƒํ’ˆ ์ƒ์„ธ ์ •๋ณด๋ฅผ ๋ฐ›์•„์™€, ์ ์žฌ์ ์†Œ์— ์œ„์น˜
    • ์ƒํ’ˆ ์ˆ˜๋Ÿ‰ state์— ๋”ฐ๋ฅธ ๊ฐ€๊ฒฉ ๋ณ€ํ™”
    • ์ƒํ’ˆ ์ˆ˜๋Ÿ‰ state์™€ ์ƒํ’ˆ id๋ฅผ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐฑ์—”๋“œ API๋กœ ์ „์†ก
    • ๋˜‘๊ฐ™์€ UI ๋‹จ์œ„์ธ ์ƒํ’ˆ ๊ณตํ†ต ์•ˆ๋‚ด ์ •๋ณด๋ฅผ ์ƒ์ˆ˜ ๋ฐ์ดํ„ฐ๋กœ ๋งŒ๋“ค๊ณ , map ๋ฉ”์„œ๋“œ๋กœ ๋Œ๋ฆผ
    • ํฌํ†  ๋ฆฌ๋ทฐ ์ฐฝ ํด๋ฆญ์‹œ ํ•ด๋‹น ๋ฆฌ๋ทฐ ๋‚ด์šฉ(์ด๋ฆ„, ํ‰์ , ์ข‹์•„์š” ์ˆ˜, ๋‚ด์šฉ, ํฌํ†  ๋ฆฌ๋ทฐ ์‚ฌ์ง„) ๋‹ด๊ธด ํŒ์—… ON/OFF

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

์ผ์ • ๊ด€๋ฆฌ : Trello

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

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

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

๋ฉ”์‹ ์ € : Slack

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

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

์‹œ๋ จ๊ณผ ๊ณ ํ†ต.. โ“

ํ”„๋ก ํŠธ์™€ ๋ฐฑ์—”๋“œ์˜ ์†Œํ†ต์˜ ์ค‘์š”์„ฑ

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

์šฐ๋ฆฌ ํŒ€์› ๊ฐ„ ์†Œํ†ต์˜ ๊ณผ์ •์—์„œ๋Š” ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์ง€๋งŒ, ์†Œํ†ต์œผ๋กœ ์“ฐ์ด๋Š” ์‹œ๊ฐ„์ด ๋งŽ์•˜๋˜ ํ„ฐ๋ผ ์‹œ๊ฐ„ ๋ฐฐ๋ถ„์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์„ ๋งŽ์ด ํ–ˆ์—ˆ๋‹ค. ์ง€๊ธˆ ์ƒ๊ฐํ•ด ๋ณด๋ฉด ํ™œ๋ฐœํ•œ ์†Œํ†ต์— ๊ธด ์‹œ๊ฐ„์„ ํˆฌ์žํ•œ ๋•๋ถ„์— ์šฐ๋ฆฌ ํŒ€์€ ๋ฐฑ์—”๋“œ์™€ ํ”„๋ก ํŠธ์˜ API ์—ฐ๊ฒฐ์ด ๋น„๊ต์  ๋นจ๋ฆฌ, ์›ํ™œํ•˜๊ฒŒ ์—ฐ๊ฒฐ์ด ๋˜์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.

React SASS์˜ nesting์˜ ์ค‘์š”์„ฑ

๋ฆฌ์•กํŠธ๋Š” SPA์ด๋‹ค. ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ ์ฃผ๋Š” ํ˜•ํƒœ์ด๋‹ค. ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ํŒ€์›์ด ๋งŒ๋“  ํŽ˜์ด์ง€๊ฐ€ ๋‚˜์˜ ํŽ˜์ด์ง€์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ฐ˜๋Œ€๋กœ ๋‚ด๊ฐ€ ๋งŒ๋“  ํŽ˜์ด์ง€๊ฐ€ ๋‹ค๋ฅธ ํŒ€์›์ด ๋งŒ๋“  ํŽ˜์ด์ง€์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜๋„ ์žˆ๋‹ค.

ํ•˜์—ฌ, sass์—์„œ nesting์„ ํ™•์‹คํžˆ ํ•ด์•ผ ํ–ˆ๋Š”๋ฐ ๋‚˜ ํฌํ•จ ์šฐ๋ฆฌ ํ”„๋ก ํŠธ์—”๋“œ ํŒ€์›๋“ค ๋ชจ๋‘๊ฐ€ ๋ฏธ์ณ ์‹ ๊ฒฝ์“ฐ์ง€ ๋ชปํ–ˆ๋‹ค. ๋ ˆ์ด์•„์›ƒ์„ ์Šคํƒ€์ผ๋งํ•˜๋ฉด์„œ "๊ณผ์—ฐ ๋‚ด๊ฐ€ ์ž‘๋ช…ํ•œ class๋ช…์„ ๋‹ค๋ฅธ ํŒ€์›๋„ class๋ช…์œผ๋กœ ์“ธ๊นŒ?" ๋ผ๊ณ  ๊ณ ๋ฏผํ–ˆ์—ˆ๋Š”๋ฐ.. ์—ญ์‹œ๋‚˜ ์“ฐ๋”๋ผ. nesting์— ์‹ ๊ฒฝ์„ ์“ฐ์ง€ ์•Š์•˜๋‹ค๋Š” ์ ์— ๋Œ€ํ•ด ๋ผˆ์ €๋ฆฌ๊ฒŒ ๋ฐ˜์„ฑํ–ˆ๋‹ค.

์ด ๋ถ€๋ถ„์—์„œ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์€ ์ ์ด ์žˆ๋‹ค. ํฐ ํ‹€์ธ Tag์˜ class๋ช…์„ ํŒŒ์Šค์นผ ์ผ€์ด์Šค๋กœ ์ ์œผ๋‹ˆ๊นŒ, sass์—์„œ nesting์„ ํ•  ๋•Œ ํฐ ํ‹€์ธ Tag์˜ class๋ช…์„ ํฌ๊ฒŒ ๋ฌถ์–ด ์ค˜์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ๋ช…์‹ฌํ•˜๊ณ  ๋˜ ๋ช…์‹ฌํ•˜์ž. ์ด๋ฒˆ์— ์‹ค์ˆ˜๋ฅผ ํ•ด๋ดค์œผ๋‹ˆ ๋‹ค์Œ์—๋Š” ์ ˆ๋Œ€ ์‹ค์ˆ˜๋ฅผ ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

Github์— ๋Œ€ํ•œ ์•„ํ”ˆ ๊ธฐ์–ต..

๋‚ด๊ฐ€ Github์— ์•ฝํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋‚˜ ์Šค์Šค๋กœ๋„ ์•Œ๊ณ  ์žˆ์—ˆ๋˜ ํ„ฐ๋ผ, ํ”„๋กœ์ ํŠธ ์‹œ์ž‘ ์ „ ์ฃผ๋ง์— Github ๊ณต๋ถ€๋ฅผ ์—ด์‹ฌํžˆ ํ•˜๊ณ  ๊ฐ”์—ˆ๋‹ค. ์–ผํ• ๊ณต๋ถ€ํ–ˆ์—ˆ๋˜ ๊ฑด์ง€ ์—„์ฒญ๋‚œ ์‹ค์ˆ˜๋ฅผ ํ•˜๊ณ  ๋ง์•˜๋‹ค.

master -> A ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ ๋ฐ ์ด๋™ -> B ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ ๋ฐ ์ด๋™ -> C ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ ๋ฐ ์ด๋™ -> B ๋ธŒ๋žœ์น˜ ์ด๋™ ํ›„ ์ˆ˜์ • ์ž‘์—… -> A ๋ธŒ๋žœ์น˜ ์ด๋™ ํ›„ ์ˆ˜์ • ์ž‘์—… -> C ๋ธŒ๋žœ์น˜ ์ด๋™ ํ›„ ์ˆ˜์ • ์ž‘์—…

ํ•˜.. ์ง€๊ธˆ ์ƒ๊ฐํ•ด๋„ ์ ˆ๋Œ€ ํ•˜์ง€ ๋ง์•„์•ผ ํ•  ์‹ค์ˆ˜์˜€๋Š”๋ฐ, ์šฐ๋ฆฌ ํŒ€์›๋“คํ•œํ…Œ ๋„ˆ๋ฌด ๋ฏธ์•ˆํ•ด์„œ ์šธ์Œ์„ ์ฐธ์•˜๋˜ ๊ธฐ์–ต์ด ๋‚œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋ฒˆ์— ํ–ˆ๋˜ ์‹ค์ˆ˜ ๋•๋ถ„์— ๋ธŒ๋žœ์น˜๋ฅผ ํ™•์ธํ•˜๊ณ  ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์Šต๊ด€์ด ์ƒ๊ฒผ๊ณ , ์ „๋ฐ˜์ ์ธ Github ํ๋ฆ„์— ๋Œ€ํ•ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

  1. master์—์„œ branch ์ƒ์„ฑ ํ›„ ์ด๋™

    • $ git branch <๋ธŒ๋žœ์น˜ ์ด๋ฆ„> : ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ
    • $ git checkout -b <๋ธŒ๋žœ์น˜ ์ด๋ฆ„> : ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ ํ›„ ์ด๋™
  2. $ git add . or $ git add <ํŒŒ์ผ๋ช…>

  3. $ git commit -m "์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€"

  4. $ git push origin "๋ธŒ๋žœ์น˜"

  5. $ git checkout master

  6. $ git pull origin master

  7. ์ถฉ๋Œ์ด ์ƒ๊ฒผ๋‹ค๋ฉด, $ git checkout <1๋ฒˆ์˜ ๋ธŒ๋žœ์น˜> ๋กœ ์ด๋™ํ•˜์—ฌ $ git merge master ๋ช…๋ น์–ด ํ•œ ๋‹ค์Œ ์ฝ”๋“œ ๋ฎ์–ด์”Œ์šฐ๊ธฐ

  8. ์ถฉ๋Œ์ด ์—†๋‹ค๋ฉด, $ git checkout -b <์ƒˆ๋กœ์šด ๋ธŒ๋žœ์น˜> ๋กœ ์ด๋™ํ•˜์—ฌ $ git merge master ํ•œ ๋‹ค์Œ ์ƒˆ๋กœ์šด ์ž‘์—… ์‹œ์ž‘

๋˜ํ•œ Git์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํŒŒ์ผ๋ช… or ํด๋”๋ช…์˜ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ๋ชปํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ ์ž˜ํ•ด์„œ mergy๋ฅผ ํ•˜๋„๋ก ํ•˜์ž..

๋‹นํ™ฉ์Šค๋Ÿฌ์› ๋˜ ๋‚˜์˜ error..

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

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


๊ธฐ์–ตํ•˜๊ณ  ์‹ถ์€ ์ฝ”๋“œ ์—ํ”ผ์†Œ๋“œ TOP3

์ƒํ’ˆ ์ƒ์„ธ - ํฌํ† ๋ฆฌ๋ทฐ

ํŒ€์›๋ถ„๋“ค์˜ ์‹ค์ œ ์‚ฌ์ง„์œผ๋กœ ํฌํ† ๋ฆฌ๋ทฐ ์‚ฌ์ง„์„ ๊พธ๋ช„์—ˆ๋‹ค. ๋‚ด๊ฐ€ ๋จผ์ € ์‹ค์ œ ๋Ÿฌ์‰ฌ ํŒฉ์„ ํ•ด์„œ ์…€์นด ์‚ฌ์ง„์„ ๋ณด๋‚ด๊ณ , ํฌํ† ๋ฆฌ๋ทฐ๋กœ ๊พธ๋ฏธ์ž๊ณ  ์ œ์•ˆํ–ˆ์—ˆ๋Š”๋ฐ ๋‹ค๋“ค ์œ ์พŒํ•˜๊ณ  ํ”์พŒํžˆ ๋ฐ›์•„์ฃผ์…”์„œ ๋„ˆ๋ฌด ๊ฐ์‚ฌํ–ˆ๋‹ค. ์ด๋•Œ ์œก์ฒด์ ์œผ๋กœ ๋‹ค๋“ค ํ”ผ๊ณคํ–ˆ์„ ํ…๋ฐ, ์ด img ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค๊ณ  ๋งž์ถฐ ๋ณด๋Š” ๊ณผ์ •์—์„œ ์„œ๋กœ์˜ ์–ผ๊ตด ์‚ฌ์ง„์ด ๋ณด์ด๋‹ˆ ๋‹ค๋“ค ๋นต ํ„ฐ์ ธ์„œ ์›ƒ์—ˆ๋˜ ๊ธฐ์–ต์ด ๊นŠ๊ฒŒ ๋‚จ๋Š”๋‹ค.

componentDidMount() {
    fetch(`${API.PRODUCT_DETAIL}/${this.props.match.params.id}`)
      .then(res => res.json())
      .then(productInfo =>
        this.setState({
          productData: productInfo.product_info,
        })
      );
  }

// ๋ถ€๋ชจ(์ƒํ’ˆ ์ƒ์„ธ) ์ปดํฌ๋„ŒํŠธ์˜ ์ž์‹(ํฌํ†  ๋ฆฌ๋ทฐ) ์ปดํฌ๋„ŒํŠธ ํ˜ธ์ถœ
<span className="photoWrap">
{productData.photo_reviews?.map(imgData => (
  <PhotoReviewImg key={imgData.review_id}
                  imgSrc={imgData.image_url}
                  imgID={imgData.review_id} />
                ))}
</span>

[ํฌํ† ๋ฆฌ๋ทฐ ๋ชจ์•„๋ณด๊ธฐ]์˜ ์ž‘์€ img ์‚ฌ์ง„์€, ์ƒํ’ˆ ์ƒ์„ธ ๋ฐ์ดํ„ฐ API์— ์†ํ•ด์žˆ์œผ๋ฏ€๋กœ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ˜ธ์ถœํ–ˆ๋‹ค.

์ž‘์€ img ์‚ฌ์ง„์„ ํด๋ฆญํ•˜๋ฉด ๋œจ๋Š” ํ•ด๋‹น ๋ฆฌ๋ทฐ์˜ ๋‚ด์šฉ์€ ๋ฆฌ๋ทฐ API์— ์†ํ•ด์žˆ์œผ๋ฏ€๋กœ, ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ํŒ์—…์ฐฝ์ด ์ผœ์ง€๋Š” ์‹œ์ (ํŒ์—… class state์ธ imgClick๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š”) ๋ฉ”์„œ๋“œ ์•ˆ์— ๋™์‹œ์— API๋ฅผ ํ˜ธ์ถœํ•ด ์ฃผ์—ˆ๋‹ค.

// ์ž์‹(ํฌํ†  ๋ฆฌ๋ทฐ) ์ปดํฌ๋„ŒํŠธ
class PhotoReviewImg extends Component {
  constructor() {
    super();
    this.state = {
      closeBtnOFF: false,
      imgClick: false,
      photo: {},
    };
  }

  reviewImgClick = () => {
    const { imgClick } = this.state;
    const { imgID } = this.props;
    this.setState({
      imgClick: !imgClick,
    });
    fetch(`${API.BASE_URL}/reviews/${imgID}`)
      .then(res => res.json())
      .then(info =>
        this.setState({
          photo: info.review_info,
        })
      );
    // ์‚ฌ์ง„ IMG ํŒŒ์ผ ํด๋ฆญ์‹œ, ์‚ฌ์ง„ ํŒŒ์ผ์„ ๋ฐ›์•„์˜ค๋Š” API
  };

  AverageToStars = average => {
    const num = Math.floor(average);
    switch (num) {
      case 1:
        return 'โ˜…';
      case 2:
        return 'โ˜…โ˜…';
      case 3:
        return 'โ˜…โ˜…โ˜…';
      case 4:
        return 'โ˜…โ˜…โ˜…โ˜…';
      case 5:
        return 'โ˜…โ˜…โ˜…โ˜…โ˜…';
      default:
        return 'โ˜…โ˜…โ˜…โ˜…โ˜…';
    }
  };

  render() {
    const { imgSrc } = this.props;
    const { imgClick, photo } = this.state;

    return (
      <>
        <article className={imgClick ? 'imgPopUpON' : 'imgPopUpOFF'}>
          <div className="imgSection">
            <img className="photo" alt="photoReview_IMG" src={photo.image} />
          </div>
          <div className="bottomWrap">
            <div className="reviewUserInfo">
              <p className="userName">{photo.user_name}</p>
              <p className="userStar">{this.AverageToStars(photo.rating)}</p>
            </div>
            <div className="reviewContentWrap">
              <p className="reviewProductName">{photo.product_name}</p>
              <div className="reviewProductContent">{photo.content}</div>
              <p className="likeCount">
                <span className="countNumber">
                  ์ถ”์ฒœ ์ˆ˜ : {photo.like_count}
                </span>
              </p>
            </div>
          </div>
        </article>
        <img
          alt="photoReview_IMG"
          className="photoReviewIMG"
          src={imgSrc}
          onClick={this.reviewImgClick}
        />
      </>
    );
  }
}

export default PhotoReviewImg;

  };

์ฆ‰, ๋ฆฌ๋ทฐ ๊ฒŒ์‹œ๊ธ€์˜ id๋ฅผ ๊ธฐ์ค€์œผ๋กœ API๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ฆฌ๋ทฐ ๋ฐ์ดํ„ฐ๋ฅผ state๋กœ ๋ฐ›์•„ ํ•ด๋‹น ๋ฆฌ๋ทฐ์˜ ๋‚ด์šฉ์„ ๋ณด์—ฌ์ฃผ์—ˆ๋‹ค.

์ฒ˜์Œ์—๋Š” ๋ฆฌ๋ทฐ ๊ฒŒ์‹œ๊ธ€์˜ id๊ฐ€ ์•„๋‹Œ ๊ฐ๊ฐ์˜ index ๊ฐ’์œผ๋กœ ์ ‘๊ทผํ•ด์•ผ ํ•˜๋Š” ๊ตฌ์กฐ๋กœ ์งœ์—ฌ์ ธ ์žˆ์–ด ์–ด๋–ป๊ฒŒ ์ง์„ ์ด๋ค„ ์ ‘๊ทผํ•ด์•ผ ํ• ์ง€ ๊ฐ์ด ์žกํžˆ์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฐฑ์—”๋“œ ๊ตฌ์กฐ๊ฐ€ ์ž˜๋ชป ์งœ์—ฌ์ ธ ์žˆ๋‹ค๋Š” ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์€ ๋’ค, ๋ฐฑ์—”๋“œ ๋ถ„์ด ์ผ์‚ฌ์ฒœ๋ฆฌ๋กœ ๋ฐ”๊ฟ”์ฃผ์‹  ๋•๋ถ„์— ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

// before API ๊ตฌ์กฐ
{ ...
     ReviewID : [1, 2, 3, 4],
     Review_img : ["http://~/abc.png", "http://~/cde.png", "http://~/fgsdd.png"],
  ...
}
     
// after API ๊ตฌ์กฐ
{ ...
     photo_reviews: [{review_id: 7, review_img: "http://~/abc.png"},
                     {review_id: 6, review_img: "http://~/cde.png"}]
   ...
}

์ƒํ’ˆ ์ƒ์„ธ - ์žฅ๋ฐ”๊ตฌ๋‹ˆ API ์ „์†ก

์‚ฌ์šฉ์ž๊ฐ€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด, ํ•ด๋‹น ์ƒํ’ˆ์˜ id์™€ ์ƒํ’ˆ ์ˆ˜๋Ÿ‰์„ ์ €์žฅํ•˜์—ฌ ์žฅ๋ฐ”๊ตฌ๋‹ˆ API๋ฅผ POST๋กœ ๋ณด๋‚ด๋Š” ๊ณผ์ •์ด๋‹ค.

 goToCart = () => {
    const ID = this.state.productData.options[0].option_id;
   // ํ•ด๋‹น ์ƒํ’ˆ์˜ id๋ฅผ goToCart ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ ๋ณ€์ˆ˜๋กœ ์ €์žฅํ•œ๋‹ค.
    fetch(`${API.CART}`, {
      method: 'POST',
      // ํ•ด๋‹น ์ƒํ’ˆ์„ ๋ฐฑ์—”๋“œ ๋ฐ์ดํ„ฐ๊ตฌ์กฐ์— ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๊ณผ์ •์ด๋ฏ€๋กœ POST
      headers: {
        Authorization: localStorage.getItem('token'),
      },
      // ๋ธŒ๋ผ์šฐ์ € localStorage๋กœ๋ถ€ํ„ฐ token ๋ฐ›์•„์˜ค๊ธฐ - token์„ ๋ฐ›์€ ์‚ฌ๋žŒ = ๋กœ๊ทธ์ธํ•œ ํšŒ์›์ผ ๋•Œ๋งŒ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด์„ ์ˆ˜ ์žˆ์Œ.
      body: JSON.stringify({
        option_id: `${ID}`, 
        quantity: this.state.quantity,
      }),
      // ์ƒํ’ˆ id์™€ ํ˜„์žฌ ์ƒํ’ˆ ์ˆ˜๋Ÿ‰์„ ๋ฐฑ์—”๋“œ์— JSONํ™”ํ•˜์—ฌ ์ „์†กํ•จ.
    })
      .then(response => response.json())
      .then(response => {
        alert(
          '์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์„ฑ๊ณต์ ์œผ๋กœ ๋‹ด๊ฒจ์กŒ์Šต๋‹ˆ๋‹ค! ์ž ์‹œ ํ›„ ํŽ˜์ด์ง€๊ฐ€ ์ด๋™๋ฉ๋‹ˆ๋‹ค.'
        );
        this.props.history.push('/cart');
      });
  };

์ด๋•Œ fetch ๋ฉ”์„œ๋“œ์— ์ต์ˆ™ํ•˜์ง€ ์•Š์•˜๋˜ ํ„ฐ๋ผ ์†Œํ†ต ์ค‘ ์ดํ•ด๋ฅผ ๋ชปํ•œ ๋ถ€๋ถ„์ด ์žˆ์—ˆ๋‹ค. ๋ฐฑ์—”๋“œ๋ถ„์ด ๋ง์”€ํ•˜์‹œ๋Š” "ํ—ค๋”"์™€ ๋‚ด๊ฐ€ ์•Œ์•„๋“ฃ๋Š” "ํ—ค๋”"์˜ ์ •์˜๊ฐ€ ๋‹ฌ๋ž๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

ํ—ค๋”์— ํ† ํฐ๊ฐ’์„ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ฃผ์ œ๋Š” ๋˜‘๊ฐ™์•˜๋Š”๋ฐ, ๋ฐฑ์—”๋“œ๋ถ„์ด ๋ง์”€ํ•˜์‹œ๋Š” "ํ—ค๋”"๋Š” fetch ๋ฉ”์„œ๋“œ์˜ headers์˜€๊ณ , ๋‚ด๊ฐ€ ์•Œ์•„๋“ค์€ "ํ—ค๋”"๋Š” ์‚ฌ์ดํŠธ์˜ <head>์˜€๋‹ค. ๊ทธ๋ž˜์„œ "์‚ฌ์ดํŠธ์˜ <head>์— ํ† ํฐ๊ฐ’์„ ๋ฐ›์•„์„œ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค๊ณ ..?" ์— ๊ฝ‚ํ˜€์„œ ํ•œ๋™์•ˆ ์ดํ•ด๋ฅผ ๋ชปํ–ˆ๋˜ ๊ฒฝํ—˜์ด ์žˆ์—ˆ๋‹ค. ๋‚˜๋Š” ๋ผ›์†๊นŒ์ง€ ํ”„๋ก ํŠธ์—”๋“œ์ธ๊ฐ€ ๋ณด๋‹ค. ๐Ÿ˜†

path ํŒŒ๋ผ๋ฏธํ„ฐ์™€ componentDidUpdate ์ƒ๋ช…์ฃผ๊ธฐ

์ƒํ’ˆ ๋ชฉ๋ก ํŽ˜์ด์ง€์—์„œ ๋™์  ๋ผ์šฐํ„ฐ๋ฅผ ์ ์šฉํ•ด์•ผ ํ•˜๋Š” ๋‹จ๊ณ„์˜€๋‹ค. componentDidMount()๋Š” ํŽ˜์ด์ง€๊ฐ€ ๋กœ๋“œ๋  ๋•Œ ๋‹จ ํ•œ ๋ฒˆ ํ˜ธ์ถœ๋œ๋‹ค. ํ—ˆ๋‚˜, componentDidUpdate()๋Š” ํŽ˜์ด์ง€๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๋งˆ๋‹ค ๊ณ„์† ํ˜ธ์ถœ๋˜๋Š”๋ฐ.......

componentDidUpdate(prevProps) {
    if (prevProps.match.params.id !== this.props.match.params.id) {
      fetch(
        `${API.PRODUCT_DETAIL}?category=${this.props.match.params.id}&offset=0&limit=10`
      )
        .then(res => res.json())
        .then(listData =>
          this.setState({
            headerTitle: listData.category_info,
            productsData: listData.products_list,
          })
        );
    }
  }

์ฒ˜์Œ์—๋Š” if ์กฐ๊ฑด๋ฌธ์„ ๊ฑธ์–ด์ฃผ์ง€ ์•Š์•˜๋”๋‹ˆ, ๋ฐฑ์—”๋“œ๋ถ„์˜ ๊ฒ€์€ ํ™”๋ฉด์— ์—„์ฒญ๋‚œ log๊ฐ€ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ›์•„์ ธ์˜ค๋Š” ์—„์ฒญ๋‚œ ๊ฒฝํ—˜์„ ํ–ˆ์—ˆ๋‹ค.

๊ทธ ์ด์œ ๋Š” this.setState๋ฅผ ํ•  ๋•Œ๋งˆ๋‹ค ๋ฆฌ๋ Œ๋”๋ง์ด ๋˜๋Š”๋ฐ, componentDidUpdate ๋ฉ”์„œ๋“œ์—์„œ this.setState๋ฅผ ๊ณ„์† ํ˜ธ์ถœํ•˜๋‹ˆ componentDidUpdate๋„ ๊ณ„์† ํ˜ธ์ถœ๋˜๋Š” ์ƒํ™ฉ.. ์ฆ‰, ๋ฌดํ•œ๋ฃจํ”„์— ๋น ์ง„ ๊ฒƒ์ด๋‹ค.

์ƒํ’ˆ ๋ชฉ๋ก ํŽ˜์ด์ง€์˜ ์ด์ „ path ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ํ˜„์žฌ path ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋‹ค๋ฅด๋‹ค๋ฉด, ์ฆ‰ ์ด์ „ ํŽ˜์ด์ง€์™€ ํ˜„์žฌ ํŽ˜์ด์ง€๊ฐ€ ๋‹ค๋ฅด๋‹ค๋ฉด ํ˜„์žฌ ํŽ˜์ด์ง€์˜ ์ƒํ’ˆ ๋ชฉ๋ก API ๋ฐ์ดํ„ฐ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์งฐ๋‹ค.


๋งˆ์น˜๋ฉด์„œ ๐Ÿ™Œ

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

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

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

profile
FE Developer

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2021๋…„ 10์›” 31์ผ

ํŒ€์„ ์ž˜ ์ด๋Œ์–ด์ฃผ์‹  ๋ฏธ์—ฐ๋‹˜.!
๋•๋ถ„์— ์ฒซ ํ”„๋กœ์ ํŠธ๋ฅผ ์ž˜ ๋งˆ๋ฌด๋ฆฌํ•˜๊ณ  ๋„ˆ๋ฌด๋‚˜๋„ ์ข‹์€๊ธฐ์–ต์œผ๋กœ ๋‚จ๊ฒŒ ํ•ด ์ฃผ์…จ์–ด์š”!
๋ฐฑ์—”๋“œ์™€ ์†Œํ†ต๋„ ์ ๊ทน์ ์œผ๋กœ ํ•ด์ฃผ์‹œ๊ณ , ํ”„๋ก ํŠธ์—”๋“œ์—์„œ๋„ ์†Œํ†ต์„ ์ž˜ ํ•ด์ฃผ์…”์„œ ์„ฑ๊ณต์ ์œผ๋กœ ๋งˆ๋ฌด๋ฆฌ๊ฐ€ ๋๋˜ ๊ฒƒ ๊ฐ™์•„์š”.
ํ•ญ์ƒ ๊ณ ๋งˆ์› ๊ณ  ์•ž์œผ๋กœ๋„ ์›ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋กœ ์„ฑ๊ณตํ•˜์‹œ๊ธธ ์‘์›ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
๋ง‰๋‚ด์—”์ ค๋ฏธ์—ฐ์“ฐ~ ํ˜‘์—… ์ž˜ํ•˜๊ตฌ ์˜ค์„ธ์š”๐ŸŽ–๐ŸŽ–๐ŸŽ–๐Ÿฅ‡๐Ÿ…

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ