[๐Ÿค–] ๋ชจ๋…ธ๋ ˆํฌ ์•„ํ‚คํ…์ฒ˜: ํšจ์œจ์ ์ธ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ ์„ค๊ณ„๋ฅผ ์œ„ํ•œ ์‹ค์ „ ๊ฐ€์ด๋“œ

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

24๋ถ„
๋‹จ์–ด: 1,908๊ฐœ
๊ฒŒ์‹œ๊ธ€ ์ธ๋„ค์ผ
์ •๋ณด

๐Ÿค– ์ด ํฌ์ŠคํŒ…์€ Gemini 2.5 Flash AI๊ฐ€ ์ž‘์„ฑํ–ˆ์–ด์š”.
๋‚ด์šฉ์˜ ์ •ํ™•์„ฑ์„ ์œ„ํ•ด ๊ฒ€ํ† ๋ฅผ ๊ฑฐ์ณค์ง€๋งŒ, ์‹ค๋ฌด ์ ์šฉ ์ „ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ํ•จ๊ป˜ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

์œ ์šฉํ•œ ํŒ

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

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

๐Ÿค” ์™œ ๋ชจ๋…ธ๋ ˆํฌ์ธ๊ฐ€์š”?

0๏ธโƒฃ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์˜ ๋„์ „ ๊ณผ์ œ

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

1๏ธโƒฃ ๋ฉ€ํ‹ฐ๋ ˆํฌ์˜ ํ•œ๊ณ„์ 

  • ๋ณต์žกํ•œ ์˜์กด์„ฑ ๊ด€๋ฆฌ: ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ๊ฐ€ ๊ณตํ†ต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ๊ฐ ๋ ˆํฌ๋งˆ๋‹ค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•ด์•ผ ํ•ด์š”. ์ด๋กœ ์ธํ•ด ๋ฒ„์ „ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ๋‚˜ ์˜์กด์„ฑ ์ง€์˜ฅ์— ๋น ์งˆ ์œ„ํ—˜์ด ์ปค์ ธ์š”.
  • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์˜ ์–ด๋ ค์›€: ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” UI ์ปดํฌ๋„ŒํŠธ๋‚˜ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ„๋„์˜ ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ณ , ์ด๋ฅผ ๊ฐ ๋ ˆํฌ์— ๋ฐฐํฌํ•œ ํ›„ ์„ค์น˜ํ•ด์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์ด ์žˆ์–ด์š”. ์ด ๊ณผ์ •์ด ๋ณต์žกํ•˜๊ณ  ์‹œ๊ฐ„์ด ๋งŽ์ด ์†Œ์š”๋ผ์š”.
  • ์ผ๊ด€์„ฑ ์—†๋Š” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ: ๊ฐ ๋ ˆํฌ๋งˆ๋‹ค ESLint, Prettier, TypeScript ์„ค์ • ๋“ฑ์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์–ด์„œ, ์ฝ”๋“œ ์Šคํƒ€์ผ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์–ด๋ ต๊ณ  ๊ฐœ๋ฐœ์ž๋“ค์˜ ํ˜ผ๋ž€์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ๋น„ํšจ์œจ์ ์ธ CI/CD: ์ž‘์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด๋ผ๋„ ์—ฌ๋Ÿฌ ๋ ˆํฌ์— ๊ฑธ์ณ ์žˆ๋‹ค๋ฉด, ๊ฐ๊ฐ์˜ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์„ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•ด์„œ ๋นŒ๋“œ ๋ฐ ๋ฐฐํฌ ์‹œ๊ฐ„์ด ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ์–ด์š”.

๋ชจ๋…ธ๋ ˆํฌ๋Š” ์ด๋Ÿฐ ๋ฉ€ํ‹ฐ๋ ˆํฌ์˜ ํ•œ๊ณ„์ ๋“ค์„ ๊ทน๋ณตํ•˜๊ณ , ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ๋ฅผ ๋”์šฑ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ๋Œ€์•ˆ์œผ๋กœ ๋– ์˜ค๋ฅด๊ณ  ์žˆ์–ด์š”.

๐Ÿš€ ๋ชจ๋…ธ๋ ˆํฌ์˜ ์žฅ์ ๊ณผ ๋‹จ์ 

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

0๏ธโƒฃ ๋ชจ๋…ธ๋ ˆํฌ์˜ ์žฅ์  ๐Ÿ‘

  • ์ฝ”๋“œ ๊ณต์œ  ๋ฐ ์žฌ์‚ฌ์šฉ์„ฑ ๊ทน๋Œ€ํ™”: ๊ณตํ†ต UI ์ปดํฌ๋„ŒํŠธ, ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜, ํƒ€์ž… ์ •์˜ ๋“ฑ์„ ์‰ฝ๊ฒŒ ๊ณต์œ ํ•˜๊ณ  ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋ณ„๋„์˜ ๋ฐฐํฌ ๊ณผ์ • ์—†์ด ๋‚ด๋ถ€ ํŒจํ‚ค์ง€ ์˜์กด์„ฑ์œผ๋กœ ๋ฐ”๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด์„œ ๊ฐœ๋ฐœ ์†๋„๊ฐ€ ๋นจ๋ผ์ ธ์š”.
  • ๋‹จ์ผํ™”๋œ ์˜์กด์„ฑ ๋ฐ ๋ฒ„์ „ ๊ด€๋ฆฌ: ๋ชจ๋“  ํ”„๋กœ์ ํŠธ๊ฐ€ ํ•˜๋‚˜์˜ package.json ๋˜๋Š” ์›Œํฌ์ŠคํŽ˜์ด์Šค ์„ค์ •์„ ๊ณต์œ ํ•˜์—ฌ ์˜์กด์„ฑ ๋ฒ„์ „์„ ์ผ๊ด€๋˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”. ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์— ๊ฑธ์ณ ํ•œ ๋ฒˆ์— ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ์ฃ .
  • ๊ฐ„๊ฒฐํ•œ CI/CD ํŒŒ์ดํ”„๋ผ์ธ: ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ์ด ํฌํ•จ๋œ ํŒจํ‚ค์ง€๋งŒ ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌํ•˜๋„๋ก ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” CI/CD ์‹œ๊ฐ„์„ ํฌ๊ฒŒ ๋‹จ์ถ•์‹œํ‚ค๊ณ  ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๋ฅผ ์ค„์—ฌ์ค˜์š”.
  • ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ • ๊ฐ„์†Œํ™”: ESLint, Prettier, TypeScript ๋“ฑ ๊ณตํ†ต ๊ฐœ๋ฐœ ๋„๊ตฌ ์„ค์ •์„ ๋ฃจํŠธ ๋ ˆ๋ฒจ์—์„œ ํ•œ ๋ฒˆ๋งŒ ์„ค์ •ํ•˜๋ฉด ๋ชจ๋“  ์„œ๋ธŒ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. ๊ฐœ๋ฐœ์ž ์˜จ๋ณด๋”ฉ์ด ํ›จ์”ฌ ์‰ฌ์›Œ์ง„๋‹ต๋‹ˆ๋‹ค.
  • ์ „์ฒด ํ”„๋กœ์ ํŠธ ๊ฐ€์‹œ์„ฑ ์ฆ๋Œ€: ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ํ•œ๊ณณ์— ๋ชจ์—ฌ ์žˆ์–ด์„œ, ๋‹ค๋ฅธ ํŒ€์˜ ํ”„๋กœ์ ํŠธ๋‚˜ ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฝ”๋“œ๋ฅผ ์‰ฝ๊ฒŒ ํƒ์ƒ‰ํ•˜๊ณ  ์ดํ•ดํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” ํŒ€ ๊ฐ„์˜ ํ˜‘์—…๊ณผ ์ง€์‹ ๊ณต์œ ๋ฅผ ์ด‰์ง„ํ•ด์š”.
  • ๋ฆฌํŒฉํ† ๋ง ์šฉ์ด์„ฑ: ๊ณตํ†ต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ, ์˜ํ–ฅ์„ ๋ฐ›๋Š” ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์—์„œ ์ฆ‰์‹œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ™•์ธํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋Œ€๊ทœ๋ชจ ๋ฆฌํŒฉํ† ๋ง์ด ํ›จ์”ฌ ์•ˆ์ „ํ•˜๊ณ  ํšจ์œจ์ ์ด์—์š”.

1๏ธโƒฃ ๋ชจ๋…ธ๋ ˆํฌ์˜ ๋‹จ์  ๐Ÿ‘Ž

  • ์ดˆ๊ธฐ ์„ค์ • ๋ณต์žก์„ฑ: ๋ชจ๋…ธ๋ ˆํฌ ํˆด(Lerna, Nx, Turborepo, Yarn/pnpm Workspaces ๋“ฑ)์˜ ํ•™์Šต๊ณผ ์„ค์ •์— ์ดˆ๊ธฐ ๋น„์šฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ ์ ˆํ•œ ํˆด์„ ์„ ํƒํ•˜๊ณ  ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ํ•„์š”ํ•˜์ฃ .
  • ๋นŒ๋“œ ์‹œ๊ฐ„ ์ฆ๊ฐ€ ๊ฐ€๋Šฅ์„ฑ: ๋งŒ์•ฝ ๋ชจ๋…ธ๋ ˆํฌ ํˆด์˜ ์ตœ์ ํ™” ๊ธฐ๋Šฅ์„ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜์ง€ ๋ชปํ•˜๋ฉด, ๋ชจ๋“  ํ”„๋กœ์ ํŠธ๋ฅผ ๋งค๋ฒˆ ๋นŒ๋“œํ•˜๊ฒŒ ๋˜์–ด ์ „์ฒด ๋นŒ๋“œ ์‹œ๊ฐ„์ด ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ์–ด์š”.
  • ์ฝ”๋“œ๋ฒ ์ด์Šค ๊ทœ๋ชจ ์ฆ๊ฐ€: ๋‹จ์ผ ์ €์žฅ์†Œ์— ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ๋ชจ์—ฌ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ €์žฅ์†Œ์˜ ํฌ๊ธฐ๊ฐ€ ๋งค์šฐ ์ปค์งˆ ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” Git ์ž‘์—…(clone, fetch)์ด๋‚˜ IDE ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜๋„ ์žˆ์–ด์š”.
  • ์‹ฌ๋ฆฌ์  ๋ถ€๋‹ด: ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ํ•œ๊ณณ์— ์žˆ๋‹ค๋Š” ์ ์ด ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ์‹ฌ๋ฆฌ์ ์ธ ๋ถ€๋‹ด๊ฐ์ด๋‚˜ ํ˜ผ๋ž€์„ ์ค„ ์ˆ˜๋„ ์žˆ์–ด์š”. ์ฝ”๋“œ๋ฒ ์ด์Šค๊ฐ€ ๋„ˆ๋ฌด ๋ฐฉ๋Œ€ํ•˜๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์ฃ .
  • ํŠน์ • ํˆด์— ๋Œ€ํ•œ ์˜์กด์„ฑ: ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ „์šฉ ํˆด์— ๋Œ€ํ•œ ์˜์กด์„ฑ์ด ์ƒ๊ฒจ์š”. ํˆด์ด ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ๊ณผ ์ œ์•ฝ ์‚ฌํ•ญ์„ ์ดํ•ดํ•˜๊ณ  ๋”ฐ๋ผ์•ผ ํ•˜์ฃ .

๋ชจ๋…ธ๋ ˆํฌ๋Š” ๋งŒ๋Šฅ ํ•ด๊ฒฐ์ฑ…์ด ์•„๋‹ˆ์—์š”. ํ”„๋กœ์ ํŠธ์˜ ๊ทœ๋ชจ, ํŒ€์˜ ์—ญ๋Ÿ‰, ๊ธฐ์ˆ  ์Šคํƒ ๋“ฑ์„ ๊ณ ๋ คํ•˜์—ฌ ์‹ ์ค‘ํ•˜๊ฒŒ ๋„์ž… ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•ด์•ผ ํ•ด์š”.

โš™๏ธ ๋ชจ๋…ธ๋ ˆํฌ, ์–ด๋–ป๊ฒŒ ์„ค๊ณ„ํ•ด์•ผ ํ• ๊นŒ์š”?

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

0๏ธโƒฃ ํ•ต์‹ฌ ์•„์ด๋””์–ด: ํŒจํ‚ค์ง€(Packages) ๋ถ„๋ฆฌ ๐Ÿ“ฆ

๋ชจ๋…ธ๋ ˆํฌ์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์›์น™์€ ๊ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(์˜ˆ: ์›น ์•ฑ, ๊ด€๋ฆฌ์ž ์•ฑ, ๋ฐฑ์—”๋“œ API)๊ณผ ๊ณต์œ  ๊ฐ€๋Šฅํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(์˜ˆ: UI ์ปดํฌ๋„ŒํŠธ, ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜, ํƒ€์ž… ์ •์˜)๋ฅผ ๋…๋ฆฝ์ ์ธ ํŒจํ‚ค์ง€๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ๊ฐ ํŒจํ‚ค์ง€๋Š” ์ž์ฒด์ ์ธ package.json ํŒŒ์ผ์„ ๊ฐ€์ง€๋ฉฐ, ์„œ๋กœ ์˜์กด์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์–ด์š”.

1๏ธโƒฃ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ ์„ค๊ณ„ ๐Ÿ“

์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋…ธ๋ ˆํฌ๋Š” apps/์™€ packages/๋ผ๋Š” ๋‘ ๊ฐœ์˜ ์ตœ์ƒ์œ„ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„์š”.

  • apps/: ์‹ค์ œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์„œ๋น„์Šค๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋“ค์„ ๋ชจ์•„๋‘๋Š” ๊ณณ์ด์—์š”. Next.js ์›น ์•ฑ, React ๊ด€๋ฆฌ์ž ์•ฑ, Express/NestJS ๊ธฐ๋ฐ˜์˜ ๋ฐฑ์—”๋“œ API ๋“ฑ์ด ์—ฌ๊ธฐ์— ํฌํ•จ๋  ์ˆ˜ ์žˆ์–ด์š”.
  • packages/: ์—ฌ๋Ÿฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ณต์œ ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ๋ชจ์•„๋‘๋Š” ๊ณณ์ด์—์š”. UI ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ๊ณตํ†ต ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜, ํƒ€์ž… ์ •์˜, ์„ค์ • ํŒŒ์ผ(ESLint, Prettier ๋“ฑ) ๋“ฑ์ด ์—ฌ๊ธฐ์— ํ•ด๋‹น๋ผ์š”.
root โ”œโ”€โ”€ apps โ”‚ โ”œโ”€โ”€ web # Next.js/React ๊ธฐ๋ฐ˜์˜ ์‚ฌ์šฉ์ž ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ โ”‚ โ”œโ”€โ”€ admin # Next.js/React ๊ธฐ๋ฐ˜์˜ ๊ด€๋ฆฌ์ž ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ โ”‚ โ””โ”€โ”€ api # Express/NestJS ๊ธฐ๋ฐ˜์˜ ๋ฐฑ์—”๋“œ API โ”œโ”€โ”€ packages โ”‚ โ”œโ”€โ”€ ui # ๊ณตํ†ต UI ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ โ”‚ โ”œโ”€โ”€ utils # ๊ณตํ†ต ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜ ๋ชจ์Œ โ”‚ โ”œโ”€โ”€ types # ๊ณตํ†ต TypeScript ํƒ€์ž… ์ •์˜ โ”‚ โ””โ”€โ”€ config # ESLint, Prettier, TypeScript ๋“ฑ ๊ณตํ†ต ์„ค์ • ํŒŒ์ผ โ”œโ”€โ”€ .gitignore โ”œโ”€โ”€ package.json # ๋ชจ๋…ธ๋ ˆํฌ ์›Œํฌ์ŠคํŽ˜์ด์Šค ์„ค์ • ๋ฐ ๊ณตํ†ต ์Šคํฌ๋ฆฝํŠธ โ””โ”€โ”€ pnpm-workspace.yaml # pnpm ์›Œํฌ์ŠคํŽ˜์ด์Šค ์„ค์ • ํŒŒ์ผ (๋˜๋Š” lerna.json, .yarnrc.yml)

2๏ธโƒฃ ์ ์ ˆํ•œ ๋ชจ๋…ธ๋ ˆํฌ ํˆด ์„ ํƒ ๐Ÿ› ๏ธ

๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ ค๋ฉด ์›Œํฌ์ŠคํŽ˜์ด์Šค ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๋‚˜ ์ „์šฉ ํˆด์ด ํ•„์š”ํ•ด์š”. ๋Œ€ํ‘œ์ ์ธ ํˆด๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์•„์š”.

  • Yarn Workspaces / pnpm Workspaces: ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์ž์ฒด์—์„œ ์ œ๊ณตํ•˜๋Š” ์›Œํฌ์ŠคํŽ˜์ด์Šค ๊ธฐ๋Šฅ์ด์—์š”. ๋น„๊ต์  ๊ฐ€๋ณ๊ณ  ์„ค์ •์ด ๊ฐ„๋‹จํ•˜์—ฌ ์‹œ์ž‘ํ•˜๊ธฐ ์ข‹์•„์š”. ํŠนํžˆ pnpm์€ ํ•˜๋“œ ๋งํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋””์Šคํฌ ๊ณต๊ฐ„์„ ์ ˆ์•ฝํ•˜๊ณ  ์„ค์น˜ ์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์–ด์š”.
  • Lerna: ์›Œํฌ์ŠคํŽ˜์ด์Šค ๊ด€๋ฆฌ, ๋ฒ„์ „ ๊ด€๋ฆฌ, ํŒจํ‚ค์ง€ ๋ฐฐํฌ ๋“ฑ์„ ๋„์™€์ฃผ๋Š” ํˆด์ด์—์š”. Yarn/pnpm Workspaces์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์‹œ๋„ˆ์ง€๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ์–ด์š”.
  • Nx (Nrwl Extensible Dev Tools): ๋นŒ๋“œ ์‹œ์Šคํ…œ, ์ฝ”๋“œ ์ƒ์„ฑ๊ธฐ, ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„ ๋ถ„์„ ๋“ฑ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํ’€์Šคํƒ ๋ชจ๋…ธ๋ ˆํฌ ์†”๋ฃจ์…˜์ด์—์š”. ๋Œ€๊ทœ๋ชจ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ํ™˜๊ฒฝ์— ์ ํ•ฉํ•ด์š”.
  • Turborepo: Nx์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๊ณ ์„ฑ๋Šฅ ๋นŒ๋“œ ์‹œ์Šคํ…œ๊ณผ ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์š”. ์ฆ๋ถ„ ๋นŒ๋“œ(incremental build)์™€ ์›๊ฒฉ ์บ์‹ฑ(remote caching)์„ ํ†ตํ•ด ๋นŒ๋“œ ์‹œ๊ฐ„์„ ํš๊ธฐ์ ์œผ๋กœ ๋‹จ์ถ•์‹œ์ผœ์ค˜์š”.

๊ฐ ํˆด๋งˆ๋‹ค ์žฅ๋‹จ์ ์ด ๋ช…ํ™•ํ•˜๋ฏ€๋กœ, ํ”„๋กœ์ ํŠธ์˜ ๊ทœ๋ชจ, ํŒ€์˜ ์ˆ™๋ จ๋„, ํ•„์š”ํ•œ ๊ธฐ๋Šฅ ๋“ฑ์„ ๊ณ ๋ คํ•˜์—ฌ ์‹ ์ค‘ํ•˜๊ฒŒ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ด์š”. ์ด ๊ธ€์—์„œ๋Š” ์„ค์ •์ด ๋น„๊ต์  ๊ฐ„๋‹จํ•˜๊ณ  ํšจ์œจ์ ์ธ pnpm Workspaces๋ฅผ ์˜ˆ์‹œ๋กœ ๋ณด์—ฌ๋“œ๋ฆด๊ฒŒ์š”.

๐Ÿ› ๏ธ ์‹ค์ „ ๋ชจ๋…ธ๋ ˆํฌ ๊ตฌ์ถ• ์˜ˆ์‹œ

์ด์ œ pnpm Workspaces๋ฅผ ํ™œ์šฉํ•ด์„œ ๊ฐ„๋‹จํ•œ ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ๊ตฌ์ถ•ํ•ด๋ณด๊ณ , ๊ณต์œ  UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ด์š”. Next.js ์•ฑ๊ณผ React UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์˜ˆ์‹œ๋กœ ๋“ค์–ด๋ณผ๊ฒŒ์š”.

0๏ธโƒฃ pnpm Workspaces๋ฅผ ์ด์šฉํ•œ ๊ธฐ๋ณธ ์„ค์ •

๋จผ์ € ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  pnpm init์œผ๋กœ package.json์„ ๋งŒ๋“  ํ›„, pnpm-workspace.yaml ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ฅผ ์„ค์ •ํ•ด ์ค˜์•ผ ํ•ด์š”.

# ๋ชจ๋…ธ๋ ˆํฌ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ mkdir my-monorepo-example cd my-monorepo-example # package.json ์ดˆ๊ธฐํ™” pnpm init # apps/ ์™€ packages/ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ mkdir apps packages # apps/web (Next.js ์•ฑ) ์ƒ์„ฑ cd apps pnpm create next-app web --ts --eslint --tailwind --app --src-dir --use-pnpm --no-import-alias cd .. # packages/ui (React ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ) ์ƒ์„ฑ cd packages mkdir ui cd ui pnpm init # (๋‚˜์ค‘์— React, TypeScript ์˜์กด์„ฑ ์ถ”๊ฐ€ ์˜ˆ์ •) cd ../.. # pnpm-workspace.yaml ํŒŒ์ผ ์ƒ์„ฑ touch pnpm-workspace.yaml

1๏ธโƒฃ pnpm-workspace.yaml ์„ค์ • ๐Ÿ“

pnpm-workspace.yaml ํŒŒ์ผ์— ์›Œํฌ์ŠคํŽ˜์ด์Šค์— ํฌํ•จ๋  ํŒจํ‚ค์ง€๋“ค์˜ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ด ์ฃผ์„ธ์š”. apps/*๋Š” apps ๋””๋ ‰ํ† ๋ฆฌ ํ•˜์œ„์˜ ๋ชจ๋“  ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ํŒจํ‚ค์ง€๋กœ ์ธ์‹ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์˜ˆ์š”.

packages: - 'apps/*' - 'packages/*'

2๏ธโƒฃ ๋ฃจํŠธ package.json ์„ค์ • ๐Ÿ“„

๋ฃจํŠธ package.json์—๋Š” ๋ชจ๋…ธ๋ ˆํฌ ์ „์ฒด์— ์ ์šฉ๋˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋‚˜ ๊ฐœ๋ฐœ ์˜์กด์„ฑ(์˜ˆ: TypeScript)์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด์š”. private: true๋Š” ์ด ๋ฃจํŠธ ํ”„๋กœ์ ํŠธ๊ฐ€ ์ง์ ‘ ๋ฐฐํฌ๋˜์ง€ ์•Š์Œ์„ ์˜๋ฏธํ•ด์š”.

{ "name": "my-monorepo", "version": "1.0.0", "private": true, "scripts": { "build": "pnpm --filter \"./apps/**\" build", "dev": "pnpm --filter \"./apps/**\" dev", "lint": "pnpm --filter \"./**\" lint" }, "devDependencies": { "typescript": "^5.x.x" } }

3๏ธโƒฃ packages/ui ํŒจํ‚ค์ง€ ์„ค์ • ๐ŸŽจ

packages/ui๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ด์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŒจํ‚ค์ง€์˜ˆ์š”. ์—ฌ๊ธฐ์— react์™€ typescript ๊ด€๋ จ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ณ , main๊ณผ types ํ•„๋“œ๋ฅผ ์„ค์ •ํ•ด ์ฃผ์„ธ์š”.

{ "name": "@my-monorepo/ui", "version": "1.0.0", "main": "./src/index.ts", "types": "./src/index.ts", "license": "MIT", "scripts": { "lint": "eslint src" }, "devDependencies": { "@types/react": "^18.x.x", "@types/react-dom": "^18.x.x", "react": "^18.x.x", "eslint": "^8.x.x" } }

4๏ธโƒฃ packages/ui์— Button ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ โœจ

packages/ui/src/Button.tsx ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ๊ฐ„๋‹จํ•œ React ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์„ธ์š”.

import React from 'react'; interface ButtonProps { children: React.ReactNode; onClick?: () => void; } export function Button({ children, onClick }: ButtonProps) { return ( <button onClick={onClick} style={{ padding: '10px 20px', borderRadius: '5px', border: '1px solid #ccc', backgroundColor: '#f0f0f0', cursor: 'pointer', }} > {children} </button> ); }

๊ทธ๋ฆฌ๊ณ  packages/ui/src/index.ts ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์—ฌ Button ์ปดํฌ๋„ŒํŠธ๋ฅผ ์™ธ๋ถ€๋กœ ๋‚ด๋ณด๋‚ด ์ฃผ์„ธ์š”.

export * from './Button';

5๏ธโƒฃ apps/web ํŒจํ‚ค์ง€์—์„œ ui ํŒจํ‚ค์ง€ ์‚ฌ์šฉํ•˜๊ธฐ ๐ŸŒ

์ด์ œ apps/web/package.json์—์„œ ui ํŒจํ‚ค์ง€๋ฅผ ์˜์กด์„ฑ์œผ๋กœ ์ถ”๊ฐ€ํ•ด ์ค„ ์ฐจ๋ก€์˜ˆ์š”. "@my-monorepo/ui": "workspace:*"๋Š” ์ด ๋ชจ๋…ธ๋ ˆํฌ ๋‚ด์˜ ui ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์˜ˆ์š”.

{ "name": "web", "version": "1.0.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "@my-monorepo/ui": "workspace:*", "next": "14.x.x", "react": "18.x.x", "react-dom": "18.x.x" }, "devDependencies": { "@types/node": "20.x.x", "@types/react": "18.x.x", "@types/react-dom": "18.x.x", "eslint": "8.x.x", "eslint-config-next": "14.x.x", "typescript": "^5.x.x" } }

๋งˆ์ง€๋ง‰์œผ๋กœ apps/web/app/page.tsx์—์„œ ui ํŒจํ‚ค์ง€์˜ Button ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž„ํฌํŠธํ•˜์—ฌ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š”.

'use client'; import { Button } from '@my-monorepo/ui'; export default function HomePage() { const handleClick = () => { alert('๋ฒ„ํŠผ์ด ํด๋ฆญ๋˜์—ˆ์–ด์š”!'); }; return ( <div style={{ padding: '20px', textAlign: 'center' }}> <h1>์•ˆ๋…•ํ•˜์„ธ์š”, ๋ชจ๋…ธ๋ ˆํฌ ์˜ˆ์ œ์˜ˆ์š”!</h1> <Button onClick={handleClick}>ํด๋ฆญํ•ด ๋ณด์„ธ์š”</Button> </div> ); }

6๏ธโƒฃ ํ”„๋กœ์ ํŠธ ์‹คํ–‰ ๋ฐ ๊ฒฐ๊ณผ ํ™•์ธ โœ…

์ด์ œ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ pnpm install์„ ์‹คํ–‰ํ•˜์—ฌ ๋ชจ๋“  ์˜์กด์„ฑ์„ ์„ค์น˜ํ•˜๊ณ , pnpm dev ๋ช…๋ น์–ด๋กœ Next.js ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ด ๋ณด์„ธ์š”.

# ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๋ชจ๋“  ํŒจํ‚ค์ง€ ์˜์กด์„ฑ ์„ค์น˜ pnpm install # web ์•ฑ ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰ (๋ฃจํŠธ package.json์˜ scripts.dev ์‚ฌ์šฉ) pnpm dev

http://localhost:3000์œผ๋กœ ์ ‘์†ํ•˜๋ฉด packages/ui์— ์ •์˜๋œ Button ์ปดํฌ๋„ŒํŠธ๊ฐ€ apps/web์—์„œ ์ •์ƒ์ ์œผ๋กœ ๋ Œ๋”๋ง๋˜๊ณ  ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ์ด๋ ‡๊ฒŒ ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ์—์„œ ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‰ฝ๊ณ  ํšจ์œจ์ ์œผ๋กœ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

๐Ÿ’ก ๋ชจ๋…ธ๋ ˆํฌ, ์„ฑ๊ณต์ ์ธ ๋„์ž…์„ ์œ„ํ•œ ํŒ

๋ชจ๋…ธ๋ ˆํฌ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ด์ง€๋งŒ, ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜์ง€ ๋ชปํ•˜๋ฉด ์˜คํžˆ๋ ค ๋ณต์žก์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”. ์„ฑ๊ณต์ ์ธ ๋ชจ๋…ธ๋ ˆํฌ ๋„์ž…์„ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ์„ ์•Œ๋ ค๋“œ๋ฆด๊ฒŒ์š”.

  • ์ ์ง„์  ๋„์ž… ๊ณ ๋ ค: ๋ชจ๋“  ํ”„๋กœ์ ํŠธ๋ฅผ ํ•œ ๋ฒˆ์— ๋ชจ๋…ธ๋ ˆํฌ๋กœ ์ „ํ™˜ํ•˜๊ธฐ๋ณด๋‹ค๋Š”, ์‹ ๊ทœ ํ”„๋กœ์ ํŠธ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ๋ ˆ๊ฑฐ์‹œ ์‹œ์Šคํ…œ์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณด์„ธ์š”. ์ž‘์€ ์„ฑ๊ณต ๊ฒฝํ—˜์„ ํ†ตํ•ด ํŒ€์˜ ์ˆ™๋ จ๋„๋ฅผ ๋†’์ด๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ด์š”.
  • ์ ์ ˆํ•œ ํˆด ์„ ํƒ: ํŒ€์˜ ๊ทœ๋ชจ, ๊ธฐ์ˆ  ์Šคํƒ, ์š”๊ตฌ์‚ฌํ•ญ(๊ฐ•๋ ฅํ•œ ๋นŒ๋“œ ์บ์‹ฑ, ์ฝ”๋“œ ์ƒ์„ฑ, ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„ ๋ถ„์„ ๋“ฑ)์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๋ชจ๋…ธ๋ ˆํฌ ํˆด์„ ์‹ ์ค‘ํ•˜๊ฒŒ ์„ ํƒํ•ด์•ผ ํ•ด์š”. Nx๋‚˜ Turborepo ๊ฐ™์€ ๊ณ ์„ฑ๋Šฅ ํˆด์€ ์ดˆ๊ธฐ ํ•™์Šต ๊ณก์„ ์ด ์žˆ์ง€๋งŒ, ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ํฐ ์ด์ ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ๋ช…ํ™•ํ•œ ํŒจํ‚ค์ง€ ๊ฒฝ๊ณ„: ๊ฐ ํŒจํ‚ค์ง€์˜ ์—ญํ• ๊ณผ ์ฑ…์ž„์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜ํ•˜๊ณ , ํŒจํ‚ค์ง€ ๊ฐ„์˜ ์˜์กด์„ฑ ๊ทœ์น™์„ ์„ค์ •ํ•ด ์ฃผ์„ธ์š”. ์ˆœํ™˜ ์˜์กด์„ฑ(circular dependency)์„ ํ”ผํ•˜๊ณ , ์‘์ง‘๋„ ๋†’์€ ํŒจํ‚ค์ง€๋ฅผ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ด์š”.
  • CI/CD ์ตœ์ ํ™”: ๋ชจ๋…ธ๋ ˆํฌ ํˆด์ด ์ œ๊ณตํ•˜๋Š” ์ฆ๋ถ„ ๋นŒ๋“œ(incremental build) ๋ฐ ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ์ ๊ทน์ ์œผ๋กœ ํ™œ์šฉํ•˜์—ฌ, ๋ณ€๊ฒฝ๋œ ํŒจํ‚ค์ง€์—๋งŒ ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌ๊ฐ€ ์ด๋ฃจ์–ด์ง€๋„๋ก CI/CD ํŒŒ์ดํ”„๋ผ์ธ์„ ์ตœ์ ํ™”ํ•ด์•ผ ํ•ด์š”. ์ด๋Š” ๋นŒ๋“œ ์‹œ๊ฐ„์„ ํš๊ธฐ์ ์œผ๋กœ ๋‹จ์ถ•์‹œ์ผœ์ค˜์š”.
  • ์ฒ ์ €ํ•œ ๋ฌธ์„œํ™”: ๋ชจ๋…ธ๋ ˆํฌ์˜ ๊ตฌ์กฐ, ๊ฐ ํŒจํ‚ค์ง€์˜ ์—ญํ• , ํˆด ์‚ฌ์šฉ๋ฒ•, ๊ธฐ์—ฌ ๊ฐ€์ด๋“œ ๋“ฑ์„ ์ƒ์„ธํ•˜๊ฒŒ ๋ฌธ์„œํ™”ํ•ด ์ฃผ์„ธ์š”. ์ƒˆ๋กœ์šด ํŒ€์›์ด ํ•ฉ๋ฅ˜ํ•˜๊ฑฐ๋‚˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ํฐ ๋„์›€์ด ๋  ๊ฑฐ์˜ˆ์š”.
  • ์ฝ”๋“œ ์ปจ๋ฒค์…˜ ํ†ต์ผ: ESLint, Prettier, Stylelint ๋“ฑ์˜ ๋ฆฐํ„ฐ์™€ ํฌ๋งทํ„ฐ๋ฅผ ๋ฃจํŠธ ๋ ˆ๋ฒจ์—์„œ ์„ค์ •ํ•˜์—ฌ ๋ชจ๋“  ํŒจํ‚ค์ง€์˜ ์ฝ”๋“œ ์Šคํƒ€์ผ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•ด ์ฃผ์„ธ์š”. ์ด๋Š” ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•˜๊ณ  ์ฝ”๋“œ ํ’ˆ์งˆ์„ ๋†’์ด๋Š” ๋ฐ ๊ธฐ์—ฌํ•ด์š”.

๐Ÿ“ ์ •๋ฆฌ

์˜ค๋Š˜์€ ๋ชจ๋…ธ๋ ˆํฌ ์•„ํ‚คํ…์ฒ˜์— ๋Œ€ํ•ด ๊นŠ์ด ์žˆ๊ฒŒ ํƒ๊ตฌํ•ด ๋ดค์–ด์š”. ๋ชจ๋…ธ๋ ˆํฌ๋Š” ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•˜๊ณ , ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๋ฉฐ, CI/CD ํšจ์œจ์„ฑ์„ ๋†’์ด๋Š” ๊ฐ•๋ ฅํ•œ ์•„ํ‚คํ…์ฒ˜ ํŒจํ„ด์ด์—์š”.

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

์ด ํฌ์ŠคํŒ…์ด ์ดˆ์ค‘๊ธ‰ ๊ฐœ๋ฐœ์ž๋ถ„๋“ค๊ป˜ ๋ชจ๋…ธ๋ ˆํฌ์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋•๊ณ , ์‹ค๋ฌด์— ์ ์šฉํ•˜๋Š” ๋ฐ ์‹ค์งˆ์ ์ธ ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ์ข‹๊ฒ ์–ด์š”. ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“ ์ง€ ์งˆ๋ฌธํ•ด ์ฃผ์„ธ์š”!

๐Ÿ“ฎ ์ฐธ๊ณ 

์—ฐ๊ด€๋œ ํฌ์ŠคํŠธ