μΉ μ»΄ν¬λνΈλ‘ νμ₯ κ°λ₯νκ³ μ μ§λ³΄μ μ©μ΄νλ©° νλ μμν¬μ ꡬμ λ°μ§ μλ μ ν리μΌμ΄μ μ ꡬμΆνμΈμ. κ²¬κ³ ν κΈλ‘λ² μν°νλΌμ΄μ¦ μμ€ν μ μν μν€ν μ² ν¨ν΄μ μ¬μΈ΅ λΆμν©λλ€.
μΉ μ»΄ν¬λνΈ νλ μμν¬: νμ₯ κ°λ₯ν μν€ν μ²λ₯Ό μν μ²μ¬μ§
λΉ λ₯΄κ² μ§ννλ μΉ κ°λ° νκ²½μμ νμ₯ κ°λ₯νκ³ , μ μ§λ³΄μκ° μ©μ΄νλ©°, λ―Έλμλ μ¬μ© κ°λ₯ν μν€ν μ²λ₯Ό μ°Ύλ κ²μ μ μΈκ³ μμ§λμ΄λ§ 리λμ μν€ν νΈμκ² λμμλ κ³Όμ μ λλ€. μ°λ¦¬λ μλ§μ νλ μμν¬λ₯Ό κ±°μ³μκ³ , λͺ¨λ리μ νλ‘ νΈμλμ 볡μ‘μ±μ ν€μ³λκ°μΌλ©°, κΈ°μ μ’ μμ κ³ ν΅μ λκ»΄μμ΅λλ€. λ§μ½ κ·Έ ν΄λ΅μ΄ λ λ€λ₯Έ μλ‘μ΄ νλ μμν¬κ° μλλΌ νλ«νΌ μ체λ‘μ νκ·λΌλ©΄ μ΄λ¨κΉμ? λ°λ‘ μΉ μ»΄ν¬λνΈ(Web Components)μ λλ€.
μΉ μ»΄ν¬λνΈλ μλ‘μ΄ κΈ°μ μ΄ μλμ§λ§, κ·Έ μ±μλμ μ£Όλ³ λꡬλ€μ΄ μκ³μ μ λλ¬νμ¬ νλμ μ΄κ³ νμ₯ κ°λ₯ν νλ‘ νΈμλ μν€ν μ²μ μ΄μμ΄ λμμ΅λλ€. μΉ μ»΄ν¬λνΈλ ν¨λ¬λ€μμ μ νμ μ μν©λλ€. μ¦, νλ μμν¬μ μ’ μλ μ¬μΌλ‘μμ λ²μ΄λ UIλ₯Ό ꡬμΆνλ 보νΈμ μ΄κ³ νμ€ κΈ°λ°μ μ κ·Ό λ°©μμΌλ‘ λμκ°λ κ²μ λλ€. μ΄ κΈμ λ¨μν 컀μ€ν λ²νΌ νλλ₯Ό λ§λλ λ°©λ²μ λν κ²μ΄ μλλλ€. μ΄κ²μ κΈλ‘λ² μν°νλΌμ΄μ¦ μ ν리μΌμ΄μ μ μꡬμ¬νμ λ§μΆ° μ€κ³λ μΉ μ»΄ν¬λνΈ νλ μμν¬λ₯Ό μ¬μ©νμ¬ ν¬κ΄μ μ΄κ³ νμ₯ κ°λ₯ν μν€ν μ²λ₯Ό ꡬννκΈ° μν μ λ΅μ κ°μ΄λμ λλ€.
ν¨λ¬λ€μμ μ ν: μ νμ₯ κ°λ₯ν μν€ν μ²λ₯Ό μν΄ μΉ μ»΄ν¬λνΈλ₯Ό μ¬μ©νλκ°?
μλ λμ λκ·λͺ¨ μ‘°μ§λ€μ λ°λ³΅λλ λ¬Έμ μ μ§λ©΄ν΄ μμ΅λλ€. ν λΆμμ νμ Angularλ₯Ό μ¬μ©νμ¬ μ νκ΅°μ ꡬμΆν©λλ€. λ€λ₯Έ νμ μΈμλ μ νΈλμ λ°λΌ Reactλ₯Ό μ¬μ©ν©λλ€. μΈ λ²μ§Έ νμ Vueλ₯Ό μ¬μ©ν©λλ€. κ° νμ μμ°μ μΌ μ μμ§λ§, μ‘°μ§ μ 체λ μ€λ³΅λ λ Έλ ₯μΌλ‘ κ³ ν΅λ°μ΅λλ€. λ²νΌ, λ μ§ μ νκΈ°, ν€λμ κ°μ UI μμλ₯Ό μν λ¨μΌνκ³ κ³΅μ κ°λ₯ν λΌμ΄λΈλ¬λ¦¬κ° μμ΅λλ€. μ΄λ¬ν ννΈνλ νμ μ μ ν΄νκ³ , μ μ§λ³΄μ λΉμ©μ μ¦κ°μν€λ©°, λΈλλ μΌκ΄μ±μ μ λͺ½μΌλ‘ λ§λλλ€.
μΉ μ»΄ν¬λνΈλ λΈλΌμ°μ λ€μ΄ν°λΈ API μΈνΈλ₯Ό νμ©νμ¬ μ΄ λ¬Έμ λ₯Ό μ§μ μ μΌλ‘ ν΄κ²°ν©λλ€. μ΄λ₯Ό ν΅ν΄ νΉμ JavaScript νλ μμν¬μ μ½λ§€μ΄μ§ μλ μΊ‘μνλκ³ μ¬μ¬μ© κ°λ₯ν UI μμλ₯Ό λ§λ€ μ μμ΅λλ€. μ΄κ²μ΄ λ°λ‘ μΉ μ»΄ν¬λνΈκ° μ§λ μν€ν μ²μ νμ κΈ°λ°μ λλ€.
νμ₯μ±μ μν μ£Όμ μ΄μ
- νλ μμν¬ λ 립μ±: μ΄κ²μ΄ κ°μ₯ ν΅μ¬μ μΈ νΉμ§μ λλ€. Litμ΄λ Stencilκ³Ό κ°μ λΌμ΄λΈλ¬λ¦¬λ‘ ꡬμΆλ μΉ μ»΄ν¬λνΈλ React, Angular, Vue, Svelte λλ μμ HTML/JavaScript νλ‘μ νΈμμλ μννκ² μ¬μ©ν μ μμ΅λλ€. μ΄λ λ€μν κΈ°μ μ€νμ κ°μ§ λκ·λͺ¨ μ‘°μ§μκ² κ²μ 체μΈμ μ΄λ©°, μ μ§μ μΈ λ§μ΄κ·Έλ μ΄μ μ μ΄μ§νκ³ μ₯κΈ°μ μΈ νλ‘μ νΈ μμ μ±μ κ°λ₯νκ² ν©λλ€.
- μλ DOM(Shadow DOM)μ ν΅ν μ§μ ν μΊ‘μν: λκ·λͺ¨ CSSμ κ°μ₯ ν° κ³Όμ μ€ νλλ μ€μ½ν(scope)μ λλ€. μ ν리μΌμ΄μ μ ν λΆλΆμ μ€νμΌμ΄ μ μΆλμ΄ λ€λ₯Έ λΆλΆμ μλμΉ μκ² μν₯μ μ€ μ μμ΅λλ€. μλ DOMμ μ»΄ν¬λνΈλ₯Ό μν λΉκ³΅κ°, μΊ‘μνλ DOM νΈλ¦¬λ₯Ό μμ±νλ©°, μ체μ μΈ μ€μ½νλ₯Ό κ°μ§ μ€νμΌκ³Ό λ§ν¬μ μ κ°μ§λλ€. μ΄ 'μμ'λ μ€νμΌ μΆ©λκ³Ό μ μ λ€μμ€νμ΄μ€ μ€μΌμ λ°©μ§νμ¬ μ»΄ν¬λνΈλ₯Ό κ²¬κ³ νκ³ μμΈ‘ κ°λ₯νκ² λ§λλλ€.
- ν₯μλ μ¬μ¬μ©μ± λ° μνΈμ΄μ©μ±: μΉ μ»΄ν¬λνΈλ μΉ νμ€μ΄κΈ° λλ¬Έμ κΆκ·Ήμ μΈ μμ€μ μ¬μ¬μ©μ±μ μ 곡ν©λλ€. μ€μνλ λμμΈ μμ€ν μ΄λ μ»΄ν¬λνΈ λΌμ΄λΈλ¬λ¦¬λ₯Ό ν λ² κ΅¬μΆνκ³ NPMκ³Ό κ°μ ν¨ν€μ§ κ΄λ¦¬μλ₯Ό ν΅ν΄ λ°°ν¬ν μ μμ΅λλ€. λͺ¨λ νμ μ νν νλ μμν¬μ κ΄κ³μμ΄ μ΄λ¬ν μ»΄ν¬λνΈλ₯Ό μ¬μ©νμ¬ λͺ¨λ λμ§νΈ μμ°μμ μκ°μ λ° κΈ°λ₯μ μΌκ΄μ±μ 보μ₯ν μ μμ΅λλ€.
- κΈ°μ μ€νμ λ―Έλ 보μ₯: νλ μμν¬λ μκ²Όλ€κ° μ¬λΌμ§μ§λ§, μΉ νλ«νΌμ μ§μλ©λλ€. μΉ νμ€μ κΈ°λ°μΌλ‘ ν΅μ¬ UI λ μ΄μ΄λ₯Ό ꡬμΆν¨μΌλ‘μ¨, λ¨μΌ νλ μμν¬μ μλͺ μ£ΌκΈ°λ‘λΆν° λΆλ¦¬(decoupling)ν μ μμ΅λλ€. 5λ νμ μλ‘κ³ λ λμ νλ μμν¬κ° λ±μ₯νλλΌλ μ 체 μ»΄ν¬λνΈ λΌμ΄λΈλ¬λ¦¬λ₯Ό λ€μ μμ±ν νμ μμ΄ κ°λ¨ν ν΅ν©ν μ μμ΅λλ€. μ΄λ κΈ°μ λ°μ μ λ°λ₯Έ μνκ³Ό λΉμ©μ ν¬κ² μ€μ¬μ€λλ€.
μΉ μ»΄ν¬λνΈ μν€ν μ²μ ν΅μ¬ κΈ°λ₯
νμ₯ κ°λ₯ν μν€ν μ²λ₯Ό ꡬννλ €λ©΄ μΉ μ»΄ν¬λνΈλ₯Ό ꡬμ±νλ λ€ κ°μ§ μ£Όμ μ¬μμ μ΄ν΄νλ κ²μ΄ μ€μν©λλ€.
1. 컀μ€ν μ리먼νΈ(Custom Elements): κ΅¬μ± μμ
컀μ€ν
μλ¦¬λ¨ΌνΈ APIλ₯Ό μ¬μ©νλ©΄ μμ λ§μ HTML νκ·Έλ₯Ό μ μν μ μμ΅λλ€. <custom-button>μ΄λ <profile-card>λ₯Ό λ§λ€κ³ , κ·Έ λμμ μ μνλ JavaScript ν΄λμ€λ₯Ό μ°κ²°ν μ μμ΅λλ€. λΈλΌμ°μ λ μ΄λ¬ν νκ·Έλ₯Ό μΈμνκ³ ν΄λΉ νκ·Έλ₯Ό λ§λ λλ§λ€ ν΄λμ€λ₯Ό μΈμ€ν΄μ€ννλλ‘ νμ΅λ©λλ€.
ν΅μ¬ κΈ°λ₯μ μ»΄ν¬λνΈ μλͺ μ£ΌκΈ°μ μ£Όμ μκ°μ κ°μ ν μ μκ² ν΄μ£Όλ λΌμ΄νμ¬μ΄ν΄ μ½λ°± μΈνΈμ λλ€.
connectedCallback(): μ»΄ν¬λνΈκ° DOMμ μ½μ λ λ μ€νλ©λλ€. μ€μ , λ°μ΄ν° κ°μ Έμ€κΈ°, μ΄λ²€νΈ 리μ€λ μΆκ°μ μ΄μμ μ λλ€.disconnectedCallback(): μ»΄ν¬λνΈκ° DOMμμ μ κ±°λ λ μ€νλ©λλ€. μ 리 μμ μ μ ν©ν©λλ€.attributeChangedCallback(): μ»΄ν¬λνΈμ κ΄μ°° λμ μμ± μ€ νλκ° λ³κ²½λ λ μ€νλ©λλ€. μΈλΆλ‘λΆν°μ λ°μ΄ν° λ³κ²½μ λ°μνλ μ£Όμ λ©μ»€λμ¦μ λλ€.
2. μλ DOM(Shadow DOM): μΊ‘μνμ μμ
μμ μΈκΈνλ―μ΄, μλ DOMμ μ§μ ν μΊ‘μνλ₯Ό μν λΉκ²°μ λλ€. μ΄κ²μ μμμ μ¨κ²¨μ§, λΆλ¦¬λ DOMμ 첨λΆν©λλ€. μλ λ£¨νΈ λ΄λΆμ λ§ν¬μ κ³Ό μ€νμΌμ λ©μΈ λ¬Έμλ‘λΆν° 격리λ©λλ€. μ¦, λ©μΈ νμ΄μ§μ CSSλ μ»΄ν¬λνΈ λ΄λΆμ μν₯μ μ€ μ μμΌλ©°, μ»΄ν¬λνΈ λ΄λΆμ CSSλ λ°μΌλ‘ μ μΆλ μ μμ΅λλ€. μΈλΆμμ μ»΄ν¬λνΈ μ€νμΌμ μ§μ νλ μ μΌν λ°©λ²μ μ£Όλ‘ CSS 컀μ€ν μμ±(CSS Custom Properties)μ μ¬μ©νμ¬ μ μ μλ κ³΅κ° APIλ₯Ό ν΅νλ κ²μ λλ€.
3. HTML ν νλ¦Ώ & μ¬λ‘―: μ½ν μΈ μ£Όμ λ©μ»€λμ¦
<template> νκ·Έλ₯Ό μ¬μ©νλ©΄ μ¦μ λ λλ§λμ§ μκ³ λμ€μ 볡μ νμ¬ μ¬μ©ν μ μλ λ§ν¬μ
μ‘°κ°μ μ μΈν μ μμ΅λλ€. μ΄λ μ»΄ν¬λνΈμ λ΄λΆ ꡬ쑰λ₯Ό μ μνλ λ§€μ° ν¨μ¨μ μΈ λ°©λ²μ
λλ€.
<slot> μ리먼νΈλ μΉ μ»΄ν¬λνΈμ μ‘°ν© λͺ¨λΈμ
λλ€. μ΄κ²μ μ»΄ν¬λνΈμ μλ DOM λ΄μμ μΈλΆλ‘λΆν° μμ μ λ§ν¬μ
μΌλ‘ μ±μΈ μ μλ νλ μ΄μ€νλ μν μ ν©λλ€. μ΄λ₯Ό ν΅ν΄ 컀μ€ν
ν€λ, λ³Έλ¬Έ, νΈν°λ₯Ό μ£Όμ
ν μ μλ μ λ€λ¦ <modal-dialog>μ κ°μ΄ μ μ°νκ³ μ‘°ν© κ°λ₯ν μ»΄ν¬λνΈλ₯Ό λ§λ€ μ μμ΅λλ€.
λꡬ μ ν: μΉ μ»΄ν¬λνΈ νλ μμν¬μ λΌμ΄λΈλ¬λ¦¬
λ°λλΌ JavaScriptλ‘ μΉ μ»΄ν¬λνΈλ₯Ό μμ±ν μ μμ§λ§, νΉν λ λλ§, λ°μμ±, μμ± μ²λ¦¬λ₯Ό ν λ μ₯ν©ν μ μμ΅λλ€. μ΅μ λꡬλ€μ μ΄λ¬ν 보μΌλ¬νλ μ΄νΈλ₯Ό μΆμννμ¬ κ°λ° κ²½νμ ν¨μ¬ λ μννκ² λ§λλλ€.
Lit (Google μ μ)
Litμ λΉ λ₯΄κ³ κ°λ²Όμ΄ μΉ μ»΄ν¬λνΈλ₯Ό λ§λ€κΈ° μν κ°λ¨ν λΌμ΄λΈλ¬λ¦¬μ λλ€. μμ ν κΈ°λ₯μ κ°μΆ νλ μμν¬κ° λλ €κ³ νμ§ μμ΅λλ€. λμ ν νλ¦Ώ(JavaScript νκ·Έλ ν νλ¦Ώ 리ν°λ΄ μ¬μ©), λ°μν μμ±, μ€μ½ν μ€νμΌμ μν μ μΈμ APIλ₯Ό μ 곡ν©λλ€. μΉ νλ«νΌμ κ°κΉκ³ μ©λμ΄ μμ 곡μ κ°λ₯ν μ»΄ν¬λνΈ λΌμ΄λΈλ¬λ¦¬ λ° λμμΈ μμ€ν μ ꡬμΆνλ λ° νμν μ νμ λλ€.
Stencil (Ionic ν μ μ)
Stencilμ λΌμ΄λΈλ¬λ¦¬λΌκΈ°λ³΄λ€λ μ»΄νμΌλ¬μ κ°κΉμ΅λλ€. TypeScriptλ JSXμ κ°μ μ΅μ κΈ°λ₯μ μ¬μ©νμ¬ μ»΄ν¬λνΈλ₯Ό μμ±νλ©΄, Stencilμ΄ μ΄λ₯Ό νμ€μ μ€μνκ³ μ΅μ νλ μΉ μ»΄ν¬λνΈλ‘ μ»΄νμΌνμ¬ μ΄λμλ μ€νν μ μκ² ν΄μ€λλ€. κ°μ DOM, λΉλκΈ° λ λλ§, μ»΄ν¬λνΈ λΌμ΄νμ¬μ΄ν΄κ³Ό κ°μ κΈ°λ₯μ ν¬ν¨νμ¬ Reactλ Vue κ°μ νλ μμν¬μ μ μ¬ν κ°λ°μ κ²½νμ μ 곡ν©λλ€. μ΄λ λ νλΆν κΈ°λ₯μ νκ²½μ μνκ±°λ μΉ μ»΄ν¬λνΈμ μ§ν©μΌλ‘ 볡μ‘ν μ ν리μΌμ΄μ μ ꡬμΆνλ νμκ² νλ₯ν μ νμ λλ€.
μ κ·Ό λ°©μ λΉκ΅
- Lit μ¬μ© κ²½μ°: μ£Όμ λͺ©νκ° λ€λ₯Έ μ ν리μΌμ΄μ μμ μ¬μ©ν κ°λ³κ³ κ³ μ±λ₯μ λμμΈ μμ€ν μ΄λ κ°λ³ μ»΄ν¬λνΈ λΌμ΄λΈλ¬λ¦¬λ₯Ό ꡬμΆνλ κ²½μ°. νλ«νΌ νμ€μ κ°κΉκ² μ μ§νλ κ²μ μ€μνκ² μκ°ν λ.
- Stencil μ¬μ© κ²½μ°: μμ ν μ ν리μΌμ΄μ μ΄λ 볡μ‘ν μ»΄ν¬λνΈμ λκ·λͺ¨ μ νκ΅°μ ꡬμΆνλ κ²½μ°. νμ΄ TypeScript, JSX, λ΄μ₯ κ°λ° μλ² λ° λꡬλ₯Ό ν¬ν¨ν 'λͺ¨λ κ²μ΄ ν¬ν¨λ(batteries-included)' κ²½νμ μ νΈν λ.
- λ°λλΌ JS μ¬μ© κ²½μ°: νλ‘μ νΈκ° λ§€μ° μκ±°λ, μμ‘΄μ± μλ μ μ± μ΄ μ격νκ±°λ, κ·Ήλλ‘ μμμ΄ μ νλ νκ²½μ μν΄ κ΅¬μΆν λ.
νμ₯ κ°λ₯ν ꡬνμ μν μν€ν μ² ν¨ν΄
μ΄μ κ°λ³ μ»΄ν¬λνΈλ₯Ό λμ΄ μ 체 μ ν리μΌμ΄μ κ³Ό μμ€ν μ νμ₯ κ°λ₯νκ² κ΅¬μ±νλ λ°©λ²μ μ΄ν΄λ³΄κ² μ΅λλ€.
ν¨ν΄ 1: μ€μνλ, νλ μμν¬ λ 립μ λμμΈ μμ€ν
μ΄κ²μ λκ·λͺ¨ κΈ°μ μμ μΉ μ»΄ν¬λνΈλ₯Ό μ¬μ©νλ κ°μ₯ μΌλ°μ μ΄κ³ κ°λ ₯ν μ¬λ‘μ λλ€. λͺ©νλ λͺ¨λ UI μμλ₯Ό μν λ¨μΌ μ§μ€ 곡κΈμ(single source of truth)μ λ§λλ κ²μ λλ€.
μλ λ°©μ: μ λ΄ νμ΄ Litμ΄λ Stencilμ μ¬μ©νμ¬ ν΅μ¬ UI μ»΄ν¬λνΈ(μ: <brand-button>, <data-table>, <global-header>) λΌμ΄λΈλ¬λ¦¬λ₯Ό ꡬμΆνκ³ μ μ§λ³΄μν©λλ€. μ΄ λΌμ΄λΈλ¬λ¦¬λ λΉκ³΅κ° NPM λ μ§μ€νΈλ¦¬μ κ²μλ©λλ€. μ‘°μ§ μ λ°μ μ ν νλ€μ React, Angular, Vue μ¬μ© μ¬λΆμ κ΄κ³μμ΄ μ΄λ¬ν μ»΄ν¬λνΈλ₯Ό μ€μΉνκ³ μ¬μ©ν μ μμ΅λλ€. λμμΈ μμ€ν
νμ λͺ
νν λ¬Έμ(μ’
μ’
Storybookκ³Ό κ°μ λꡬ μ¬μ©), λ²μ κ΄λ¦¬ λ° μ§μμ μ 곡ν©λλ€.
κΈλ‘λ² μν₯: λΆλ―Έ, μ λ½, μμμμ κ°λ° νλΈλ₯Ό λ κΈλ‘λ² κΈ°μ μ Angularλ‘ κ΅¬μΆλ λ΄λΆ HR ν¬νΈλΆν° Reactλ‘ λ§λ λμΈ μ μμκ±°λ μ¬μ΄νΈμ μ΄λ₯΄κΈ°κΉμ§ λͺ¨λ λμ§νΈ μ νμ΄ λμΌν μκ°μ μΈμ΄μ μ¬μ©μ κ²½νμ 곡μ νλλ‘ λ³΄μ₯ν μ μμ΅λλ€. μ΄λ λμμΈ λ° κ°λ°μ μ€λ³΅μ±μ λν μ€μ΄κ³ λΈλλ μ 체μ±μ κ°νν©λλ€.
ν¨ν΄ 2: μΉ μ»΄ν¬λνΈλ₯Ό μ¬μ©ν λ§μ΄ν¬λ‘ νλ‘ νΈμλ
λ§μ΄ν¬λ‘ νλ‘ νΈμλ ν¨ν΄μ ν¬κ³ λͺ¨λ리μν νλ‘ νΈμλ μ ν리μΌμ΄μ μ λ μκ³ λ 립μ μΌλ‘ λ°°ν¬ κ°λ₯ν μλΉμ€λ‘ λΆν΄ν©λλ€. μΉ μ»΄ν¬λνΈλ μ΄ ν¨ν΄μ ꡬννκΈ°μ μ΄μμ μΈ κΈ°μ μ λλ€.
μλ λ°©μ: κ° λ§μ΄ν¬λ‘ νλ‘ νΈμλλ 컀μ€ν
μ리먼νΈλ‘ λνλ©λλ€. μλ₯Ό λ€μ΄, μ μμκ±°λ μ ν νμ΄μ§λ μ¬λ¬ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ‘ κ΅¬μ±λ μ μμ΅λλ€: <search-header> (κ²μν κ΄λ¦¬), <product-recommendations> (λ°μ΄ν° κ³Όνν κ΄λ¦¬), <shopping-cart-widget> (κ²°μ ν κ΄λ¦¬). κ°λ²Όμ΄ μ
Έ μ ν리μΌμ΄μ
μ΄ νμ΄μ§μμ μ΄λ¬ν μ»΄ν¬λνΈλ€μ μ‘°μ¨νλ μν μ ν©λλ€. κ° μ»΄ν¬λνΈλ νμ€ μΉ μ»΄ν¬λνΈμ΄λ―λ‘, νλ€μ μΌκ΄λ 컀μ€ν
μλ¦¬λ¨ΌνΈ μΈν°νμ΄μ€λ₯Ό λ
ΈμΆνλ ν μνλ κΈ°μ (React, Vue λ±)λ‘ κ΅¬μΆν μ μμ΅λλ€.
κΈλ‘λ² μν₯: μ΄λ₯Ό ν΅ν΄ μ μΈκ³μ λΆμ°λ νλ€μ΄ μμ¨μ μΌλ‘ μμ ν μ μμ΅λλ€. μΈλμ ν νμ λ μΌμ κ²μνκ³Ό νμ μμ΄ μ ν μΆμ² κΈ°λ₯μ μ λ°μ΄νΈνκ³ λ°°ν¬ν μ μμ΅λλ€. μ΄λ¬ν μ‘°μ§μ , κΈ°μ μ λΆλ¦¬λ κ°λ°κ³Ό λ°°ν¬ μμͺ½μμ μμ²λ νμ₯μ±μ κ°λ₯νκ² ν©λλ€.
ν¨ν΄ 3: "μμΌλλ" μν€ν μ²
μ΄ ν¨ν΄μ μ±λ₯μ΄ κ°μ₯ μ€μν μ½ν μΈ μ€μ¬μ μΉμ¬μ΄νΈμ μ ν©ν©λλ€. μμ΄λμ΄λ λλΆλΆ μ μ μΈ μλ² λ λλ§ HTML νμ΄μ§λ₯Ό μ 곡νλ©΄μ μΉ μ»΄ν¬λνΈλ‘ ꡬλλλ μκ³ κ³ λ¦½λ "μμΌλλ" ννμ μνΈμμ©μ±μ μΆκ°νλ κ²μ λλ€.
μλ λ°©μ: μλ₯Ό λ€μ΄ λ΄μ€ κΈ°μ¬ νμ΄μ§λ μ£Όλ‘ μ μ μΈ ν μ€νΈμ μ΄λ―Έμ§λ‘ ꡬμ±λ©λλ€. μ΄ μ½ν μΈ λ μλ²μμ λ λλ§λμ΄ λΈλΌμ°μ λ‘ λ§€μ° λΉ λ₯΄κ² μ μ‘λ μ μμΌλ©°, κ²°κ³Όμ μΌλ‘ μ°μν μ΅μ΄ μ½ν μΈ ν νμΈνΈ(FCP) μκ°μ 보μ¬μ€λλ€. λΉλμ€ νλ μ΄μ΄, λκΈ μΉμ , ꡬλ μμκ³Ό κ°μ μνΈμμ© μμλ€μ μΉ μ»΄ν¬λνΈλ‘ μ λ¬λ©λλ€. μ΄λ¬ν μ»΄ν¬λνΈλ€μ μ§μ° λ‘λ©(lazy-loaded)λ μ μλλ°, μ΄λ ν΄λΉ μ»΄ν¬λνΈκ° μ¬μ©μμκ² λ³΄μ΄κΈ° μ§μ μλ§ JavaScriptκ° λ€μ΄λ‘λλκ³ μ€νλλ€λ μλ―Έμ λλ€.
κΈλ‘λ² μν₯: κΈλ‘λ² λ―Έλμ΄ κΈ°μ μ κ²½μ°, μ΄λ μΈν°λ· μ°κ²°μ΄ λλ¦° μ§μμ μ¬μ©μλ€μ΄ ν΅μ¬ μ½ν μΈ λ₯Ό κ±°μ μ¦μ λ°κ³ , μνΈμμ©μ μΈ ν₯μ κΈ°λ₯μ μ μ§μ μΌλ‘ λ‘λ©λ¨μ μλ―Έν©λλ€. μ΄λ μ μΈκ³μ μΌλ‘ μ¬μ©μ κ²½νκ³Ό SEO μμλ₯Ό ν₯μμν΅λλ€.
μν°νλΌμ΄μ¦κΈ μμ€ν μ μν κ³ κΈ κ³ λ €μ¬ν
μ»΄ν¬λνΈ κ° μν κ΄λ¦¬
ν΅μ μ μν κΈ°λ³Έ ν¨ν΄μ 'μμ±μ μλλ‘, μ΄λ²€νΈλ μλ‘(properties down, events up)'μ λλ€. λΆλͺ¨ μμλ μμ±/νλ‘νΌν°λ₯Ό ν΅ν΄ μμμκ² λ°μ΄ν°λ₯Ό μ λ¬νκ³ , μμμ 컀μ€ν μ΄λ²€νΈλ₯Ό λ°μμμΌ λΆλͺ¨μκ² λ³κ²½ μ¬νμ μ립λλ€. μ¬μ©μ μΈμ¦ μνλ μ₯λ°κ΅¬λ λ°μ΄ν°μ κ°μ΄ λ 볡μ‘νκ³ μ¬λ¬ μ»΄ν¬λνΈμ κ±ΈμΉ μνμ κ²½μ°, λͺ κ°μ§ μ λ΅μ μ¬μ©ν μ μμ΅λλ€.
- μ΄λ²€νΈ λ²μ€: μ¬λ¬ κ΄λ ¨ μλ μ»΄ν¬λνΈλ€μ΄ μμ ν΄μΌ νλ λ©μμ§λ₯Ό λΈλ‘λμΊμ€ν νλ λ° κ°λ¨ν μ μ μ΄λ²€νΈ λ²μ€λ₯Ό μ¬μ©ν μ μμ΅λλ€.
- μΈλΆ μ€ν μ΄: Redux, MobX, Zustandμ κ°μ κ²½λ μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬λ₯Ό ν΅ν©ν μ μμ΅λλ€. μ€ν μ΄λ μ»΄ν¬λνΈ μΈλΆμ μ‘΄μ¬νλ©°, μ»΄ν¬λνΈλ€μ μ€ν μ΄μ μ°κ²°νμ¬ μνλ₯Ό μ½κ³ μ‘μ μ λμ€ν¨μΉν©λλ€.
- 컨ν μ€νΈ μ 곡μ ν¨ν΄: 컨ν μ΄λ μΉ μ»΄ν¬λνΈκ° μνλ₯Ό 보μ νκ³ μμ±μ ν΅ν΄ λͺ¨λ νμ μ»΄ν¬λνΈμ μ λ¬νκ±°λ, μμλ€μ΄ μΊ‘μ²νλ μ΄λ²€νΈλ₯Ό λμ€ν¨μΉνμ¬ μ λ¬ν μ μμ΅λλ€.
λκ·λͺ¨ μ€νμΌλ§ λ° ν λ§ μ μ©
μΊ‘μνλ μΉ μ»΄ν¬λνΈμ ν λ§λ₯Ό μ μ©νλ ν΅μ¬μ CSS 컀μ€ν μμ±μ λλ€. λ³μλ₯Ό μ¬μ©νμ¬ μ»΄ν¬λνΈμ λν κ³΅κ° μ€νμΌλ§ APIλ₯Ό μ μν©λλ€.
μλ₯Ό λ€μ΄, λ²νΌ μ»΄ν¬λνΈμ λ΄λΆ CSSλ λ€μκ³Ό κ°μ μ μμ΅λλ€:
.button { background-color: var(--button-primary-bg, blue); color: var(--button-primary-color, white); }
λΆλͺ¨ μμλ :rootμ μ΄λ¬ν λ³μλ₯Ό μ μν¨μΌλ‘μ¨ μ ν리μΌμ΄μ
μ μ½κ² λ€ν¬ ν
λ§λ₯Ό λ§λ€ μ μμ΅λλ€:
.dark-theme { --button-primary-bg: #333; --button-primary-color: #eee; }
λ κ³ κΈ μ€νμΌλ§μ μν΄ ::part() μμ¬(pseudo) μ리먼νΈλ₯Ό μ¬μ©νλ©΄ μ»΄ν¬λνΈμ μλ DOM λ΄μμ 미리 μ μλ νΉμ ννΈλ₯Ό νκ²ν
ν μ μμ΄, μλΉμμκ² λ λ§μ μ€νμΌλ§ μ μ΄κΆμ μμ νκ³ λͺ
μμ μΌλ‘ λΆμ¬ν μ μμ΅λλ€.
νΌκ³Ό μ κ·Όμ±(A11y)
컀μ€ν
μ»΄ν¬λνΈκ° λ€μν μꡬλ₯Ό κ°μ§ μ μΈκ³ μ¬μ©μμκ² μ κ·Ό κ°λ₯νλλ‘ λ³΄μ₯νλ κ²μ ννν μ μλ λ¬Έμ μ
λλ€. μ΄λ ARIA(Accessible Rich Internet Applications) μμ±μ μΈμ¬ν μ£Όμλ₯Ό κΈ°μΈμ΄κ³ , ν¬μ»€μ€λ₯Ό κ΄λ¦¬νλ©°, μμ ν ν€λ³΄λ νμμ 보μ₯νλ κ²μ μλ―Έν©λλ€. 컀μ€ν
νΌ μ»¨νΈλ‘€μ κ²½μ°, ElementInternals κ°μ²΄λ 컀μ€ν
μ리먼νΈκ° λ€μ΄ν°λΈ <input> μ리먼νΈμ²λΌ νΌ μ μΆ λ° μ ν¨μ± κ²μ¬μ μ°Έμ¬ν μ μκ² ν΄μ£Όλ μλ‘μ΄ APIμ
λλ€.
μ€μ©μ μΈ μ¬λ‘ μ°κ΅¬: νμ₯ κ°λ₯ν μ ν μΉ΄λ λ§λ€κΈ°
μ΄ κ°λ
λ€μ μ μ©νμ¬ Litμ μ¬μ©ν΄ νλ μμν¬ λ
립μ μΈ <product-card> μ»΄ν¬λνΈλ₯Ό μ€κ³ν΄ λ³΄κ² μ΅λλ€.
1λ¨κ³: μ»΄ν¬λνΈμ API μ μ (Props & Events)
μ°λ¦¬ μ»΄ν¬λνΈλ λ°μ΄ν°λ₯Ό λ°μλ€μ΄κ³ μ¬μ©μ νλμ μ ν리μΌμ΄μ μ μλ €μΌ ν©λλ€.
- μμ± (μ
λ ₯):
productName(λ¬Έμμ΄),price(μ«μ),currencySymbol(λ¬Έμμ΄, μ: "$", "β¬", "Β₯"),imageUrl(λ¬Έμμ΄). - μ΄λ²€νΈ (μΆλ ₯):
addToCart(μ ν μμΈ μ 보μ ν¨κ» λ²λΈλ§λλ CustomEvent).
2λ¨κ³: μ¬λ‘―μΌλ‘ HTML ꡬ쑰ννκΈ°
μλΉμκ° "μΈμΌ μ€" λλ "μ μν"κ³Ό κ°μ 컀μ€ν
λ°°μ§λ₯Ό μΆκ°ν μ μλλ‘ μ¬λ‘―μ μ¬μ©ν κ²μ
λλ€.
${this.currencySymbol}${this.price}
<div class="card">
<img src="${this.imageUrl}" alt="${this.productName}">
<div class="badge"><slot name="badge"></slot></div>
${this.productName}
3λ¨κ³: λ‘μ§ λ° ν λ§ κ΅¬ν
Lit μ»΄ν¬λνΈ ν΄λμ€λ μμ±κ³Ό _handleAddToCart λ©μλλ₯Ό μ μνλ©°, μ΄ λ©μλλ 컀μ€ν
μ΄λ²€νΈλ₯Ό λμ€ν¨μΉν©λλ€. CSSλ ν
λ§ μ μ©μ μν΄ μ»€μ€ν
μμ±μ μ¬μ©ν©λλ€.
CSS μμ:
:host {
--card-background: #fff;
--card-border-color: #ddd;
--card-primary-font-color: #333;
}
.card {
background-color: var(--card-background);
border: 1px solid var(--card-border-color);
color: var(--card-primary-font-color);
}
4λ¨κ³: μ»΄ν¬λνΈ μ¬μ©νκΈ°
μ΄μ μ΄ μ»΄ν¬λνΈλ μ΄λμμλ μ¬μ©ν μ μμ΅λλ€.
μμ HTMLμμ:
<product-card
product-name="κΈλ‘λ² μ€λ§νΈμμΉ"
price="199"
currency-symbol="$"
image-url="/path/to/image.jpg">
<span slot="badge">λ² μ€νΈμ
λ¬</span>
</product-card>
React μ»΄ν¬λνΈμμ:
function ProductDisplay({ product }) {
const handleAddToCart = (e) => console.log('μ₯λ°κ΅¬λμ μΆκ°λ¨:', e.detail);
return (
<product-card
productName={product.name}
price={product.price}
currencySymbol={product.currency}
imageUrl={product.image}
onAddToCart={handleAddToCart}
>
<span slot="badge">λ² μ€νΈμ
λ¬</span>
</product-card>
);
}
(μ°Έκ³ : React ν΅ν©μ μ’
μ’
μμ λνΌκ° νμνκ±°λ, νλ μμν¬λ³ κ³ λ €μ¬νμ λν΄ Custom Elements Everywhereμ κ°μ μλ£λ₯Ό νμΈν΄μΌ ν©λλ€.)
λ―Έλλ νμ€νλμ΄ μμ΅λλ€
μΉ μ»΄ν¬λνΈ κΈ°λ° μν€ν μ²λ₯Ό μ±ννλ κ²μ νλ‘ νΈμλ μνκ³μ μ₯κΈ°μ μΈ κ±΄μ μ±κ³Ό νμ₯μ±μ λν μ λ΅μ ν¬μμ λλ€. μ΄λ Reactλ Angularμ κ°μ νλ μμν¬λ₯Ό λ체νλ κ²μ΄ μλλΌ, μμ μ μ΄κ³ μνΈμ΄μ© κ°λ₯ν κΈ°λ°μΌλ‘ κ·Έκ²λ€μ 보κ°νλ κ²μ λλ€. ν΅μ¬ λμμΈ μμ€ν μ ꡬμΆνκ³ λ§μ΄ν¬λ‘ νλ‘ νΈμλμ κ°μ ν¨ν΄μ νμ€ κΈ°λ° μ»΄ν¬λνΈλ‘ ꡬνν¨μΌλ‘μ¨, νλ μμν¬ μ’ μμμ λ²μ΄λκ³ , μ μΈκ³μ λΆμ°λ νλ€μ΄ λ ν¨μ¨μ μΌλ‘ μμ ν μ μλλ‘ κΆνμ λΆμ¬νλ©°, λ―Έλμ λΆκ°νΌν λ³νμ νλ ₯μ μΈ κΈ°μ μ€νμ ꡬμΆν μ μμ΅λλ€.
μ§κΈμ΄ λ°λ‘ νλ«νΌ μμμ ꡬμΆμ μμν λμ λλ€. λꡬλ μ±μνκ³ , λΈλΌμ°μ μ§μμ 보νΈμ μ΄λ©°, μ§μ μΌλ‘ νμ₯ κ°λ₯ν κΈλ‘λ² μ ν리μΌμ΄μ μ λ§λ€κΈ° μν μν€ν μ²μ μ΄μ μ λΆμΈν μ μμ΅λλ€.