Alpine.js 백패킹처럼 가벼운 프레임워크

Share

백패킹과 닮은 미니멀리즘 프레임워크, Alpine.js 탐험

최근 빅서로 백패킹을 다녀왔습니다. 며칠 지나지 않아 배낭 속 물건들을 보며 ‘이게 정말 필요한가?’라는 질문을 던지게 되었죠. 소프트웨어 개발도 마찬가지입니다. 시스템의 모든 요소는 복잡성을 더하므로, 그만한 가치를 제공해야 합니다. Alpine.js는 마치 백패킹 장비처럼, 미니멀리즘을 추구하는 개발자를 위한 리액티브 프레임워크입니다. 작은 크기에도 놀라운 기능을 제공하죠.

Alpine.js: 작지만 강력한 API

Alpine.js의 API는 단 15개의 속성, 6개의 속성, 2개의 메서드로 구성되어 있습니다. 이 작은 패키지로 반응성을 제공하고, 이벤트 처리, 스토어와 같은 유용한 기능까지 제공합니다. 간단한 웹 페이지를 예로 들어볼까요?

<html>
<head>
  <script src=&quot;https://unpkg.com/alpinejs@3.14.8/dist/cdn.min.js&quot; defer></script>
</head>
<body>
  <div x-data=&quot;&quot;>
    <span x-text=&quot;'Text literal'&quot;></span>
  </div>
</body>
</html>

CDN을 통해 Alpine.js를 포함하는 것 외에, x-datax-text 두 개의 속성만 사용했습니다. 브라우저에서 확인하면 "Text literal" 메시지를 볼 수 있습니다. 여기서 Alpine.js의 두 가지 중요한 특징을 알 수 있습니다.

첫째, 반응성이 작동하려면 마크업을 x-data 속성으로 감싸야 합니다. 이 속성을 제거하면 x-text가 작동하지 않습니다. 즉, x-data는 Alpine.js 컴포넌트를 생성합니다. 둘째, 유효한 JavaScript라면 무엇이든 x-text에 넣을 수 있습니다. 이는 모든 Alpine.js 속성에 해당됩니다. x-text 속성은 HTML(뷰)과 JavaScript(동작) 간의 연결고리를 제공합니다.

x-datax-text 활용

x-data의 내용은 해당 요소 내의 모든 요소에 제공됩니다. 다음 코드를 예시로 보겠습니다.

<div x-data=&quot;{ message: 'When in the course of human events...' }&quot;>
  <span x-text=&quot;message&quot;></span>
</div>

이제 페이지에 미국 독립 선언문의 시작 문장이 출력됩니다. x-data는 "message"라는 단일 필드를 가진 JavaScript 객체를 정의했고, x-text는 이 객체 필드를 참조합니다.

Alpine.js의 반응성

다음과 같이 반응성을 사용하여 문서의 오류를 수정할 수 있습니다.

<div x-data=&quot;{ noun: 'men' }&quot;>
  <button x-on:click=&quot;noun = 'people'&quot;>Fix It</button>
  <span x-text=&quot;`all ${noun} are created equal`&quot;></span>
</div>

x-text 속성은 x-data에 의해 노출된 noun 변수를 참조합니다. 새로운 부분은 x-on:click 속성이 있는 버튼입니다. 이 클릭 이벤트의 핸들러는 기존의 기본 noun("men")을 성별 중립적인 "people"로 대체합니다. 그러면 반응성에 따라 x-text에서 참조 업데이트가 처리됩니다. UI는 데이터의 변경 사항을 자동으로 반영합니다.

데이터의 함수

Alpine.js의 데이터 속성은 JavaScript 객체입니다. 위의 요구 사항을 처리하는 다른 방법을 살펴보겠습니다.

<div x-data=&quot;{ 
      noun: 'men', 
      fixIt: function(){
        this.noun = 'people';
      }
    }&quot;>
    <button x-on:click=&quot;fixIt()&quot;>Fix It</button>
    <span x-text=&quot;`all ${noun} are created equal`&quot;></span>
  </div>

이 예제에서는 data 객체가 이제 클릭 핸들러에 의해 호출되는 fixIt 메서드를 호스팅하는 것을 볼 수 있습니다. HTML에서 보고자 하는 동작에 가장 적합한 객체 구조를 만들 수 있습니다.

원격 데이터 가져오기

이번에는 외부 API에서 JSON 형식으로 된 미국 대통령 목록을 로드해야 하는 경우를 살펴보겠습니다. 가장 먼저 할 일은 페이지가 로드될 때 목록을 로드하는 것입니다. 이를 위해 x-init 속성을 사용합니다.

<div x-data=&quot;{
      presidents: []
    }&quot; 
    x-init=&quot;(
      async () => {
        const response = await fetch('https://raw.githubusercontent.com/hitch17/sample-data/master/presidents.json');
        presidents = await response.json();
      }
    )&quot;>
    <span x-text=&quot;presidents&quot;></span>
  </div>

x-data 속성은 빈 배열을 가진 presidents 필드를 가지고 있습니다. span 요소의 x-text는 이 필드의 내용을 출력합니다. x-init 코드는 자체 실행 함수로 래핑되어 있습니다. 이는 Alpine.js가 함수 정의가 아닌 함수를 기대하기 때문입니다. 엔드포인트에서 대통령 목록을 가져오고 나면 Alpine.js가 x-data 객체의 일부로 노출한 presidents 변수에 저장합니다.

Alpine.js로 반복

현재 앱은 원격 엔드포인트에서 데이터를 가져와 상태에 저장하지만 출력은 [Object],[Object]…와 같은 형태입니다. 이 문제를 해결하려면 먼저 데이터에 대한 반복을 살펴봐야 합니다.

<div x-data=&quot;...&quot;>
<ul>
      <template x-for=&quot;pres in presidents&quot;>
        <li><div x-text=&quot;pres.president&quot;></div>
          From: <span x-text=&quot;pres.took_office&quot;></span> Until: <span x-text=&quot;pres.left_office&quot;></span></li>
      </template>
    </ul>
</div>

위 코드는 순서 없는 목록과 x-for 속성이 포함된 HTML 템플릿 요소를 포함합니다. x-for는 컬렉션, 대통령, 식별자를 지정할 수 있고, 해당 컬렉션의 각 인스턴스(이 경우 대통령)를 나타내는 포함된 마크업에 제공됩니다. 나머지 마크업은 pres 변수를 사용해서 x-text를 통해 객체의 데이터를 출력합니다.

맺음말

Alpine.js는 마치 백패킹에 필요한 기본적인 장비와 같습니다. 최소한의 장비지만 충분히 제 역할을 해내죠. 중앙 스토어, 이벤트 처리 시스템, 플러그인 아키텍처와 같은 고급 기능도 포함되어 있습니다. 사용하기 편리하며, 다른 리액티브 프레임워크를 다룬 경험이 있다면 쉽게 익힐 수 있습니다. 간단한 코딩 작업에 Alpine.js를 적극적으로 활용해 보세요.

You may also like...