๐Ÿš€ ์›น ์ปดํฌ๋„ŒํŠธ์˜ ์„ธ๊ณ„๋กœ ๋– ๋‚˜๋ณผ๊นŒ์š”? Shadow DOM๊ณผ Custom Elements์˜ ์‹ ๋น„๋กœ์šด ์—ฌ์ •! ๐ŸŒŸ

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ ์›น ์ปดํฌ๋„ŒํŠธ์˜ ์„ธ๊ณ„๋กœ ๋– ๋‚˜๋ณผ๊นŒ์š”? Shadow DOM๊ณผ Custom Elements์˜ ์‹ ๋น„๋กœ์šด ์—ฌ์ •! ๐ŸŒŸ

 

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ ์ •๋ง ํฅ๋ฏธ์ง„์ง„ํ•œ ์ฃผ์ œ๋กœ ์—ฌ๋Ÿฌ๋ถ„๊ณผ ํ•จ๊ป˜ ์›น ๊ฐœ๋ฐœ์˜ ์ƒˆ๋กœ์šด ์ง€ํ‰์„ ์—ด์–ด๋ณผ ๊ฑฐ์˜ˆ์š”. ๋ฐ”๋กœ ์›น ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์ ธ๋ณผ ํ…๋ฐ์š”. ํŠนํžˆ Shadow DOM๊ณผ Custom Elements๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ํ•ต์‹ฌ ๊ธฐ์ˆ ์— ๋Œ€ํ•ด ๊นŠ์ด ํŒŒํ—ค์ณ๋ณผ ๊ฑฐ์˜ˆ์š”. ๐Ÿ˜Ž

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

์ž, ์ด์ œ๋ถ€ํ„ฐ ์šฐ๋ฆฌ๋Š” ๋งˆ๋ฒ•์˜ ๋ ˆ๊ณ  ๋ธ”๋ก์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์›Œ๋ณผ ๊ฑฐ์˜ˆ์š”. ๊ทธ๋ฆฌ๊ณ  ์ด ๋ธ”๋ก๋“ค๋กœ ์–ด๋–ป๊ฒŒ ๋ฉ‹์ง„ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. ์ค€๋น„๋˜์…จ๋‚˜์š”? ๊ทธ๋Ÿผ ์ถœ๋ฐœ~! ๐Ÿš‚

๐Ÿ’ก ์ž ๊น! ์•Œ๊ณ  ๊ฐ€๋ฉด ์ข‹์€ ํŒ!

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

๐ŸŒˆ ์›น ์ปดํฌ๋„ŒํŠธ๋ž€ ๋ญ˜๊นŒ์š”?

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์›น ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ๊นŒ์š”? ์›น ์ปดํฌ๋„ŒํŠธ๋Š” ์‰ฝ๊ฒŒ ๋งํ•ด์„œ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์‚ฌ์šฉ์ž ์ •์˜ HTML ์š”์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์›น ํ”Œ๋žซํผ API์˜ ๋ชจ์Œ์ด์—์š”. ์Œ... ๋„ˆ๋ฌด ์–ด๋ ต๋‚˜์š”? ใ…‹ใ…‹ใ…‹ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”!

์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๋Ÿฌ๋ถ„์ด ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ„ํŠผ์ด ์žˆ๋‹ค๊ณ  ํ•ด๋ณผ๊นŒ์š”? ์ด ๋ฒ„ํŠผ์€ ํด๋ฆญํ•˜๋ฉด ํŠน๋ณ„ํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋‚˜ํƒ€๋‚˜๊ณ , hover ํ–ˆ์„ ๋•Œ ์ƒ‰์ƒ์ด ๋ณ€ํ•˜๊ณ , ํ…์ŠคํŠธ๋„ ๋ฐ”๋€Œ๋Š” ๊ทธ๋Ÿฐ ๋ฉ‹์ง„ ๋ฒ„ํŠผ์ด์—์š”. ์ด๋Ÿฐ ๋ฒ„ํŠผ์„ ๋งค๋ฒˆ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋ฉด ์ •๋ง ๊ท€์ฐฎ๊ฒ ์ฃ ? ๐Ÿ˜ซ

๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ ์ด ๋ฒ„ํŠผ์„ <super-button>์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ํ•œ ๋ฒˆ๋งŒ ๋งŒ๋“ค์–ด ๋†“๊ณ , ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค <super-button>๋งŒ ์“ฐ๋ฉด ๋œ๋‹ค๋ฉด ์–ด๋–จ๊นŒ์š”? ์ด๊ฒŒ ๋ฐ”๋กœ ์›น ์ปดํฌ๋„ŒํŠธ์˜ ํ•ต์‹ฌ์ด์—์š”! ๐Ÿ˜Ž

๐ŸŽญ ์›น ์ปดํฌ๋„ŒํŠธ์˜ ์„ธ ๊ฐ€์ง€ ์ฃผ์š” ๊ธฐ์ˆ 

  • Custom Elements: ์ƒˆ๋กœ์šด HTML ํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.
  • Shadow DOM: ์ปดํฌ๋„ŒํŠธ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ์บก์Šํ™”ํ•ด์„œ ์™ธ๋ถ€์™€ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • HTML Templates: ๋ Œ๋”๋ง๋˜์ง€ ์•Š๋Š” HTML ์ฝ”๋“œ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์–ด์š”.

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

๊ทธ๋Ÿผ ์ด์ œ Shadow DOM๊ณผ Custom Elements์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณผ๊นŒ์š”? ์ด ๋‘ ๊ฐ€์ง€๋Š” ์›น ์ปดํฌ๋„ŒํŠธ์˜ ํ•ต์‹ฌ ๊ธฐ์ˆ ์ด์—์š”. ๋งˆ์น˜ ์Šˆํผํžˆ์–ด๋กœ์˜ ๋น„๋ฐ€ ๋Šฅ๋ ฅ ๊ฐ™์€ ๊ฑฐ์ฃ ! ๐Ÿฆธโ€โ™‚๏ธ๐Ÿฆธโ€โ™€๏ธ

์›น ์ปดํฌ๋„ŒํŠธ์˜ ์„ธ ๊ฐ€์ง€ ์ฃผ์š” ๊ธฐ์ˆ  Custom Elements Shadow DOM HTML Templates

์ด ๊ทธ๋ฆผ์„ ๋ณด๋ฉด ์›น ์ปดํฌ๋„ŒํŠธ์˜ ์„ธ ๊ฐ€์ง€ ์ฃผ์š” ๊ธฐ์ˆ ์ด ์–ด๋–ป๊ฒŒ ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ํ•œ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ์–ด์š”. Custom Elements, Shadow DOM, HTML Templates๊ฐ€ ์„œ๋กœ ์กฐํ™”๋กญ๊ฒŒ ์ž‘๋™ํ•˜๋ฉด์„œ ์›น ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ฑฐ์ฃ . ๐Ÿ˜Š

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

๐Ÿ•ต๏ธโ€โ™‚๏ธ Shadow DOM: ์›น ์ปดํฌ๋„ŒํŠธ์˜ ๋น„๋ฐ€ ์š”์›

์—ฌ๋Ÿฌ๋ถ„, Shadow DOM์ด๋ผ๋Š” ๋ง์„ ๋“ค์œผ๋ฉด ๋ญ๊ฐ€ ๋– ์˜ค๋ฅด๋‚˜์š”? ๋ญ”๊ฐ€ ๋น„๋ฐ€์Šค๋Ÿฝ๊ณ  ์‹ ๋น„๋กœ์šด ๋Š๋‚Œ์ด ๋“ค์ง€ ์•Š๋‚˜์š”? ใ…‹ใ…‹ใ…‹ ์‹ค์ œ๋กœ Shadow DOM์€ ์›น ์ปดํฌ๋„ŒํŠธ์˜ ๋น„๋ฐ€ ์š”์› ๊ฐ™์€ ์กด์žฌ์˜ˆ์š”. ์™œ ๊ทธ๋Ÿฐ์ง€ ํ•จ๊ป˜ ์•Œ์•„๋ณผ๊นŒ์š”? ๐Ÿ•ต๏ธโ€โ™€๏ธ

Shadow DOM์€ ์›น ์ปดํฌ๋„ŒํŠธ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ์ˆจ๊ธฐ๋Š” ์—ญํ• ์„ ํ•ด์š”. ๋งˆ์น˜ ๋น„๋ฐ€ ์š”์›์ด ์ค‘์š”ํ•œ ์ •๋ณด๋ฅผ ์ˆจ๊ธฐ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ . ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํƒ€์ผ๊ณผ ๊ธฐ๋Šฅ์ด ์™ธ๋ถ€์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ณ  ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๐Ÿ‘€

๐ŸŽญ Shadow DOM์˜ ์ฃผ์š” ํŠน์ง•

  • ์บก์Šํ™”: ์ปดํฌ๋„ŒํŠธ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ์™ธ๋ถ€์™€ ๋ถ„๋ฆฌํ•ด์š”.
  • ์Šค์ฝ”ํ”„ ๋ถ„๋ฆฌ: ์Šคํƒ€์ผ๊ณผ JavaScript๊ฐ€ ๋‹ค๋ฅธ ์š”์†Œ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์•„์š”.
  • ์žฌ์‚ฌ์šฉ์„ฑ: ๋…๋ฆฝ์ ์ธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‰ฝ๊ฒŒ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.

์ž, ์ด์ œ Shadow DOM์„ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ์•„๋ณผ๊นŒ์š”? ์ฝ”๋“œ๋กœ ๋ณด๋ฉด ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜Š


// Shadow DOM ์ƒ์„ฑํ•˜๊ธฐ
const div = document.createElement('div');
const shadowRoot = div.attachShadow({mode: 'open'});

// Shadow DOM ๋‚ด๋ถ€์— ์ปจํ…์ธ  ์ถ”๊ฐ€ํ•˜๊ธฐ
shadowRoot.innerHTML = `
  <style>
    p { color: red; }
  </style>
  <p>์•ˆ๋…•ํ•˜์„ธ์š”, ์ €๋Š” Shadow DOM ์•ˆ์— ์žˆ์–ด์š”!</p>
`;

// ํŽ˜์ด์ง€์— ์ถ”๊ฐ€ํ•˜๊ธฐ
document.body.appendChild(div);

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

Shadow DOM์˜ ๋˜ ๋‹ค๋ฅธ ๋ฉ‹์ง„ ์ ์€ ๋ญ˜๊นŒ์š”? ๋ฐ”๋กœ ์Šฌ๋กฏ(Slot)์ด๋ผ๋Š” ๊ธฐ๋Šฅ์ด์—์š”. ์Šฌ๋กฏ์„ ์‚ฌ์šฉํ•˜๋ฉด Shadow DOM ์™ธ๋ถ€์—์„œ ๋‚ด๋ถ€๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋น„๋ฐ€ ์š”์›์—๊ฒŒ ๋ฏธ์…˜์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐Ÿ˜Ž


// Shadow DOM ํ…œํ”Œ๋ฆฟ ๋งŒ๋“ค๊ธฐ
const template = document.createElement('template');
template.innerHTML = `
  <style>
    ::slotted(p) { color: blue; }
  </style>
  <slot></slot>
`;

// Custom Element ๋งŒ๋“ค๊ธฐ
class MyElement extends HTMLElement {
  constructor() {
    super();
    const shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.appendChild(template.content.cloneNode(true));
  }
}

customElements.define('my-element', MyElement);

// ์‚ฌ์šฉํ•˜๊ธฐ
document.body.innerHTML = `
  <my-element>
    <p>์ด ํ…์ŠคํŠธ๋Š” ์Šฌ๋กฏ์„ ํ†ตํ•ด ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค!</p>
  </my-element>
`;

์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? "์ด ํ…์ŠคํŠธ๋Š” ์Šฌ๋กฏ์„ ํ†ตํ•ด ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค!"๋ผ๋Š” ํŒŒ๋ž€์ƒ‰ ๊ธ€์”จ๊ฐ€ ๋‚˜ํƒ€๋‚  ๊ฑฐ์˜ˆ์š”. ์Šฌ๋กฏ์„ ํ†ตํ•ด ์™ธ๋ถ€์—์„œ ๋‚ด์šฉ์„ ์ „๋‹ฌํ–ˆ์ง€๋งŒ, ์Šคํƒ€์ผ์€ Shadow DOM ๋‚ด๋ถ€์—์„œ ์ •์˜ํ•œ ๋Œ€๋กœ ์ ์šฉ๋์–ด์š”. ์ •๋ง ๋ฉ‹์ง€์ง€ ์•Š๋‚˜์š”? ๐ŸŒŸ

Shadow DOM๊ณผ ์Šฌ๋กฏ์˜ ๋™์ž‘ ๋ฐฉ์‹ Light DOM Shadow DOM Slot Content

์ด ๊ทธ๋ฆผ์„ ๋ณด๋ฉด Shadow DOM๊ณผ ์Šฌ๋กฏ์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์–ด์š”. Light DOM(์ผ๋ฐ˜์ ์ธ DOM)์—์„œ Shadow DOM์œผ๋กœ ์ฝ˜ํ…์ธ ๊ฐ€ ์ „๋‹ฌ๋˜๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์ฃ . ์ด๋ ‡๊ฒŒ Shadow DOM์€ ์™ธ๋ถ€์™€ ๋‚ด๋ถ€๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด์„œ๋„ ๋ถ„๋ฆฌ๋œ ํ™˜๊ฒฝ์„ ์œ ์ง€ํ•ด์š”. ๐Ÿ‘

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

๐Ÿ’ก Shadow DOM ์‚ฌ์šฉ ์‹œ ์ฃผ์˜ํ•  ์ 

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

์ž, ์—ฌ๊ธฐ๊นŒ์ง€ Shadow DOM์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์–ด์š”. ์–ด๋•Œ์š”? ์ƒ๊ฐ๋ณด๋‹ค ์žฌ๋ฏธ์žˆ์ง€ ์•Š๋‚˜์š”? ใ…‹ใ…‹ใ…‹ Shadow DOM์€ ๋งˆ์น˜ ์›น ํŽ˜์ด์ง€ ์†์˜ ๋น„๋ฐ€ ์š”์› ๊ฐ™์•„์š”. ๊ฒ‰์œผ๋กœ ๋ณด์ด์ง€ ์•Š์ง€๋งŒ, ๋’ค์—์„œ ์—ด์‹ฌํžˆ ์ผํ•˜๋ฉด์„œ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋”์šฑ ๊ฐ•๋ ฅํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์กด์žฌ์ฃ . ๐Ÿฆธโ€โ™‚๏ธ

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” Custom Elements์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. Custom Elements๋Š” Shadow DOM๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์ •๋ง ๋ฉ‹์ง„ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋น„๋ฐ€ ์š”์›(Shadow DOM)๊ณผ ์Šˆํผํžˆ์–ด๋กœ(Custom Elements)๊ฐ€ ํž˜์„ ํ•ฉ์น˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์—์š”! ๐Ÿฆธโ€โ™€๏ธ๐Ÿ•ต๏ธโ€โ™‚๏ธ ๊ทธ๋Ÿผ ๋‹ค์Œ ๋ชจํ—˜์„ ํ–ฅํ•ด ์ถœ๋ฐœ~! ๐Ÿš€

๐Ÿฆธโ€โ™€๏ธ Custom Elements: ๋‚˜๋งŒ์˜ HTML ํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค์ž!

์•ˆ๋…•ํ•˜์„ธ์š”, ์›น ๊ฐœ๋ฐœ ์˜์›…๋“ค! ์ด์ œ ์šฐ๋ฆฌ์˜ ์—ฌ์ •์€ Custom Elements์˜ ์„ธ๊ณ„๋กœ ํ–ฅํ•ฉ๋‹ˆ๋‹ค. Custom Elements๋Š” ๋ง ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ์ž ์ •์˜ HTML ์š”์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฐ•๋ ฅํ•œ ๊ธฐ์ˆ ์ด์—์š”. ์ด๊ฑธ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ๋ถ„๋งŒ์˜ ํŠน๋ณ„ํ•œ HTML ํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๊ณ ์š”! ๐Ÿ˜ฒ

์ƒ๊ฐํ•ด๋ณด์„ธ์š”. ์—ฌ๋Ÿฌ๋ถ„์ด ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ณต์žกํ•œ UI ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋‹ค๋ฉด, ๊ทธ๊ฑธ ๋งค๋ฒˆ <div>์™€ <span>์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒŒ ์–ผ๋งˆ๋‚˜ ๊ท€์ฐฎ์„๊นŒ์š”? Custom Elements๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ทธ๋Ÿฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•˜๋‚˜์˜ ํƒœ๊ทธ๋กœ ๊ฐ„๋‹จํžˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, <super-button>์ด๋‚˜ <awesome-card> ๊ฐ™์€ ํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๊ณ ์š”! ๐ŸŽ‰

๐ŸŒŸ Custom Elements์˜ ์žฅ์ 

  • ์žฌ์‚ฌ์šฉ์„ฑ: ํ•œ ๋ฒˆ ๋งŒ๋“ค๋ฉด ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์บก์Šํ™”: ์ปดํฌ๋„ŒํŠธ์˜ ๋กœ์ง๊ณผ ์Šคํƒ€์ผ์„ ํ•˜๋‚˜์˜ ์š”์†Œ๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ์–ด์š”.
  • ๊ฐ€๋…์„ฑ: ๋ณต์žกํ•œ ๋งˆํฌ์—… ๋Œ€์‹  ์˜๋ฏธ ์žˆ๋Š” ํƒœ๊ทธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ํ™•์žฅ์„ฑ: ๊ธฐ์กด HTML ์š”์†Œ๋ฅผ ํ™•์žฅํ•˜์—ฌ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด์š”.

์ž, ์ด์ œ Custom Elements๋ฅผ ์–ด๋–ป๊ฒŒ ๋งŒ๋“œ๋Š”์ง€ ์‚ดํŽด๋ณผ๊นŒ์š”? ์ฝ”๋“œ๋กœ ๋ณด๋ฉด ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜Š


// Custom Element ํด๋ž˜์Šค ์ •์˜ํ•˜๊ธฐ
class SuperButton extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode: 'open'});
    this.shadowRoot.innerHTML = `
      <style>
        button {
          background-color: #ff4081;
          color: white;
          border: none;
          padding: 10px 20px;
          border-radius: 5px;
          cursor: pointer;
          transition: all 0.3s;
        }
        button:hover {
          background-color: #ff80ab;
          transform: scale(1.1);
        }
      </style>
      <button><slot></slot></button>
    `;
  }
}

// Custom Element ๋“ฑ๋กํ•˜๊ธฐ
customElements.define('super-button', SuperButton);

// ์‚ฌ์šฉํ•˜๊ธฐ
document.body.innerHTML = `
  <super-button>ํด๋ฆญํ•ด๋ณด์„ธ์š”!</super-button>
`;

์šฐ์™€! ์ด์ œ ์šฐ๋ฆฌ๋งŒ์˜ <super-button> ํƒœ๊ทธ๊ฐ€ ์ƒ๊ฒผ์–ด์š”! ๐Ÿ˜† ์ด ๋ฒ„ํŠผ์€ ํด๋ฆญํ•˜๋ฉด ์‚ด์ง ์ปค์ง€๊ณ , ๋งˆ์šฐ์Šค๋ฅผ ์˜ฌ๋ฆฌ๋ฉด ์ƒ‰์ƒ์ด ๋ณ€ํ•˜๋Š” ๋ฉ‹์ง„ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋„ ๊ฐ€์ง€๊ณ  ์žˆ์ฃ . ๊ทธ๋ฆฌ๊ณ  ์ด ๋ชจ๋“  ๊ธฐ๋Šฅ๊ณผ ์Šคํƒ€์ผ์ด ํ•˜๋‚˜์˜ ํƒœ๊ทธ์— ๋‹ด๊ฒจ ์žˆ์–ด์š”. ์ •๋ง ๋Œ€๋‹จํ•˜์ง€ ์•Š๋‚˜์š”?

Custom Elements๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ทœ์น™์„ ์ง€์ผœ์•ผ ํ•ด์š”:

  • ํด๋ž˜์Šค ์ด๋ฆ„์€ ๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•ด์š” (์˜ˆ: SuperButton)
  • ํƒœ๊ทธ ์ด๋ฆ„์—๋Š” ๋ฐ˜๋“œ์‹œ ํ•˜์ดํ”ˆ(-)์ด ํฌํ•จ๋˜์–ด์•ผ ํ•ด์š” (์˜ˆ: super-button)
  • HTMLElement๋ฅผ ์ƒ์†๋ฐ›์•„์•ผ ํ•ด์š”

์ด๋ ‡๊ฒŒ ๋งŒ๋“  Custom Elements๋Š” ๋‹ค๋ฅธ HTML ์š”์†Œ๋“ค๊ณผ ๋˜‘๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ์ด๋ฒคํŠธ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ฑฐ๋‚˜, ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์ฃ . ์ •๋ง ํŽธ๋ฆฌํ•˜์ง€ ์•Š๋‚˜์š”? ๐Ÿ˜Ž

Custom Elements์˜ ๊ตฌ์กฐ Custom Element Shadow DOM Public API Internal Structure Attributes & Methods

์ด ๊ทธ๋ฆผ์€ Custom Element์˜ ๊ตฌ์กฐ๋ฅผ ๋ณด์—ฌ์ค˜์š”. Shadow DOM์€ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ์บก์Šํ™”ํ•˜๊ณ , Public API๋Š” ์™ธ๋ถ€์™€ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•ด์š”. ์ด ๋‘ ๊ฐ€์ง€๊ฐ€ ์กฐํ™”๋กญ๊ฒŒ ์ž‘๋™ํ•˜๋ฉด์„œ ๊ฐ•๋ ฅํ•œ Custom Element๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ฑฐ์ฃ ! ๐Ÿ‘

Custom Elements๋Š” ์ •๋ง ๋‹ค์–‘ํ•œ ๊ณณ์—์„œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉ์ž ๋ฆฌ๋ทฐ ์นด๋“œ๋ฅผ ๋งŒ๋“ ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณผ๊นŒ์š”? <user-review> ํƒœ๊ทธ ํ•˜๋‚˜๋กœ ๋ณ„์ , ์‚ฌ์šฉ์ž ์ด๋ฆ„, ๋ฆฌ๋ทฐ ๋‚ด์šฉ์„ ๋ชจ๋‘ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ๋„ ๊น”๋”ํ•ด์ง€๊ณ , ๋‚˜์ค‘์— ์ˆ˜์ •ํ•˜๊ธฐ๋„ ํ›จ์”ฌ ์‰ฌ์›Œ์ ธ์š”. ๐Ÿ˜Š

๐Ÿ’ก Custom Elements ์‚ฌ์šฉ ์‹œ ์ฃผ์˜ํ•  ์ 

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

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


class SuperButton extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode: 'open'});
    // ์ƒ๋žต...
  }

  // ์š”์†Œ๊ฐ€ DOM์— ์ถ”๊ฐ€๋  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  connectedCallback() {
    console.log('SuperButton์ด ํŽ˜์ด์ง€์— ์ถ”๊ฐ€๋˜์—ˆ์–ด์š”!');
  }

  // ์š”์†Œ๊ฐ€ DOM์—์„œ ์ œ๊ฑฐ๋  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  disconnectedCallback() {
    console.log('SuperButton์ด ํŽ˜์ด์ง€์—์„œ ์ œ๊ฑฐ๋˜์—ˆ์–ด์š”!');
  }

  // ์š”์†Œ์˜ ์†์„ฑ์ด ๋ณ€๊ฒฝ๋  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  attributeChangedCallback(name, oldValue, newValue) {
    console.log(`${name} ์†์„ฑ์ด ${oldValue}์—์„œ ${newValue}๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์–ด์š”!`);
  }

  // ๊ด€์ฐฐํ•  ์†์„ฑ๋“ค์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  static get observedAttributes() {
    return ['color', 'size'];
  }
}

customElements.define('super-button', SuperButton);

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

Custom Elements์˜ ๋˜ ๋‹ค๋ฅธ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์€ ๊ธฐ์กด HTML ์š”์†Œ๋ฅผ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑฐ์˜ˆ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ธฐ๋ณธ ๋ฒ„ํŠผ์— ํŠน๋ณ„ํ•œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ด๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์žˆ์–ด์š”:


class SuperButton extends HTMLButtonElement {
  constructor() {
    super();
    this.addEventListener('click', () => {
      this.style.transform = 'scale(1.1)';
      setTimeout(() => {
        this.style.transform = 'scale(1)';
      }, 200);
    });
  }
}

customElements.define('super-button', SuperButton, {extends: 'button'});

// ์‚ฌ์šฉํ•˜๊ธฐ
document.body.innerHTML = `
  <button is="super-button">์Šˆํผ ๋ฒ„ํŠผ!</button>
`;

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ธฐ๋ณธ <button> ์š”์†Œ์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ๊ทธ๋Œ€๋กœ ๊ฐ€์ง€๋ฉด์„œ, ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค ์‚ด์ง ์ปค์กŒ๋‹ค ์ž‘์•„์ง€๋Š” ํšจ๊ณผ๊ฐ€ ์ถ”๊ฐ€๋œ ๋ฒ„ํŠผ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๋ฉ‹์ง€์ง€ ์•Š๋‚˜์š”? ๐Ÿ˜†

Custom Elements์˜ ํ™•์žฅ HTMLButtonElement SuperButton extends

์ด ๊ทธ๋ฆผ์€ SuperButton์ด HTMLButtonElement๋ฅผ ํ™•์žฅํ•˜๋Š” ๋ชจ์Šต์„ ๋ณด์—ฌ์ค˜์š”. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ๊ธฐ์กด ๋ฒ„ํŠผ์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ƒ์†๋ฐ›์œผ๋ฉด์„œ๋„ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์ฃ ! ๐Ÿ‘

Custom Elements๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ •๋ง ๋งŽ์€ ๊ฒƒ๋“ค์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท์—์„œ ์‚ฌ์šฉ์ž ํ”„๋กœํ•„ ์นด๋“œ๋ฅผ ๋งŒ๋“ ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณผ๊นŒ์š”? <user-profile> ํƒœ๊ทธ ํ•˜๋‚˜๋กœ ์‚ฌ์šฉ์ž์˜ ์ด๋ฆ„, ํ”„๋กœํ•„ ์‚ฌ์ง„, ํ‰์ , ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค ๋“ฑ์„ ๋ชจ๋‘ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ๋„ ๊น”๋”ํ•ด์ง€๊ณ , ๋‚˜์ค‘์— ์ˆ˜์ •ํ•˜๊ธฐ๋„ ํ›จ์”ฌ ์‰ฌ์›Œ์ ธ์š”. ๐Ÿ˜Š

๐ŸŒŸ Custom Elements ์‚ฌ์šฉ ํŒ

  • ์˜๋ฏธ ์žˆ๋Š” ์ด๋ฆ„ ์‚ฌ์šฉํ•˜๊ธฐ: ํƒœ๊ทธ ์ด๋ฆ„๋งŒ ๋ด๋„ ์–ด๋–ค ๊ธฐ๋Šฅ์„ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ์ด๋ฆ„์„ ์ง€์–ด์ฃผ์„ธ์š”.
  • ์žฌ์‚ฌ์šฉ์„ฑ ๊ณ ๋ คํ•˜๊ธฐ: ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ์—ฐํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜์„ธ์š”.
  • ์ ‘๊ทผ์„ฑ ์‹ ๊ฒฝ ์“ฐ๊ธฐ: ์Šคํฌ๋ฆฐ ๋ฆฌ๋” ๋“ฑ์˜ ๋ณด์กฐ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๋“ค๋„ ์‰ฝ๊ฒŒ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ฃผ์„ธ์š”.
  • ๋ฌธ์„œํ™”ํ•˜๊ธฐ: ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์ด ์—ฌ๋Ÿฌ๋ถ„์˜ Custom Elements๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ์šฉ๋ฒ•์„ ์ž˜ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.

์ž, ์—ฌ๊ธฐ๊นŒ์ง€ Custom Elements์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์–ด์š”. ์–ด๋•Œ์š”? ์ƒ๊ฐ๋ณด๋‹ค ์žฌ๋ฏธ์žˆ๊ณ  ๊ฐ•๋ ฅํ•˜์ง€ ์•Š๋‚˜์š”? ใ…‹ใ…‹ใ…‹ Custom Elements๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ •๋ง ๋งŽ์€ ๊ฒƒ๋“ค์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์—ฌ๋Ÿฌ๋ถ„๋งŒ์˜ HTML ํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค์–ด ์›น ๊ฐœ๋ฐœ์„ ๋”์šฑ ์žฌ๋ฏธ์žˆ๊ณ  ํšจ์œจ์ ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ฃ . ๐Ÿฆธโ€โ™€๏ธ

์ด์ œ ์šฐ๋ฆฌ๋Š” Shadow DOM๊ณผ Custom Elements๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋์–ด์š”. ์ด ๋‘˜์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์ •๋ง ๋ฉ‹์ง„ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋น„๋ฐ€ ์š”์›(Shadow DOM)๊ณผ ์Šˆํผํžˆ์–ด๋กœ(Custom Elements)๊ฐ€ ํž˜์„ ํ•ฉ์ณ ์„ธ์ƒ์„ ๊ตฌํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์—์š”! ๐Ÿฆธโ€โ™‚๏ธ๐Ÿ•ต๏ธโ€โ™€๏ธ

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

๐ŸŒŸ Shadow DOM๊ณผ Custom Elements์˜ ํ™˜์ƒ์ ์ธ ์กฐํ•ฉ

์•ˆ๋…•ํ•˜์„ธ์š”, ์›น ๊ฐœ๋ฐœ์˜ ์˜์›…๋“ค! ์ด์ œ ์šฐ๋ฆฌ๋Š” Shadow DOM๊ณผ Custom Elements๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ๊ฐ•๋ ฅํ•œ ๋ฌด๊ธฐ๋ฅผ ์†์— ์ฅ๊ฒŒ ๋์–ด์š”. ์ด ๋‘ ๊ฐ€์ง€๋ฅผ ์–ด๋–ป๊ฒŒ ์กฐํ•ฉํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„์ง€, ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค ๋ฉ‹์ง„ ๊ฒƒ๋“ค์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€ ํ•จ๊ป˜ ์•Œ์•„๋ณผ๊นŒ์š”? ๐Ÿ˜Ž

Shadow DOM๊ณผ Custom Elements๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด, ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ณ  ์บก์Šํ™”๋œ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ๋Š” ๋‹ค๋ฅธ ์ฝ”๋“œ์™€ ์™„์ „ํžˆ ๋ถ„๋ฆฌ๋˜์–ด ๋™์ž‘ํ•˜๋ฉด์„œ๋„, HTML์˜ ์ผ๋ถ€๋กœ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ฃ . ์ •๋ง ๋ฉ‹์ง€์ง€ ์•Š๋‚˜์š”? ๐ŸŒˆ

์ž, ์ด์ œ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์•Œ์•„๋ณผ๊นŒ์š”?


class FancyCard extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode: 'open'});

    this.shadowRoot.innerHTML = `
      <style>
        .card {
          background-color: #fff;
          border-radius: 8px;
          box-shadow: 0 4px 8px rgba(0,0,0,0.1);
          padding: 16px;
          margin: 16px;
          transition: all 0.3s ease;
        }
        .card:hover {
          transform: translateY(-5px);
          box-shadow: 0 6px 12px rgba(0,0,0,0.15);
        }
        h2 {
          color: #333;
          margin-top: 0;
        }
        p {
          color: #666;
        }
      </style>
      <div class="card">
        <h2><slot name="title">์ œ๋ชฉ</slot></h2>
        <p><slot name="content">๋‚ด์šฉ</slot></p>
      </div>
    `;
  }
}

customElements.define('fancy-card', FancyCard);

// ์‚ฌ์šฉํ•˜๊ธฐ
document.body.innerHTML += `
  <fancy-card>
    <span slot="title">์•ˆ๋…•ํ•˜์„ธ์š”, ์›น ์ปดํฌ๋„ŒํŠธ!</span>
    <span slot="content">์ด๊ฒƒ์€ Shadow DOM๊ณผ Custom Elements๋ฅผ ์‚ฌ์šฉํ•œ ๋ฉ‹์ง„ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ์˜ˆ์š”.</span>
  </fancy-card>
`;

์šฐ์™€! ์ด์ œ ์šฐ๋ฆฌ๋งŒ์˜ <fancy-card> ํƒœ๊ทธ๊ฐ€ ์ƒ๊ฒผ์–ด์š”! ๐Ÿ˜† ์ด ์นด๋“œ๋Š” ๋งˆ์šฐ์Šค๋ฅผ ์˜ฌ๋ฆฌ๋ฉด ์‚ด์ง ๋– ์˜ค๋ฅด๋Š” ํšจ๊ณผ๊ฐ€ ์žˆ๊ณ , ์ œ๋ชฉ๊ณผ ๋‚ด์šฉ์„ ์Šฌ๋กฏ์„ ํ†ตํ•ด ์ž์œ ๋กญ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ๋ฆฌ๊ณ  ์ด ๋ชจ๋“  ์Šคํƒ€์ผ๊ณผ ๊ตฌ์กฐ๊ฐ€ Shadow DOM ์•ˆ์— ์บก์Šํ™”๋˜์–ด ์žˆ์–ด์„œ ์™ธ๋ถ€ ์Šคํƒ€์ผ์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์•„์š”. ์ •๋ง ๋Œ€๋‹จํ•˜์ง€ ์•Š๋‚˜์š”?

Fancy Card ๊ตฌ์กฐ Fancy Card Shadow DOM Title Slot Content Slot

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

์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด ์ •๋ง ๋งŽ์€ ์ด์ ์ด ์žˆ์–ด์š”:

๐ŸŒŸ ์›น ์ปดํฌ๋„ŒํŠธ์˜ ์žฅ์ 

  • ์žฌ์‚ฌ์šฉ์„ฑ: ํ•œ ๋ฒˆ ๋งŒ๋“ค๋ฉด ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ์—์„œ ์‰ฝ๊ฒŒ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์บก์Šํ™”: ์ปดํฌ๋„ŒํŠธ์˜ ๋‚ด๋ถ€ ๋กœ์ง๊ณผ ์Šคํƒ€์ผ์ด ์™ธ๋ถ€์™€ ์™„์ „ํžˆ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์–ด์š”.
  • ์œ ์ง€๋ณด์ˆ˜์„ฑ: ๊ฐ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋…๋ฆฝ์ ์ด์–ด์„œ ์ˆ˜์ •์ด ์‰ฝ๊ณ  ๋‹ค๋ฅธ ๋ถ€๋ถ„์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์•„์š”.
  • ํ™•์žฅ์„ฑ: ๊ธฐ์กด HTML ์š”์†Œ๋ฅผ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ์š”์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.

์ด๋Ÿฐ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์ •๋ง ๋‹ค์–‘ํ•œ ๊ฒƒ๋“ค์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”?


// ์‚ฌ์šฉ์ž ํ”„๋กœํ•„ ์นด๋“œ
class UserProfileCard extends HTMLElement {
  // ... (๊ตฌํ˜„ ์ƒ๋žต)
}
customElements.define('user-profile-card', UserProfileCard);

// ๋ฆฌ๋ทฐ ์ปดํฌ๋„ŒํŠธ
class ReviewComponent extends HTMLElement {
  // ... (๊ตฌํ˜„ ์ƒ๋žต)
}
customElements.define('review-component', ReviewComponent);

// ๋ณ„์  ์ปดํฌ๋„ŒํŠธ
class StarRating extends HTMLElement {
  // ... (๊ตฌํ˜„ ์ƒ๋žต)
}
customElements.define('star-rating', StarRating);

// ์‚ฌ์šฉํ•˜๊ธฐ
document.body.innerHTML += `
  <user-profile-card>
    <span slot="name">๊น€๋ฉ‹์Ÿ์ด</span>
    <span slot="skill">์›น ๋””์ž์ธ</span>
    <star-rating slot="rating" value="4.5"></star-rating>
  </user-profile-card>

  <review-component>
    <span slot="author">๋ฐ•๊ณ ๊ฐ</span>
    <span slot="content">์ •๋ง ํ›Œ๋ฅญํ•œ ์„œ๋น„์Šค์˜€์Šต๋‹ˆ๋‹ค!</span>
    <star-rating slot="rating" value="5"></star-rating>
  </review-component>
`;

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

๋ฌผ๋ก , ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋„ ์žˆ์–ด์š”:

๐Ÿ’ก ์›น ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ

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

ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ์ฃผ์˜์‚ฌํ•ญ๋“ค์„ ์ž˜ ๊ณ ๋ คํ•˜๋ฉด์„œ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์›น ์ปดํฌ๋„ŒํŠธ๋Š” ์ •๋ง ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๊ฐ€ ๋  ์ˆ˜ ์žˆ์–ด์š”. ์—ฌ๋Ÿฌ๋ถ„์˜ ์›น ๊ฐœ๋ฐœ ์‹ค๋ ฅ์„ ํ•œ ๋‹จ๊ณ„ ๋” ๋†’์—ฌ์ค„ ๊ฑฐ์˜ˆ์š”! ๐Ÿš€

์ž, ์—ฌ๊ธฐ๊นŒ์ง€ Shadow DOM๊ณผ Custom Elements๋ฅผ ์กฐํ•ฉํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์–ด์š”. ์–ด๋•Œ์š”? ์ƒ๊ฐ๋ณด๋‹ค ์žฌ๋ฏธ์žˆ๊ณ  ๊ฐ•๋ ฅํ•˜์ง€ ์•Š๋‚˜์š”? ใ…‹ใ…‹ใ…‹ ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์€ ์›น ์ปดํฌ๋„ŒํŠธ์˜ ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ๋œ ๊ฒƒ ๊ฐ™์•„์š”! ๐Ÿง™โ€โ™‚๏ธโœจ

์›น ์ปดํฌ๋„ŒํŠธ์˜ ์„ธ๊ณ„๋Š” ์ •๋ง ๋ฌด๊ถ๋ฌด์ง„ํ•ด์š”. ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ์ƒ๋ ฅ์„ ๋งˆ์Œ๊ป ํŽผ์ณ๋ณด์„ธ์š”! ์–ด๋–ค ๋ฉ‹์ง„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์œผ์‹ ๊ฐ€์š”? ์‚ฌ์šฉ์ž ํ”„๋กœํ•„ ์นด๋“œ? ๋™์ ์ธ ์ฐจํŠธ? ์•„๋‹ˆ๋ฉด ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ํ˜•ํƒœ์˜ UI? ๊ฐ€๋Šฅ์„ฑ์€ ๋ฌดํ•œํ•ด์š”! ๐ŸŒˆ

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ best practices์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋” ํšจ์œจ์ ์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์šด ์›น์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์›Œ๋ณผ ๊ฑฐ์˜ˆ์š”. ์ •๋ง ๊ธฐ๋Œ€๋˜์ง€ ์•Š๋‚˜์š”? ๊ทธ๋Ÿผ ๋‹ค์Œ ๋ชจํ—˜์„ ํ–ฅํ•ด ์ถœ๋ฐœ~! ๐Ÿš€

๐Ÿ—๏ธ ์›น ์ปดํฌ๋„ŒํŠธ๋กœ ๋” ๋‚˜์€ ์›น์‚ฌ์ดํŠธ ๋งŒ๋“ค๊ธฐ

์•ˆ๋…•ํ•˜์„ธ์š”, ์›น ๊ฐœ๋ฐœ์˜ ๋งˆ๋ฒ•์‚ฌ๋“ค! ์ด์ œ ์šฐ๋ฆฌ๋Š” ์›น ์ปดํฌ๋„ŒํŠธ์˜ ๊ธฐ๋ณธ์„ ๋งˆ์Šคํ„ฐํ–ˆ์–ด์š”. Shadow DOM๊ณผ Custom Elements์˜ ๊ฐ•๋ ฅํ•œ ํž˜์„ ์ด์šฉํ•ด ๋ฉ‹์ง„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ๋์ฃ . ์ด์ œ๋Š” ์ด ์ง€์‹์„ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๊ณ , ๋” ๋‚˜์€ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. ์ค€๋น„๋˜์…จ๋‚˜์š”? ๐Ÿ˜Ž

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

์ž, ์ด์ œ ์‹ค์ œ๋กœ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์•Œ์•„๋ณผ๊นŒ์š”?

๐Ÿš€ ์›น ์ปดํฌ๋„ŒํŠธ ์ ์šฉ ๋‹จ๊ณ„

  1. ์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„ํ•˜๊ธฐ
  2. ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„ํ•˜๊ธฐ
  3. ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธํ•˜๊ธฐ
  4. ์ปดํฌ๋„ŒํŠธ ๋ฌธ์„œํ™”ํ•˜๊ธฐ
  5. ์ปดํฌ๋„ŒํŠธ ๋ฐฐํฌ ๋ฐ ์‚ฌ์šฉํ•˜๊ธฐ

๊ฐ ๋‹จ๊ณ„๋ฅผ ์ž์„ธํžˆ ์‚ดํŽด๋ณผ๊นŒ์š”?

1. ์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„ํ•˜๊ธฐ

๋จผ์ € ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•„์š”ํ•œ์ง€ ํŒŒ์•…ํ•˜๊ณ , ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ ์—ญํ• ๊ณผ ๊ธฐ๋Šฅ์„ ์ •์˜ํ•ด์•ผ ํ•ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท ํ”Œ๋žซํผ์„ ๋งŒ๋“ ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณผ๊นŒ์š”?


// ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ ๋ชฉ๋ก
- <user-profile>: ์‚ฌ์šฉ์ž ํ”„๋กœํ•„ ์ •๋ณด๋ฅผ ํ‘œ์‹œ
- <skill-tag>: ์‚ฌ์šฉ์ž์˜ ์Šคํ‚ฌ์„ ํƒœ๊ทธ ํ˜•ํƒœ๋กœ ํ‘œ์‹œ
- <review-card>: ์‚ฌ์šฉ์ž ๋ฆฌ๋ทฐ๋ฅผ ์นด๋“œ ํ˜•ํƒœ๋กœ ํ‘œ์‹œ
- <star-rating>: ๋ณ„์ ์„ ํ‘œ์‹œํ•˜๊ณ  ์ž…๋ ฅ๋ฐ›์Œ
- <service-card>: ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค ์ •๋ณด๋ฅผ ์นด๋“œ ํ˜•ํƒœ๋กœ ํ‘œ์‹œ

2. ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„ํ•˜๊ธฐ

์„ค๊ณ„ํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•ด์š”. Shadow DOM๊ณผ Custom Elements๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด์š”.


class UserProfile extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode: 'open'});
    this.shadowRoot.innerHTML = `
      <style>
        /* ์Šคํƒ€์ผ ์ •์˜ */
      </style>
      <div class="user-profile">
        <img src="${this.getAttribute('avatar')}" alt="User Avatar">
        <h2>${this.getAttribute('name')}</h2>
        <p>${this.getAttribute('bio')}</p>
        <slot name="skills"></slot>
      </div>
    `;
  }
}

customElements.define('user-profile', UserProfile);

3. ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธํ•˜๊ธฐ

๊ตฌํ˜„ํ•œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธํ•ด์š”. ๋‹ค์–‘ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๊ณ ๋ คํ•ด ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ด์š”.


// ํ…Œ์ŠคํŠธ ์˜ˆ์‹œ
describe('UserProfile', () => {
  it('should render user information correctly', () => {
    document.body.innerHTML = `
      <user-profile name="๊น€๋ฉ‹์Ÿ์ด" avatar="avatar.jpg" bio="์›น ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค">
        <skill-tag slot="skills">JavaScript</skill-tag>
        <skill-tag slot="skills">HTML</skill-tag>
        <skill-tag slot="skills">CSS</skill-tag>
      </user-profile>
    `;

    const userProfile = document.querySelector('user-profile');
    const shadowRoot = userProfile.shadowRoot;

    expect(shadowRoot.querySelector('h2').textContent).toBe('๊น€๋ฉ‹์Ÿ์ด');
    expect(shadowRoot.querySelector('img').src).toContain('avatar.jpg');
    expect(shadowRoot.querySelector('p').textContent).toBe('์›น ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค');
    expect(shadowRoot.querySelectorAll('slot[name="skills"] skill-tag').length).toBe(3);
  });
});

4. ์ปดํฌ๋„ŒํŠธ ๋ฌธ์„œํ™”ํ•˜๊ธฐ

๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์ด ์—ฌ๋Ÿฌ๋ถ„์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•ด์š”.


/**
 * UserProfile ์ปดํฌ๋„ŒํŠธ
 * 
 * ์‚ฌ์šฉ์ž์˜ ํ”„๋กœํ•„ ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
 * 
 * @attribute name - ์‚ฌ์šฉ์ž ์ด๋ฆ„
 * @attribute avatar - ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ URL
 * @attribute bio - ์ž๊ธฐ์†Œ๊ฐœ
 * 
 * @slot skills - ์‚ฌ์šฉ์ž์˜ ์Šคํ‚ฌ์„ ๋‚˜ํƒ€๋‚ด๋Š” skill-tag ์š”์†Œ๋“ค  ๋„ค, ๊ณ„์†ํ•ด์„œ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

 * 
 * @example
 * <user-profile name="๊น€๋ฉ‹์Ÿ์ด" avatar="avatar.jpg" bio="์›น ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค">
 *   <skill-tag slot="skills">JavaScript</skill-tag>
 *   <skill-tag slot="skills">HTML</skill-tag>
 *   <skill-tag slot="skills">CSS</skill-tag>
 * </user-profile>
 */

5. ์ปดํฌ๋„ŒํŠธ ๋ฐฐํฌ ๋ฐ ์‚ฌ์šฉํ•˜๊ธฐ

๊ตฌํ˜„ํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•ด์š”. ํ•„์š”ํ•˜๋‹ค๋ฉด npm ํŒจํ‚ค์ง€๋กœ ๋ฐฐํฌํ•ด์„œ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ๋„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์š”.


// index.html
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>์žฌ๋Šฅ๋„ท</title>
  <script src="components/user-profile.js"></script>
  <script src="components/skill-tag.js"></script>
  <script src="components/review-card.js"></script>
  <script src="components/star-rating.js"></script>
  <script src="components/service-card.js"></script>
</head>
<body>
  <user-profile name="๊น€๋ฉ‹์Ÿ์ด" avatar="avatar.jpg" bio="์›น ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค">
    <skill-tag slot="skills">JavaScript</skill-tag>
    <skill-tag slot="skills">HTML</skill-tag>
    <skill-tag slot="skills">CSS</skill-tag>
  </user-profile>

  <service-card title="์›น์‚ฌ์ดํŠธ ์ œ์ž‘" price="500,000์›">
    <p slot="description">๋ฐ˜์‘ํ˜• ์›น์‚ฌ์ดํŠธ๋ฅผ ์ œ์ž‘ํ•ด ๋“œ๋ฆฝ๋‹ˆ๋‹ค.</p>
    <star-rating slot="rating" value="4.5"></star-rating>
  </service-card>

  <review-card author="๋ฐ•๋งŒ์กฑ" date="2023-06-15">
    <p slot="content">์ •๋ง ํ›Œ๋ฅญํ•œ ์„œ๋น„์Šค์˜€์Šต๋‹ˆ๋‹ค. ๊ฐ•๋ ฅ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค!</p>
    <star-rating slot="rating" value="5"></star-rating>
  </review-card>
</body>
</html>

์ด๋ ‡๊ฒŒ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๋” ๊น”๋”ํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›Œ์ ธ์š”. ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ ๋‚ด๋ถ€ ๋กœ์ง์€ ์ˆจ๊ฒจ์ ธ ์žˆ์ง€๋งŒ, ํ•„์š”ํ•œ ์ •๋ณด๋Š” ์†์„ฑ์„ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์ฃ . ๐Ÿ˜Š

ํ•˜์ง€๋งŒ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ช‡ ๊ฐ€์ง€ best practices๋ฅผ ์•Œ์•„๋‘๋ฉด ์ข‹์•„์š”:

๐ŸŒŸ ์›น ์ปดํฌ๋„ŒํŠธ Best Practices

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

์ด๋Ÿฌํ•œ practices๋ฅผ ๋”ฐ๋ฅด๋ฉด ๋”์šฑ ๊ฒฌ๊ณ ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์šด ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๐Ÿ˜Ž

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

์›น ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜ ์žฌ๋Šฅ๋„ท ํ”Œ๋žซํผ ์‚ฌ์šฉ์ž ํ”„๋กœํ•„ ์„œ๋น„์Šค ๋ชฉ๋ก ๋ฆฌ๋ทฐ ์‹œ์Šคํ…œ ๊ณตํ†ต UI ์ปดํฌ๋„ŒํŠธ (๋ฒ„ํŠผ, ์ž…๋ ฅ ํ•„๋“œ, ๋ชจ๋‹ฌ ๋“ฑ)

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

์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ์–ด์š”:

  • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ ํ–ฅ์ƒ: ํ•œ ๋ฒˆ ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ์—์„œ ์‰ฝ๊ฒŒ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ ์ฆ๊ฐ€: ๋ณต์žกํ•œ UI๋„ ์ž‘์€ ์ปดํฌ๋„ŒํŠธ๋“ค๋กœ ๋‚˜๋ˆ„์–ด ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์–ด ์ƒ์‚ฐ์„ฑ์ด ๋†’์•„์ ธ์š”.
  • ์ผ๊ด€๋œ UI/UX: ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์ผ๊ด€๋œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์„ฑ๋Šฅ ์ตœ์ ํ™”: ๊ฐ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋ฏ€๋กœ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์–ด ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋ผ์š”.

๋ฌผ๋ก , ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋„ ์žˆ์–ด์š”:

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ

  • ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜์„ฑ์„ ํ•ญ์ƒ ์ฒดํฌํ•ด์•ผ ํ•ด์š”. ์ผ๋ถ€ ์˜ค๋ž˜๋œ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์ง€์›๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์–ด์š”.
  • SEO์— ์ฃผ์˜ํ•ด์•ผ ํ•ด์š”. ๊ฒ€์ƒ‰ ์—”์ง„์ด Shadow DOM ๋‚ด๋ถ€์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์ œ๋Œ€๋กœ ์ธ์‹ํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์–ด์š”. ํฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” Redux๋‚˜ MobX ๊ฐ™์€ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”.

์ž, ์—ฌ๊ธฐ๊นŒ์ง€ ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์–ด์š”. ์–ด๋– ์‹ ๊ฐ€์š”? ์ƒ๊ฐ๋ณด๋‹ค ์žฌ๋ฏธ์žˆ๊ณ  ๊ฐ•๋ ฅํ•˜์ง€ ์•Š๋‚˜์š”? ใ…‹ใ…‹ใ…‹ ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์€ ์›น ์ปดํฌ๋„ŒํŠธ์˜ ๋งˆ์Šคํ„ฐ๊ฐ€ ๋œ ๊ฒƒ ๊ฐ™์•„์š”! ๐Ÿ†

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

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

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