Skip to content

Convert react to web component

nhistory edited this page Jan 10, 2025 · 1 revision

ํ˜„์žฌ๊นŒ์ง€ ์ง„ํ–‰์ƒํ™ฉ ๊ณต์œ  (2025.01.10)

๋ฆฌ์•กํŠธ๋ฅผ ์›น ์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•˜๋Š” ์ด์œ 

  • ํ”„๋กœ์ ํŠธ ํ•„์š”์„ฑ: DaleStudy์—์„œ ๋””์ž์ธ ์‹œ์Šคํ…œ ์ ์šฉ์ด ํ•„์š”ํ•œ ์›น ์ปดํฌ๋„ŒํŠธ ํ”„๋กœ์ ํŠธ๊ฐ€ ์กด์žฌ
  • ๋ฏธ๋ž˜ ํ˜ธํ™˜์„ฑ: ๋ฆฌ์•กํŠธ ๊ธฐ๋ฐ˜ ๋””์ž์ธ ์‹œ์Šคํ…œ์„ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋ณ€ํ™˜ ํ•„์š”

r2wc ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ ํƒ ์ด์œ 

  • ์˜ค๋žœ ์ง€์›: 2019๋…„ ์ตœ์ดˆ ๋ฆด๋ฆฌ์ฆˆ, React 19๊นŒ์ง€ ์ง€์›
  • Shadow DOM ์ œ์–ด ๊ฐ€๋Šฅ: PandaCSS ์Šคํƒ€์ผ ์ ์šฉ ์‹œ ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ฐ€๋Šฅ์„ฑ

๋ฆฌ์•กํŠธ๋ฅผ ์›น ์ปดํฌ๋„ŒํŠธ๋กœ ์ „ํ™˜ํ•  ๋•Œ PandaCSS ์„ค์ •์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์–ด๋ ค์šด ์ด์œ 

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

์ฝ”๋“œ ์˜ˆ์‹œ

  1. Shadow DOM์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
import r2wc from "@r2wc/react-to-web-component";

const WcButton = r2wc(Button, {
  props: {
    children: "string",
  },
});

customElements.define("wc-button", WcButton);

์œ„์™€ ๊ฐ™์ด <Button> ์ปดํฌ๋„ŒํŠธ๋ฅผ ์›น ์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ € ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด <wc-button>์˜ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. image

๋˜ํ•œ PandaCSS์˜ ์Šคํƒ€์ผ ์†์„ฑ๋“ค๋„ ์ž˜ ์ ์šฉ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

image

  1. Shadow DOM์„ ํ™œ์„ฑํ™” ํ•œ ๊ฒฝ์šฐ
import r2wc from "@r2wc/react-to-web-component";

const WcButton = r2wc(Button, {
  shadow: "open", // Shadow DOM is opened
  props: {
    children: "string",
  },
});

customElements.define("wc-button", WcButton);

์œ„์™€ ๊ฐ™์ด Shadow DOM์„ ํ™œ์„ฑํ™” ์‹œํ‚ค๋ฉด ๋ธŒ๋ผ์šฐ์ € ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์— Shadow Root๊ฐ€ ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

image

Shadow DOM์˜ ์บก์Šํ™”, ์Šคํƒ€์ผ ๊ฒฉ๋ฆฌ ํŠน์„ฑ ๋•Œ๋ฌธ์— ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํƒ€์ผ์ด ๋” ์ด์ƒ ์ ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

image

Shadow DOM๊ณผ <slot> ์‚ฌ์šฉ ๋ฌธ์ œ

  • ์›น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์™€ ๋น„์Šทํ•œ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” <slot>์„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ
<wc-button>Click Me<wc-button>
  • ํ•˜์ง€๋งŒ ์œ„์—์„œ ๊ธฐ์ˆ ํ•œ ๋ฐ”์™€ ๊ฐ™์ด PandaCSS ์Šคํƒ€์ผ ์ ์šฉ ๋•Œ๋ฌธ์— Shadow DOM์„ ๋น„ํ™œ์„ฑํ™” ํ•˜๊ฒŒ ๋˜๋ฉด <slot>์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ
  • r2wc ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋Š” props ์•ˆ์—์„œ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ณ  ๋ฆฌ์•กํŠธ์˜ ๋ณ€์ˆ˜์— ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ. ๋งŒ์•ฝ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์˜ children์— ํ…์ŠคํŠธ๋ฅผ ๋„ฃ๊ณ  ์‹ถ๋‹ค๋ฉด props์—์„œ children ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ณ  <wc-button children="Click Me">์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ •์˜ํ•ด ์ค˜์•ผ ํ•จ

Reference