μΉ μ»΄ν¬λνΈλ₯Ό μν νμ λμμΈ ν¨ν΄μ μ΄ν΄λ³΄κ³ κ°λ ₯νκ³ μ¬μ¬μ© κ°λ₯νλ©° μ μ§ κ΄λ¦¬ κ°λ₯ν μ»΄ν¬λνΈ μν€ν μ²λ₯Ό λ§λλλ€. κΈλ‘λ² μΉ κ°λ°μ μν λͺ¨λ² μ¬λ‘λ₯Ό λ°°μ°μμμ€.
μΉ μ»΄ν¬λνΈ λμμΈ ν¨ν΄: μ¬μ¬μ© κ°λ₯ν μ»΄ν¬λνΈ μν€ν μ² κ΅¬μΆ
μΉ μ»΄ν¬λνΈλ μΉ μ ν리μΌμ΄μ λ° μΉ νμ΄μ§μμ μ¬μ©ν μ μλλ‘ μ¬μ¬μ© κ°λ₯νκ³ μΊ‘μνλ HTML μμλ₯Ό μμ±ν μ μλ κ°λ ₯ν μΉ νμ€ μΈνΈμ λλ€. μ΄λ λ€μν νλ‘μ νΈμ νλ«νΌμμ μ½λ μ¬μ¬μ©μ±, μ μ§ κ΄λ¦¬μ± λ° μΌκ΄μ±μ ν₯μμν΅λλ€. κ·Έλ¬λ μΉ μ»΄ν¬λνΈλ₯Ό μ¬μ©νλ κ²λ§μΌλ‘λ μ ꡬμ±λκ±°λ μ½κ² μ μ§ κ΄λ¦¬ν μ μλ μ ν리μΌμ΄μ μ΄ μλμΌλ‘ 보μ₯λμ§λ μμ΅λλ€. λ°λ‘ μ¬κΈ°μ λμμΈ ν¨ν΄μ΄ μ μ©λ©λλ€. ν립λ λμμΈ μμΉμ μ μ©νμ¬ κ°λ ₯νκ³ νμ₯ κ°λ₯ν μ»΄ν¬λνΈ μν€ν μ²λ₯Ό ꡬμΆν μ μμ΅λλ€.
μΉ μ»΄ν¬λνΈλ₯Ό μ¬μ©νλ μ΄μ ?
λμμΈ ν¨ν΄μ λν΄ μμΈν μμ보기 μ μ μΉ μ»΄ν¬λνΈμ μ£Όμ μ΄μ μ κ°λ΅νκ² μμ½ν΄ λ³΄κ² μ΅λλ€.
- μ¬μ¬μ©μ±: μ¬μ©μ μ μ μμλ₯Ό ν λ² μμ±νκ³ μ΄λμμλ μ¬μ©ν©λλ€.
- μΊ‘μν: Shadow DOMμ μ€νμΌ λ° μ€ν¬λ¦½νΈ 격리λ₯Ό μ 곡νμ¬ νμ΄μ§μ λ€λ₯Έ λΆλΆκ³Όμ μΆ©λμ λ°©μ§ν©λλ€.
- μνΈ μ΄μ©μ±: μΉ μ»΄ν¬λνΈλ JavaScript νλ μμν¬ λλ λΌμ΄λΈλ¬λ¦¬ λλ νλ μμν¬ μμ΄λ μννκ² μλν©λλ€.
- μ μ§ κ΄λ¦¬μ±: μ μ μλ μ»΄ν¬λνΈλ μ΄ν΄, ν μ€νΈ λ° μ λ°μ΄νΈκ° λ μ½μ΅λλ€.
ν΅μ¬ μΉ μ»΄ν¬λνΈ κΈ°μ
μΉ μ»΄ν¬λνΈλ μΈ κ°μ§ ν΅μ¬ κΈ°μ μ κΈ°λ°μΌλ‘ ꡬμΆλ©λλ€.
- μ¬μ©μ μ μ μμ: μμ λ§μ HTML μμμ κ·Έ λμμ μ μν μ μλ JavaScript APIμ λλ€.
- Shadow DOM: μ»΄ν¬λνΈμ λν λ³λμ DOM νΈλ¦¬λ₯Ό μμ±νμ¬ μ μ DOM λ° ν΄λΉ μ€νμΌλ‘λΆν° 보νΈν¨μΌλ‘μ¨ μΊ‘μνλ₯Ό μ 곡ν©λλ€.
- HTML ν
νλ¦Ώ:
<template>
λ°<slot>
μμλ₯Ό μ¬μ©νλ©΄ μ¬μ¬μ© κ°λ₯ν HTML ꡬ쑰μ μ리 νμμ μ½ν μΈ λ₯Ό μ μν μ μμ΅λλ€.
μΉ μ»΄ν¬λνΈλ₯Ό μν νμ λμμΈ ν¨ν΄
λ€μ λμμΈ ν¨ν΄μ λ³΄λ€ ν¨κ³Όμ μ΄κ³ μ μ§ κ΄λ¦¬ κ°λ₯ν μΉ μ»΄ν¬λνΈ μν€ν μ²λ₯Ό ꡬμΆνλ λ° λμμ΄ λ μ μμ΅λλ€.
1. μμλ³΄λ€ κ΅¬μ±
μ€λͺ : μμ κ³μΈ΅μ μμ‘΄ν기보λ€λ λ μκ³ νΉνλ μ»΄ν¬λνΈμμ μ»΄ν¬λνΈλ₯Ό ꡬμ±νλ κ²μ μ νΈν©λλ€. μμμ κΈ΄λ°νκ² κ²°ν©λ μ»΄ν¬λνΈμ κΉ¨μ§κΈ° μ¬μ΄ κΈ°λ³Έ ν΄λμ€ λ¬Έμ λ‘ μ΄μ΄μ§ μ μμ΅λλ€. ꡬμ±μ λμ¨ν κ²°ν©κ³Ό λ ν° μ μ°μ±μ μ΄μ§ν©λλ€.
μ: <base-button>
μμ μμλλ <special-button>
μ λ§λλ λμ <base-button>
μ ν¬ν¨νκ³ νΉμ μ€νμΌ λλ κΈ°λ₯μ μΆκ°νλ <special-button>
μ λ§λλλ€.
ꡬν: μ¬λ‘―μ μ¬μ©νμ¬ μ½ν μΈ μ λ΄λΆ μ»΄ν¬λνΈλ₯Ό μΉ μ»΄ν¬λνΈλ‘ ν¬μ¬ν©λλ€. μ΄λ₯Ό ν΅ν΄ λ΄λΆ λ Όλ¦¬λ₯Ό μμ νμ§ μκ³ λ μ»΄ν¬λνΈμ ꡬ쑰μ μ½ν μΈ λ₯Ό μ¬μ©μ μ μν μ μμ΅λλ€.
<my-composite-component>
<p slot="header">Header Content</p>
<p>Main Content</p>
</my-composite-component>
2. Observer ν¨ν΄
μ€λͺ : κ°μ²΄ κ°μ μΌλλ€ μ’ μμ±μ μ μνμ¬ ν κ°μ²΄μ μνκ° λ³κ²½λλ©΄ λͺ¨λ μ’ μ κ°μ²΄κ° μλμΌλ‘ ν΅μ§λκ³ μ λ°μ΄νΈλ©λλ€. μ΄λ μ»΄ν¬λνΈ κ°μ λ°μ΄ν° λ°μΈλ© λ° ν΅μ μ μ²λ¦¬νλ λ° μ€μν©λλ€.
μ: <data-source>
μ»΄ν¬λνΈλ κΈ°λ³Έ λ°μ΄ν°κ° λ³κ²½λ λλ§λ€ <data-display>
μ»΄ν¬λνΈμ μ릴 μ μμ΅λλ€.
ꡬν: μ¬μ©μ μ μ μ΄λ²€νΈλ₯Ό μ¬μ©νμ¬ λμ¨νκ² κ²°ν©λ μ»΄ν¬λνΈ κ°μ μ
λ°μ΄νΈλ₯Ό νΈλ¦¬κ±°ν©λλ€. <data-source>
λ λ°μ΄ν°κ° λ³κ²½λλ©΄ μ¬μ©μ μ μ μ΄λ²€νΈλ₯Ό λμ€ν¨μΉνκ³ <data-display>
λ μ΄ μ΄λ²€νΈλ₯Ό μμ νμ¬ λ·°λ₯Ό μ
λ°μ΄νΈν©λλ€. 볡μ‘ν ν΅μ μλ리μ€μλ μ€μ μ§μ€μ μ΄λ²€νΈ λ²μ€λ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
// data-source component
this.dispatchEvent(new CustomEvent('data-changed', { detail: this.data }));
// data-display component
connectedCallback() {
window.addEventListener('data-changed', (event) => {
this.data = event.detail;
this.render();
});
}
3. μν κ΄λ¦¬
μ€λͺ : μ»΄ν¬λνΈ λ° μ 체 μ ν리μΌμ΄μ μ μνλ₯Ό κ΄λ¦¬νκΈ° μν μ λ΅μ ꡬνν©λλ€. μ μ ν μν κ΄λ¦¬λ 볡μ‘νκ³ λ°μ΄ν° μ€μ¬μ μΈ μΉ μ ν리μΌμ΄μ μ ꡬμΆνλ λ° μ€μν©λλ€. 볡μ‘ν μ ν리μΌμ΄μ μλ λ°μν λΌμ΄λΈλ¬λ¦¬ λλ μ€μ μ§μ€μ μν μ μ₯μλ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€. λ μμ μ ν리μΌμ΄μ μ κ²½μ° μ»΄ν¬λνΈ μμ€ μνλ‘ μΆ©λΆν μ μμ΅λλ€.
μ: μΌν μΉ΄νΈ μ ν리μΌμ΄μ μ μΉ΄νΈμ νλͺ©, μ¬μ©μμ λ‘κ·ΈμΈ μν λ° λ°°μ‘ μ£Όμλ₯Ό κ΄λ¦¬ν΄μΌ ν©λλ€. μ΄ λ°μ΄ν°λ μ¬λ¬ μ»΄ν¬λνΈμμ μ‘μΈμ€ κ°λ₯νκ³ μΌκ΄μ±μ΄ μμ΄μΌ ν©λλ€.
ꡬν: λͺ κ°μ§ μ κ·Ό λ°©μμ΄ κ°λ₯ν©λλ€.
- μ»΄ν¬λνΈ λ‘컬 μν: μμ± λ° νΉμ±μ μ¬μ©νμ¬ μ»΄ν¬λνΈλ³ μνλ₯Ό μ μ₯ν©λλ€.
- μ€μ μ§μ€μ μν μ μ₯μ: Redux λλ Vuex(λλ μ΄μ μ μ¬ν λΌμ΄λΈλ¬λ¦¬)μ κ°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ μ ν리μΌμ΄μ μ 체 μνλ₯Ό κ΄λ¦¬ν©λλ€. μ΄λ 볡μ‘ν μν μ’ μμ±μ΄ μλ λ ν° μ ν리μΌμ΄μ μ μ μ©ν©λλ€.
- λ°μν λΌμ΄λΈλ¬λ¦¬: κΈ°λ³Έ μ 곡 λ°μμ±μ μ 곡νμ¬ μν κ΄λ¦¬λ₯Ό λ μ½κ² λ§λλ LitElement λλ Svelteμ κ°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό ν΅ν©ν©λλ€.
// Using LitElement
import { LitElement, html, property } from 'lit-element';
class MyComponent extends LitElement {
@property({ type: String }) message = 'Hello, world!';
render() {
return html`<p>${this.message}</p>`;
}
}
customElements.define('my-component', MyComponent);
4. Facade ν¨ν΄
μ€λͺ : 볡μ‘ν μλΈ μμ€ν μ λν λ¨μνλ μΈν°νμ΄μ€λ₯Ό μ 곡ν©λλ€. μ΄λ ν΄λΌμ΄μΈνΈ μ½λλ₯Ό κΈ°λ³Έ ꡬνμ 볡μ‘μ±μΌλ‘λΆν° 보νΈνκ³ μ»΄ν¬λνΈλ₯Ό λ μ½κ² μ¬μ©ν μ μλλ‘ ν©λλ€.
μ: <data-grid>
μ»΄ν¬λνΈλ λ΄λΆμ μΌλ‘ 볡μ‘ν λ°μ΄ν° κ°μ Έμ€κΈ°, νν°λ§ λ° μ λ ¬μ μ²λ¦¬ν μ μμ΅λλ€. Facade ν¨ν΄μ ν΄λΌμ΄μΈνΈκ° κΈ°λ³Έ ꡬν μΈλΆ μ 보λ₯Ό μ΄ν΄ν νμ μμ΄ μμ± λλ μμ±μ ν΅ν΄ μ΄λ¬ν κΈ°λ₯μ ꡬμ±ν μ μλ κ°λ¨ν APIλ₯Ό μ 곡ν©λλ€.
ꡬν: κΈ°λ³Έ 볡μ‘μ±μ μΊ‘μννλ μ μ μλ μμ± λ° λ©μλ μΈνΈλ₯Ό λ
ΈμΆν©λλ€. μλ₯Ό λ€μ΄ μ¬μ©μκ° λ°μ΄ν° 그리λμ λ΄λΆ λ°μ΄ν° ꡬ쑰λ₯Ό μ§μ μ‘°μνλλ‘ μꡬνλ λμ setData()
, filterData()
λ° sortData()
μ κ°μ λ©μλλ₯Ό μ 곡ν©λλ€.
// data-grid component
<data-grid data-url="/api/data" filter="active" sort-by="name"></data-grid>
// Internally, the component handles fetching, filtering, and sorting based on the attributes.
5. Adapter ν¨ν΄
μ€λͺ : ν΄λμ€μ μΈν°νμ΄μ€λ₯Ό ν΄λΌμ΄μΈνΈκ° μμνλ λ€λ₯Έ μΈν°νμ΄μ€λ‘ λ³νν©λλ€. μ΄ ν¨ν΄μ APIκ° λ€λ₯Έ κΈ°μ‘΄ JavaScript λΌμ΄λΈλ¬λ¦¬ λλ νλ μμν¬μ μΉ μ»΄ν¬λνΈλ₯Ό ν΅ν©νλ λ° μ μ©ν©λλ€.
μ: νΉμ νμμΌλ‘ λ°μ΄ν°λ₯Ό μμνλ λ κ±°μ μ°¨νΈ λΌμ΄λΈλ¬λ¦¬κ° μμ μ μμ΅λλ€. μΌλ° λ°μ΄ν° μμ€μ λ°μ΄ν°λ₯Ό μ°¨νΈ λΌμ΄λΈλ¬λ¦¬μμ μμνλ νμμΌλ‘ λ³ννλ μ΄λν° μ»΄ν¬λνΈλ₯Ό λ§λ€ μ μμ΅λλ€.
ꡬν: μΌλ° νμμΌλ‘ λ°μ΄ν°λ₯Ό μμ νκ³ λ κ±°μ λΌμ΄λΈλ¬λ¦¬μ νμν νμμΌλ‘ λ³ννλ λνΌ μ»΄ν¬λνΈλ₯Ό λ§λλλ€. κ·Έλ° λ€μ μ΄ μ΄λν° μ»΄ν¬λνΈλ λ κ±°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ μ°¨νΈλ₯Ό λ λλ§ν©λλ€.
// Adapter component
class ChartAdapter extends HTMLElement {
connectedCallback() {
const data = this.getData(); // Get data from a data source
const adaptedData = this.adaptData(data); // Transform data to the required format
this.renderChart(adaptedData); // Use the legacy charting library to render the chart
}
adaptData(data) {
// Transformation logic here
return transformedData;
}
}
6. Strategy ν¨ν΄
μ€λͺ : μκ³ λ¦¬μ¦ ν¨λ°λ¦¬λ₯Ό μ μνκ³ κ° μκ³ λ¦¬μ¦μ μΊ‘μννκ³ μλ‘ κ΅ν κ°λ₯νκ² λ§λλλ€. Strategyλ₯Ό μ¬μ©νλ©΄ μκ³ λ¦¬μ¦μ΄ μΈλΆ μμ λλ μ¬μ©μ κΈ°λ³Έ μ€μ μ λ°λΌ μκ³ λ¦¬μ¦μ μ¬μ©νλ ν΄λΌμ΄μΈνΈμ λ 립μ μΌλ‘ λ¬λΌμ§ μ μμ΅λλ€. μ΄λ μ»΄ν¬λνΈκ° μΈλΆ μμ λλ μ¬μ©μ κΈ°λ³Έ μ€μ μ λ°λΌ μλ‘ λ€λ₯Έ λ°©μμΌλ‘ λμΌν μμ μ μνν΄μΌ νλ κ²½μ°μ μ μ©ν©λλ€.
μ: <data-formatter>
μ»΄ν¬λνΈλ λ‘μΌμΌμ κΈ°μ€μΌλ‘ λ°μ΄ν°λ₯Ό λ€λ₯Έ λ°©μμΌλ‘ ν¬λ§·ν΄μΌ ν μ μμ΅λλ€(μ: λ μ§ νμ, ν΅ν κΈ°νΈ). Strategy ν¨ν΄μ μ¬μ©νλ©΄ λ³λμ ν¬λ§· μ λ΅μ μ μνκ³ λμ μΌλ‘ μ νν μ μμ΅λλ€.
ꡬν: ν¬λ§· μ λ΅μ λν μΈν°νμ΄μ€λ₯Ό μ μν©λλ€. κ° ν¬λ§· μ λ΅μ λν μ΄ μΈν°νμ΄μ€μ ꡬ체μ μΈ κ΅¬νμ λ§λλλ€(μ: DateFormattingStrategy
, CurrencyFormattingStrategy
). <data-formatter>
μ»΄ν¬λνΈλ μ λ΅μ μ
λ ₯μΌλ‘ μ¬μ©νκ³ μ΄λ₯Ό μ¬μ©νμ¬ λ°μ΄ν°λ₯Ό ν¬λ§·ν©λλ€.
// Strategy interface
class FormattingStrategy {
format(data) {
throw new Error('Method not implemented');
}
}
// Concrete strategy
class CurrencyFormattingStrategy extends FormattingStrategy {
format(data) {
return new Intl.NumberFormat(this.locale, { style: 'currency', currency: this.currency }).format(data);
}
}
// data-formatter component
class DataFormatter extends HTMLElement {
set strategy(strategy) {
this._strategy = strategy;
this.render();
}
render() {
const formattedData = this._strategy.format(this.data);
// ...
}
}
7. Publish-Subscribe (PubSub) ν¨ν΄
μ€λͺ : κ°μ²΄ κ°μ μΌλλ€ μ’ μμ±μ Observer ν¨ν΄κ³Ό μ μ¬νκ² μ μνμ§λ§ κ²°ν©μ΄ λ λμ¨ν©λλ€. κ²μμ(μ΄λ²€νΈλ₯Ό λ°©μΆνλ μ»΄ν¬λνΈ)λ ꡬλ μ(μ΄λ²€νΈλ₯Ό μμ νλ μ»΄ν¬λνΈ)μ λν΄ μ νμκ° μμ΅λλ€. μ΄λ λͺ¨λμ±μ μ΄μ§νκ³ μ»΄ν¬λνΈ κ°μ μ’ μμ±μ μ€μ λλ€.
μ: μ¬μ©μκ° μ±κ³΅μ μΌλ‘ λ‘κ·ΈμΈνλ©΄ <user-login>
μ»΄ν¬λνΈμμ "user-logged-in" μ΄λ²€νΈλ₯Ό κ²μν μ μμ΅λλ€. <profile-display>
μ»΄ν¬λνΈ λλ <notification-center>
μ»΄ν¬λνΈμ κ°μ μ¬λ¬ λ€λ₯Έ μ»΄ν¬λνΈκ° μ΄ μ΄λ²€νΈλ₯Ό ꡬλ
νκ³ κ·Έμ λ°λΌ UIλ₯Ό μ
λ°μ΄νΈν μ μμ΅λλ€.
ꡬν: μ€μ μ§μ€μ μ΄λ²€νΈ λ²μ€ λλ λ©μμ§ νλ₯Ό μ¬μ©νμ¬ μ΄λ²€νΈμ κ²μ λ° κ΅¬λ μ κ΄λ¦¬ν©λλ€. μΉ μ»΄ν¬λνΈλ μ¬μ©μ μ μ μ΄λ²€νΈλ₯Ό μ΄λ²€νΈ λ²μ€λ‘ λμ€ν¨μΉν μ μμΌλ©° λ€λ₯Έ μ»΄ν¬λνΈλ μ΄λ¬ν μ΄λ²€νΈλ₯Ό ꡬλ νμ¬ μλ¦Όμ λ°μ μ μμ΅λλ€.
// Event bus (simplified)
const eventBus = {
events: {},
subscribe: function(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
},
publish: function(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(data));
}
}
};
// user-login component
this.login().then(() => {
eventBus.publish('user-logged-in', { username: this.username });
});
// profile-display component
connectedCallback() {
eventBus.subscribe('user-logged-in', (userData) => {
this.displayProfile(userData);
});
}
8. Template Method ν¨ν΄
μ€λͺ : μμ μμ μκ³ λ¦¬μ¦μ 골격μ μ μνκ³ μΌλΆ λ¨κ³λ₯Ό μλΈ ν΄λμ€λ‘ μ°κΈ°ν©λλ€. Template Methodλ₯Ό μ¬μ©νλ©΄ μλΈ ν΄λμ€κ° μκ³ λ¦¬μ¦μ ꡬ쑰λ₯Ό λ³κ²½νμ§ μκ³ μκ³ λ¦¬μ¦μ νΉμ λ¨κ³λ₯Ό μ¬μ μν μ μμ΅λλ€. μ΄ ν¨ν΄μ μ½κ°μ λ³νμ΄ μλ μ μ¬ν μμ μ μννλ μ¬λ¬ μ»΄ν¬λνΈκ° μλ κ²½μ°μ ν¨κ³Όμ μ λλ€.
μ: λ°μ΄ν°λ₯Ό κ°μ Έμ€κ³ , ν¬λ§·ν λ€μ λ λλ§ν΄μΌ νλ μ¬λ¬ λ°μ΄ν° νμ μ»΄ν¬λνΈ(μ: <user-list>
, <product-list>
)κ° μλ€κ³ κ°μ ν©λλ€. μ΄ νλ‘μΈμ€μ κΈ°λ³Έ λ¨κ³(κ°μ Έμ€κΈ°, ν¬λ§·, λ λλ§)λ₯Ό μ μνμ§λ§ κ° λ¨κ³μ νΉμ ꡬνμ ꡬ체μ μΈ μλΈ ν΄λμ€μ λ§‘κΈ°λ μΆμ κΈ°λ³Έ μ»΄ν¬λνΈλ₯Ό λ§λ€ μ μμ΅λλ€.
ꡬν: κΈ°λ³Έ μκ³ λ¦¬μ¦μ ꡬννλ μΆμ κΈ°λ³Έ ν΄λμ€(λλ μΆμ λ©μλκ° μλ μ»΄ν¬λνΈ)λ₯Ό μ μν©λλ€. μΆμ λ©μλλ μλΈ ν΄λμ€μμ μ¬μ©μ μ μν΄μΌ νλ λ¨κ³λ₯Ό λνλ λλ€. μλΈ ν΄λμ€λ μ΄λ¬ν μΆμ λ©μλλ₯Ό ꡬννμ¬ νΉμ λμμ μ 곡ν©λλ€.
// Abstract base component
class AbstractDataList extends HTMLElement {
connectedCallback() {
this.data = this.fetchData();
this.formattedData = this.formatData(this.data);
this.renderData(this.formattedData);
}
fetchData() {
throw new Error('Method not implemented');
}
formatData(data) {
throw new Error('Method not implemented');
}
renderData(formattedData) {
throw new Error('Method not implemented');
}
}
// Concrete subclass
class UserList extends AbstractDataList {
fetchData() {
// Fetch user data from an API
return fetch('/api/users').then(response => response.json());
}
formatData(data) {
// Format user data
return data.map(user => `${user.name} (${user.email})`);
}
renderData(formattedData) {
// Render the formatted user data
this.innerHTML = `<ul>${formattedData.map(item => `<li>${item}</li>`).join('')}</ul>`;
}
}
μΉ μ»΄ν¬λνΈ μ€κ³λ₯Ό μν μΆκ° κ³ λ € μ¬ν
- μ κ·Όμ± (A11y): μ»΄ν¬λνΈκ° μ₯μ κ° μλ μ¬μ©μκ° μ‘μΈμ€ν μ μλλ‘ ν©λλ€. μλ§¨ν± HTML, ARIA μμ±μ μ¬μ©νκ³ ν€λ³΄λ νμμ μ 곡ν©λλ€.
- ν μ€νΈ: λ¨μ ν μ€νΈ λ° ν΅ν© ν μ€νΈλ₯Ό μμ±νμ¬ μ»΄ν¬λνΈμ κΈ°λ₯κ³Ό λμμ νμΈν©λλ€.
- μ€λͺ μ: μ»΄ν¬λνΈμ μμ±, μ΄λ²€νΈ λ° μ¬μ© μμ λ₯Ό ν¬ν¨νμ¬ μ»΄ν¬λνΈλ₯Ό λͺ ννκ² λ¬Έμνν©λλ€. Storybookκ³Ό κ°μ λꡬλ μ»΄ν¬λνΈ μ€λͺ μμ νμν©λλ€.
- μ±λ₯: DOM μ‘°μμ μ΅μννκ³ ν¨μ¨μ μΈ λ λλ§ κΈ°μ μ μ¬μ©νκ³ λ¦¬μμ€λ₯Ό μ§μ° λ‘λνμ¬ μ»΄ν¬λνΈμ μ±λ₯μ μ΅μ νν©λλ€.
- κ΅μ ν (i18n) λ° νμ§ν (l10n): μ¬λ¬ μΈμ΄μ μ§μμ μ§μνλλ‘ μ»΄ν¬λνΈλ₯Ό μ€κ³ν©λλ€. κ΅μ ν API (μ:
Intl
)λ₯Ό μ¬μ©νμ¬ λ€λ₯Έ λ‘μΌμΌμ λν΄ λ μ§, μ«μ λ° ν΅νλ₯Ό μ¬λ°λ₯΄κ² ν¬λ§·ν©λλ€.
μΉ μ»΄ν¬λνΈ μν€ν μ²: λ§μ΄ν¬λ‘ νλ‘ νΈμλ
μΉ μ»΄ν¬λνΈλ λ§μ΄ν¬λ‘ νλ‘ νΈμλ μν€ν μ²μμ μ€μν μν μ ν©λλ€. λ§μ΄ν¬λ‘ νλ‘ νΈμλλ νλ‘ νΈμλ μ±μ΄ λ μκ³ λ 립μ μΌλ‘ λ°°ν¬ κ°λ₯ν λ¨μλ‘ λΆν΄λλ μν€ν μ² μ€νμΌμ λλ€. μΉ μ»΄ν¬λνΈλ₯Ό μ¬μ©νμ¬ κ° λ§μ΄ν¬λ‘ νλ‘ νΈμλμ κΈ°λ₯μ μΊ‘μννκ³ λ ΈμΆνμ¬ λ ν° μ ν리μΌμ΄μ μ μννκ² ν΅ν©ν μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ νλ‘ νΈμλμ μ¬λ¬ λΆλΆμ λ 립μ μΌλ‘ κ°λ°, λ°°ν¬ λ° νμ₯ν μ μμ΅λλ€.
κ²°λ‘
μ΄λ¬ν λμμΈ ν¨ν΄κ³Ό λͺ¨λ² μ¬λ‘λ₯Ό μ μ©νλ©΄ μ¬μ¬μ© κ°λ₯νκ³ μ μ§ κ΄λ¦¬ κ°λ₯νλ©° νμ₯ κ°λ₯ν μΉ μ»΄ν¬λνΈλ₯Ό λ§λ€ μ μμ΅λλ€. μ΄λ μ νν JavaScript νλ μμν¬μ κ΄κ³μμ΄ λμ± κ°λ ₯νκ³ ν¨μ¨μ μΈ μΉ μ ν리μΌμ΄μ μΌλ‘ μ΄μ΄μ§λλ€. μ΄λ¬ν μμΉμ λ°λ₯΄λ©΄ λ λμ νμ , ν₯μλ μ½λ νμ§ λ° κΆκ·Ήμ μΌλ‘ κΈλ‘λ² μ²μ€μ μν λ λμ μ¬μ©μ κ²½νμ μ»μ μ μμ΅λλ€. μ€κ³ νλ‘μΈμ€ μ λ°μ κ±Έμ³ μ κ·Όμ±, κ΅μ ν λ° μ±λ₯μ κ³ λ €νλ κ²μ μμ§ λ§μμμ€.