# VanillaJSX.com 웹사이트 출시

> Clean Markdown view of GeekNews topic #16348. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=16348](https://news.hada.io/topic?id=16348)
- GeekNews Markdown: [https://news.hada.io/topic/16348.md](https://news.hada.io/topic/16348.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-08-17T12:34:17+09:00
- Updated: 2024-08-17T12:34:17+09:00
- Original source: [vanillajsx.com](https://vanillajsx.com/)
- Points: 3
- Comments: 1

## Topic Body

### 바닐라 JSX의 사례

#### JSX가 DOM 요소를 반환한다면?

- `ClickMe` 함수는 버튼을 생성하고 클릭 횟수를 표시하는 기능을 가짐
- 버튼을 클릭할 때마다 텍스트가 업데이트됨

```javascript
export default function ClickMe() {
  let i = 0;
  const el = &lt;button&gt;Click me&lt;/button&gt; as HTMLButtonElement;
  el.onclick = (e) => {
    el.textContent = `Clicked ${++i} times`;
  };
  return el;
}
```

#### 재사용 가능성

- `ClickMe` 컴포넌트를 여러 번 사용하여 각기 다른 상태를 유지할 수 있음

```javascript
import ClickMe from "./sample1.js";
export default () => <>
  &lt;p&gt;&lt;ClickMe /&gt;&lt;/p&gt;
  &lt;p&gt;&lt;ClickMe /&gt;&lt;/p&gt;
  &lt;p&gt;&lt;ClickMe /&gt;&lt;/p&gt;
</>;
```

#### 상호작용 DOM 트리 생성

- `TodoInput`과 `TodoList` 클래스를 사용하여 할 일 목록을 관리할 수 있음
- 항목을 추가하고 클릭하여 제거할 수 있음

```javascript
function TodoInput(attrs: { add: (v: string) => void }) {
  const input = &lt;input /&gt; as HTMLInputElement;
  input.placeholder = 'Add todo item...';
  input.onkeydown = (e) => {
    if (e.key === 'Enter') {
      attrs.add(input.value);
      input.value = '';
    }
  };
  return input;
}

class TodoList {
  ul = &lt;ul class='todolist' /&gt; as HTMLUListElement;
  add(v: string) {
    const item = &lt;li&gt;{v}&lt;/li&gt; as HTMLLIElement;
    item.onclick = () => item.remove();
    this.ul.append(item);
  }
}

export default () => {
  const list = new TodoList();
  list.add('foo');
  list.add('bar');
  return <>
    &lt;TodoInput add={(v) =&gt; list.add(v)} />
    {list.ul}
  </>;
};
```

#### 대량 데이터 처리

- `FindNames` 함수는 대량의 데이터를 처리하고 필터링하여 결과를 표시함
- 입력 값에 따라 실시간으로 일치하는 항목을 업데이트함

```javascript
import { data } from "../fetch-dataset.js";
export default function FindNames() {
  const status = &lt;p style='margin:1em 0' /&gt; as HTMLParagraphElement;
  const results = &lt;ul /&gt; as HTMLUListElement;
  const input = &lt;input value='eri(c|k)a?' autocomplete='new-password' oninput={updateMatches} /&gt; as HTMLInputElement;
  updateMatches();

  function updateMatches() {
    const matched = (data.entries().filter(([k]) => k.match(input.value)).toArray());
    const matches = (Iterator.from(matched).map(match => &lt;Item regex={input.value} match={match} /&gt;).take(30));
    results.replaceChildren(...matches);
    status.textContent = `${matched.length} / ${data.size}`;
  }

  return &lt;div class='sample4'&gt;
    {input}
    {status}
    {results}
  &lt;/div&gt;;
}

function Item(attrs: { match: [string, number], regex: string }) {
  const [name, count] = attrs.match;
  const total = &lt;small style='color:#fff3'&gt;({count})&lt;/small&gt;;
  return &lt;li&gt;
    &lt;span innerHTML={highlight(name, attrs.regex)} /&gt; {total}
  &lt;/li&gt;;
}

function highlight(str: string, regex: string) {
  if (!regex) return str;
  const r = new RegExp(`(${regex})`, 'gi');
  return str.replace(r, '&lt;span class="match"&gt;$1&lt;/span&gt;');
}
```

#### imlib의 소개

- `imlib`는 immaculatalibrary.com을 위해 개발된 라이브러리임
- minigamemaker.com과 현재 읽고 있는 웹사이트를 구축하는 데 사용됨
- 기존의 상태가 충분하지 않아 개발되었으며, 앱을 만드는 데 가장 선호하는 방법임

### GN⁺의 정리

- 이 글은 JSX를 사용하여 DOM 요소를 직접 생성하고 상호작용하는 방법을 설명함
- 기존의 가상 DOM을 사용하지 않고도 효율적으로 대량 데이터를 처리할 수 있는 방법을 제시함
- `imlib` 라이브러리는 간단하고 직관적인 방식으로 앱을 개발할 수 있게 해줌
- 비슷한 기능을 가진 다른 프로젝트로는 React, Vue.js 등이 있음

## Comments



### Comment 28068

- Author: neo
- Created: 2024-08-17T12:34:17+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=41269321) 
- 프로젝트에 관심을 가져줘서 고마움
  - 지난 10년간 SSGs 상태에 불만을 느껴 프로젝트를 시작함
  - 주로 정적 웹사이트를 만들며, 간단하고 직관적인 것을 원했음
  - JSX가 적합해 보였지만 React 같은 JSX 프레임워크의 복잡성에 지침
  - JSX를 문자열로 렌더링하는 SSG를 만들었고, 이를 브라우저에서 DOM 요소로 렌더링하도록 확장함
  - 일부 레이아웃에서는 공유 컴포넌트로 잘 작동함
  - SEO에도 잘 작동함
  - IDE 지원이 완벽하지 않음

- 실제 DOM 노드를 반환하면 JSX의 큰 장점이 사라짐
  - DOM의 설명을 반환해야 새로운 상태로 템플릿을 재평가하고 효율적으로 업데이트할 수 있음
  - 예제는 명령형 DOM API를 사용하여 업데이트함
  - VDOM의 주요 이점은 템플릿에서 항목을 반복하는 것임
  - VDOM의 문제는 느린 디핑(diffing)임

- JSX의 기원은 Facebook의 XHP에서 비롯됨
  - XHP는 E4X에서 영감을 받음

- 최종 예제가 Firefox에서 작동하지 않음
  - Edge에서는 작동하지만 Firefox에서는 오류 발생

- Vanilla TSX와 매우 유사함
  - Vanilla TSX로 작성된 앱 예제 제공

- Action Script 3을 떠올리게 함
  - XML이 언어의 핵심이었고, 재미있었지만 ES4가 되지 못함
  - Typescript와 JSX로 비슷한 수준에 도달하는 데 10년 이상 걸림

- 예제들은 시간이 지나면서 변경될 수 있는 props를 가진 컴포넌트를 보여주지 않음
  - 더 복잡한 앱으로 확장하는 데 어려움이 있을 것 같음

- 나도 실제 DOM 노드를 생성하는 jsx 템플릿 표현식을 기반으로 한 UI 라이브러리를 만듦
  - 모델 객체를 속성에 바인딩하여 명령형 이벤트 핸들러 보일러플레이트를 제거함
  - 좋은 아이디어라고 생각함

- JSX의 매력을 이해하지 못함
  - 루프, 변수 삽입 등을 자동으로 제공하는 다른 방법이 더 쉬움

- Imba를 추천함
  - JS 개발자들이 Faang 마케팅에 쉽게 넘어가서 인기가 없는 것 같음
