최근 유명세가 높아지는 프레임워크로 알파인(Alpine.js)이 있다. 알파인이라는 이름이 암시하듯이 거친 지형을 가볍게 돌파하기 위한 미니멀리스트 프레임워크다. 군살 없고 쉽게 마스터가 가능한 패키지 안에 강력한 힘을 담고 있다. 이 기사에서는 알파인이 무엇을 제공하는지, 어떤 경우에 유용한지 간단히 살펴본다.
알파인의 미니멀리스트 API
알파인 문서에 따르면 알파인의 API는 15개 특성과 6개 속성, 2개 메서드의 모음이다. 아주 작은 API 프로파일이다. 간결한 형식으로 반응성을 제공하고, 이벤팅이나 중앙 저장소와 같은 부수적인 세부 기능을 통해 보강한다는 미니멀한 목적에 맞는 특성이다.예시 1의 아주 간단한 웹 페이지를 살펴보자.
예시 1. 알파인을 사용해 구축한 간단한 웹 페이지
<head>
<script onerror="removeImage($(this));" src="https://unpkg.com/alpinejs@3.10.3/dist/cdn.min.js" defer></script>
</head>
<body>
<div x-data="">
<span x-text="'Text literal'"></span>
</div>
</body>
</html>
CDN을 통해 알파인 패키지를 포함하는 것 외에(defer 의미 체계에 대해서는 여기서 자세히 알아볼 수 있음) 알파인과 관련된 두 가지는 x-data와 x-text 지시문이 전부다.
이 코드를 시스템의 HTML 페이지에 넣고 브라우저에서 보면 “Text literal”이라는 메시지 출력을 볼 수 있다. 거창하진 않지만 이 애플리케이션에서 알파인의 두 가지 흥미로운 면을 볼 수 있다.
첫째, 반응성이 작용하도록 하려면 x-data 지시문의 마크업을 둘러싸야 한다. 이 지시문을 제거하면 x-text는 아무 효력도 없다. 기본적으로 x-data 지시문은 알파인 구성요소를 생성한다. 이 예제에서 x-data 지시문은 비어 있지만, 지금 만들고 있는 구성요소의 목적이 애초에 데이터에 반응하는 것이므로 실제 환경이라면 대부분 그 자리에 데이터가 있을 것이다.
예시 1에서 주목할 두 번째 부분은 x-text 내에 유효한 아무 자바스크립트라도 넣을 수 있다는 점이다. 이것은 모든 알파인 지시문에서 마찬가지다.
x-data와 x-text 요소
x-data 내용은 포함된 모든 요소에 제공된다. 이해를 돕기 위해 예시 2를 보자.예시 2. x-data와 x-text 상호작용
<span x-text="message"></span>
</div>
이제 페이지는 미국 독립 선언서의 시작 부분을 출력한다. x-data는 선언서의 서문이 포함된 ‘message’라는 하나의 필드가 있는 일반적인 자바스크립트 객체를 정의하다. x-text는 이 객체 필드를 참조한다.
알파인의 반응성
다음으로, 반응성을 사용해서 선언서의 오류를 수정한다. 예시 3을 보자.예시 3. x-on:click과 반응성
<button x-on:click="pronoun = 'people'">Fix It</button>
<span x-text="`all ${pronoun} are created equal`"></span>
</div>
이제 x-text 지시문의 역할이 명확히 보일 것이다. x-data 지시문에 의해 노출된 pronoun 변수를 참조한다. 새로운 요소는 x-on:click 지시문이 있는 버튼이다. 이 클릭 이벤트의 핸들러가 이전의 기본 대명사를 성별 중립적인 대명사로 대체하면 반응성이 x-text의 참조 업데이트를 처리한다.
데이터의 함수
알파인의 데이터 속성은 완전한 자바스크립트 객체다. 위의 요구사항을 처리하는 또 다른 방법으로 예시 4를 보자.예시 4. 데이터 함수 사용
pronoun: 'men',
fixIt: function(){
this.pronoun = 'people'; }
}">
<button x-on:click="fixIt()">Fix It</button>
<span x-text="`all ${pronoun} are created equal`"></span>
</div>
예시 4에서는 데이터 객체가 이제 클릭 핸들러에 의해 호출되는 fixIt 메서드를 호스팅하는 것을 볼 수 있다.
참고로 x-data 지시문에서 스크립트 태그에 정의된 함수로 호출하는 애플리케이션을 종종 볼 수 있는데, 이것은 개인적인 기호의 문제일 뿐이고 동작은 인라인 x-data와 완전히 동일하다.
...
<script>
function myDataFunction() {
return {
foo: "bar"
}
}
</script>
원격 데이터 불러오기
수준을 높여 더 복잡한 요구사항에 대해 생각해 보자. 예를 들어 외부 API로부터 JSON 포맷의 미국 대통령 목록을 로드하려고 한다. 가장 먼저 할 일은 페이지가 로드될 때 이 목록을 로드하는 것이다. 예시 5와 같이 x-init 지시문을 사용한다.예시 5. x-init에서 데이터 미리 로드
presidents: []
}"
x-init="(
async () => {
const response = await fetch('https://raw.githubusercontent.com/hitch17/sample-data/master/presidents.json'); presidents = await response.json();
}
)">
<span x-text="presidents"></span>
</div>
여기서 무슨 일이 일어나고 있는가? 일단 x-data 지시문은 명료하다. 빈 배열이 포함된 president 필드가 있을 뿐이다. span 요소의 x-text는 이 필드의 내용을 출력한다.
x-init 코드는 약간 더 복잡하다. 먼저 자체 실행 함수로 래핑돼 있는데, 이는 알파인이 함수 정의가 아닌 함수를 기대하기 때문이다. (fetch의 비동기(non-asynchronous) 콜백 형식을 사용한다면 이처럼 함수를 래핑할 필요가 없다.)
엔드포인트에서 대통령 목록을 획득하면 알파인이 x-data 객체의 일부로 노출한 presidents 변수에 집어넣는다.
반복하자면, 알파인은 a-data의 데이터를 동일한 컨텍스트 내의 다른 지시문 함수(예를 들어 x-init)에서 사용할 수 있게 해준다.
알파인을 사용한 반복
현재 애플리케이션은 원격 엔드포인트에서 데이터를 가져와 상태에 저장하고 있다. 그러나 지금의 출력은 [Object],[Object]…와 같은 형태로, 우리가 원하는 것이 아니다. 예시 6에서 데이터를 반복 처리하는 부분을 살펴보자.예시 6. 알파인을 사용한 반복
<ul>
<template x-for="pres in presidents">
<li><div x-text="pres.president"></div>
From: <span x-text="pres.took_office"></span> Until: <span x-text="pres.left_office"></span></li>
</template>
</ul>
</div>
예시 6에는 정렬되지 않은 일반적인 목록이 포함되고 그 뒤에는 x-for 지시문이 포함된 HTML 템플릿 요소가 있다. 이 지시문의 동작은 여타 반응형 프레임워크에서 볼 수 있는 것과 비슷하다. 이 경우 presidents 컬렉션, 그리고 이 컬렉션의 각 인스턴스를 나타내는 마크업에 제공될 식별자를 지정할 수 있게 해준다(여기서는 pres).
마크업의 나머지 부분은 pres 변수를 사용해서 x-text를 통해 객체의 데이터를 출력한다.
이제 애플리케이션은 그림 1과 같은 형태가 된다.
그림 1. 미국 대통령 목록
표시/숨기기와 onClick
이제 대통령 이름을 클릭하면 대통령에 대한 데이터가 켜지고 꺼지도록 애플리케이션을 설정해 보자. 먼저 예시 7과 같이 마크업을 수정한다.
예시 7. 요소 표시/숨기기
<li><div x-text="pres.president" x-on:click="pres.show = ! pres.show"></div>
<div x-show="pres.show">
From: <span x-text="pres.took_office"></span> Until: <span x-text="pres.left_office"></span></li>
</div>
</template>
예시 7에서 대통령에 대한 세부 정보가 포함된 div에 x-show 지시문을 사용할 수 있다. x-show 값의 참/거짓에 따라 내용을 표시할지 여부가 결정된다. 예시에서는 pres.show 필드에 의해 결정된다. (실제 애플리케이션이라면 표시/숨기기 변수를 호스팅하는 데 실제 비즈니스 데이터를 사용하지는 않을 것이다.)
pres.show의 값을 변경하기 위해 헤더에 x-on:click 핸들러를 추가한다. 이 핸들러는 pres.show의 참/거짓 값을 바꾸는 역할만 한다(pres.show = ! pres.show).
전환 애니메이션 추가
알파인에는 표시/숨기기 기능에 적용할 수 있는 전환 효과가 기본 포함돼 있다. 예시 8은 기본 애니메이션을 추가하는 방법이다.예시 8. 표시/숨기기에 전환 추가
From: <span x-text="pres.took_office"></span> Until: <span x-text="pres.left_office"></span></li>
</div>
유일하게 바뀐 부분은 x-show 지시문이 포함된 요소에 이제 x-transition 지시문도 있다는 점이다. 기본적으로 알파인은 인지 가능한 전환을 적용한다. 이 예시에서 사용하는 전환은 슬라이드-페이드 효과다.
입력 바인딩
이제 간단한 필터 기능을 추가한다. 이를 위해서는 데이터에 바인딩하는 입력을 추가한 다음 반환된 데이터 집합을 그 값에 따라 필터링해야 한다. 예시 9에서 변경된 부분을 볼 수 있다.예시 9. 대통령 필터링
filter: '',
presidents: [],
getPresidents: function(){
return this.presidents.filter(pres => pres.president.includes(this.filter) )
}
}"
...
<input x-model="filter" />
...
<ul>
<template x-for="pres in getPresidents">
x-data 객체에는 이제 "filter" 필드가 있다. 이 필드는 “filter “를 가리키는 x-model 지시문을 통해 입력 요소에 양방향으로 바인딩된다.
x-data 객체에 구현된 새로운 getPresidents() 메서드를 참조하도록 템플릿 x-for 지시문을 변경했다. 이 메서드는 표준 자바스크립트 구문을 사용해서 필터 필드의 텍스트를 포함하는지 여부에 따라 대통령을 필터링한다.
이 데모의 전체 코드는 여기서 받을 수 있다.
결론
알파인은 이름처럼 산악 탐험을 위한 기본적인 장비만 넣은 가벼운 백팩이라고 할 수 있다. 최소한이지만 충분하다.프레임워크에는 중앙 저장소, 이벤팅 시스템과 같은 몇 가지 고수준 기능과, 플러그인 아키텍처 및 생태계가 포함된다.
전체적으로 알파인은 다루기가 편하다. 다른 반응형 프레임워크에 대한 경험이 있다면 알파인도 친숙하게 느끼고 금방 익힐 수 있다. x-data 지시문에 구성요소와 그 데이터를 선언하는 간편함이 특징이다.
구성요소 간 커뮤니케이션의 경우 구성요소 간의 명시적인 연결을 피하고(예를 들어 부모-자식 연결이 없음) 그 대신 $dispatch 지시문을 통해 브라우저 환경(창)을 이벤트 버스로 사용한다. 이는 이미 있는 것을 보강하는 수준의 기능만 추가한다는 알파인의 철학과도 부합하는 부분이며, 실제로 잘 작동한다.
애플리케이션의 크기와 복잡성이 커지게 되면 이러한 모든 요소가 시험대에 오르게 되지만 이것은 어느 스택을 선택하든 마찬가지다. 알파인은 다음 번 코딩 작업에서 선택할 만한 매력적인 옵션이다.
editor@itworld.co.kr
함께 보면 좋은 콘텐츠
Sponsored
Surfshark
“유료 VPN, 분명한 가치 있다” VPN 선택 가이드
ⓒ Surfshark VPN(가상 사설 네트워크, Virtual Private Network)은 인터넷 사용자에게 개인 정보 보호와 보안을 제공하는 중요한 도구로 널리 인정받고 있다. VPN은 공공 와이파이 환경에서도 데이터를 안전하게 전송할 수 있고, 개인 정보를 보호하는 데 도움을 준다. VPN 서비스의 수요가 증가하는 것도 같은 이유에서다. 동시에 유료와 무료 중 어떤 VPN을 선택해야 할지 많은 관심을 가지고 살펴보는 사용자가 많다. 가장 먼저 사용자의 관심을 끄는 것은 별도의 예산 부담이 없는 무료 VPN이지만, 그만큼의 한계도 있다. 무료 VPN, 정말 괜찮을까? 무료 VPN 서비스는 편리하고 경제적 부담도 없지만 고려할 점이 아예 없는 것은 아니다. 보안 우려 대부분의 무료 VPN 서비스는 유료 서비스에 비해 보안 수준이 낮을 수 있다. 일부 무료 VPN은 사용자 데이터를 수집해 광고주나 서드파티 업체에 판매하는 경우도 있다. 이러한 상황에서 개인 정보가 유출될 우려가 있다. 속도와 대역폭 제한 무료 VPN 서비스는 종종 속도와 대역폭에 제한을 생긴다. 따라서 사용자는 느린 인터넷 속도를 경험할 수 있으며, 높은 대역폭이 필요한 작업을 수행하는 데 제약을 받을 수 있다. 서비스 제한 무료 VPN 서비스는 종종 서버 위치가 적거나 특정 서비스 또는 웹사이트에 액세스하지 못하는 경우가 생긴다. 또한 사용자 수가 늘어나 서버 부하가 증가하면 서비스의 안정성이 저하될 수 있다. 광고 및 추적 위험 일부 무료 VPN은 광고를 삽입하거나 사용자의 온라인 활동을 추적하여 광고주에게 판매할 수 있다. 이 경우 사용자가 광고를 보아야 하거나 개인 정보를 노출해야 할 수도 있다. 제한된 기능 무료 VPN은 유료 버전에 비해 기능이 제한될 수 있다. 예를 들어, 특정 프로토콜이나 고급 보안 기능을 지원하지 않는 경우가 그렇다. 유료 VPN의 필요성 최근 유행하는 로맨스 스캠은 인터넷 사기의 일종으로, 온라인 데이트나 소셜 미디어를 통해 가짜 프로필을 만들어 상대를 속이는 행위다. 이러한 상황에서 VPN은 사용자가 안전한 연결을 유지하고 사기 행위를 방지하는 데 도움이 된다. VPN을 통해 사용자는 상대방의 신원을 확인하고 의심스러운 활동을 감지할 수 있다. 서프샤크 VPN은 구독 요금제 가입 후 7일간의 무료 체험을 제공하고 있다. ⓒ Surfshark 그 외에도 유료 VPN만의 강점을 적극 이용해야 하는 이유는 다음 3가지로 요약할 수 있다. 보안 강화 해외 여행객이 증가함에 따라 공공 와이파이를 사용하는 경우가 늘어나고 있다. 그러나 공공 와이파이는 보안이 취약해 개인 정보를 노출할 위험이 있다. 따라서 VPN을 사용하여 데이터를 암호화하고 개인 정보를 보호하는 것이 중요하다. 서프샤크 VPN은 사용자의 개인 정보를 안전하게 유지하고 해킹을 방지하는 데 유용하다. 개인정보 보호 인터넷 사용자의 검색 기록과 콘텐츠 소비 패턴은 플랫폼에 의해 추적될 수 있다. VPN을 사용하면 사용자의 IP 주소와 로그를 숨길 수 있으며, 개인 정보를 보호할 수 있다. 또한 VPN은 사용자의 위치를 숨기고 인터넷 활동을 익명으로 유지하는 데 도움이 된다. 지역 제한 해제 해외 여행 중에도 한국에서 송금이 필요한 경우가 생길 수 있다. 그러나 IP가 해외 주소이므로 은행 앱에 접근하는 것이 제한될 수 있다. VPN을 사용하면 지역 제한을 해제해 해외에서도 한국 인터넷 서비스를 이용할 수 있다. 따라서 해외에서도 안전하고 편리하게 인터넷을 이용할 수 있다. 빠르고 안전한 유료 VPN, 서프샤크 VPN ⓒ Surfshark 뛰어난 보안 서프샤크 VPN은 강력한 암호화 기술을 사용하여 사용자의 인터넷 연결을 안전하게 보호한다. 이는 사용자의 개인 정보와 데이터를 보호하고 외부 공격으로부터 사용자를 보호하는 데 도움이 된다. 다양한 서버 위치 서프샤크 VPN은 전 세계 곳곳에 여러 서버가 위치하고 있어, 사용자가 지역 제한된 콘텐츠에 액세스할 수 있다. 해외에서도 로컬 콘텐츠에 손쉽게 접근할 수 있음은 물론이다. 속도와 대역폭 서프샤크 VPN은 빠른 속도와 무제한 대역폭을 제공하여 사용자가 원활한 인터넷 경험을 누릴 수 있도록 지원한다. 온라인 게임, 스트리밍, 다운로드 등 대역폭이 필요한 활동에 이상적이다. 다양한 플랫폼 지원 서프샤크 VPN은 다양한 플랫폼 및 디바이스에서 사용할 수 있다. 윈도우, 맥OS, iOS, 안드로이드 등 다양한 운영체제 및 디바이스에서 호환되어 사용자가 어디서나 안전한 인터넷을 즐길 수 있다. 디바이스 무제한 연결 서프샤크 VPN은 무제한 연결을 제공하여 사용자가 필요할 때 언제든지 디바이스의 갯수에 상관없이 VPN을 사용할 수 있다.