Svelte로 Toast Notification만들기

홍구
5 min readJan 4, 2020

svelte는 react나 vue와 다르게, 컴파일 단계에서 반응형 컴포넌트들을 순수 자바스크립트로 변환을 해준다. 따라서 기본적인 동작에 대한 코드 뭉치가 극도로 작아서 번들코드가 가볍게 생성되는 것이 장점이다(사실 더 매력적인 것은 개발시 컴포넌트의 보일러 플레이트가 거의 없다시피 한 것이다).

이 svelte를 이용하여 간단하게 Toast Notification 코드를 만들어보도록 하자. Toast는 간단해서 단일 컴포넌트로 내부 상태값을 활용하여 완성이 가능하다. 만들어보려는 컴포넌트의 모습은 아래와 같다.

데모 페이지

트랜지션 효과가 있는 알림을 만들어보자

프로젝트 생성

보통 svelte 프로젝트 시작 예시는 degit이라는 도구를 이용해서, rollup으로 세팅된 프로젝트로 다운받아 실행하는 방식이다. svelte 이외엔 아무런 의존성이 없으므로 간단하게 시험하는 목적이면 Svelte Repl을 이용해도 된다.

$ npx degit sveltejs/template svelte-toast
$ cd svelte-toast
$ npm i
$ npm run dev
시작된 모습
http://localhost:1234로 접속했을 때 기본 화면

Toast 컴포넌트 생성과 삽입

Toast.svelte 파일을 하나 생성하고 편집기로 오픈한다

$ cd src/components
$ touch Toast.svelte

먼저 더미로 구조와 스타일만 잡아본다. 두 개의 알림이 대충 하단 중앙에 적절한 크기와 간격으로 배치될 것이다.

어떻게 나오는지 보기 위하여 Hello.svelte 파일을 오픈하여 방금 생성한 Toast.svelte 를 배치한다.

처음으로 svelte 컴포넌트를 생성하고, 무사히 부모 컴포넌트에 삽입을 완료한 상태다.

메서드 생성

이제 더미로 생성된 것을 지워주고, 메서드에 의해서 생성되도록 해보자. svelte에서의 상태 모델은 할당에 의해서만 변화를 인지하는 구조다.

콘솔에서 동작을 시켜야 하므로, 전역 함수에 생성 메서드를 연결해준다(개인적으로 알림 등의 단순한 피드백용 UI 요소는 전역으로 생성하고 사용하는 것을 좋아한다)

콘솔창을 열어서 window.pushToast('알람 테스트') 라고 입력하면, 의도대로 하단에서 잘 나타나고, 3.5초 후에 잘 사라지는 것을 확인할 수 있다.

무뚝뚝하지만 심플하게 잘 반응한다

트랜지션 적용

보다 더 상업버전처럼 보이게하기 위하여 약간의 트랜지션을 추가해본다. svelte는 움직이는 효과를 주는 것이 꽤나 직관적이다.

간단하게 에니메이션 효과를 넣었다

콘솔로 테스트를 해보면 아주 간단하게 트랜지션 효과가 적용된 것을 볼 수 있다.

고유키 설정

그런데 가만 보면 뭔가 움직임이 이상하다(?). 가장 먼저 추가된 놈이 먼저 나가는 선입선출이 되어야 하는데, 반대로 마지막에 추가된 놈부터 지워지는 게 확인됐다. 소스에는 문제없이 선입선출로 되어지고 있다.

이것은 상태 모델의 문제가 아니라, 상태 모델에 따라 DOM을 조작할 때 매칭할 정보가 없어 생기는 현상이다. 현재 상태 모델에는 단순히 메시지만 담고 있고, 그 외에 알림을 구분할 수 있는 내부적인 힌트가 전혀 없는 상태다. 시간이 지나서 알림이 사라지면 배열상에서 없어지긴 하지만, 문자열 자체가 완전히 동일한 경우 어느놈이 어느놈인지 DOM은 구분을 못한다.

따라서 추가되는 메시지를 불변하는 고유키를 가지는 객체로 전환하고, svelte가 이 정보를 기반으로 매칭하도록 지정하면 해결된다.

고유키를 객체 형태로 만들었고, DOM에서는 _id를 기반으로 매칭하도록 svelte의 반복문에 적용하였다.

선입선출로 잘 사라진다

간단하게 svelte로 가져다 쓰기 좋은 형태의 Toast Notification을 만들어 보았다. 이 기본 상태에 프로젝트별로 필요한 상태 타입(단순 알림, 경고, 에러 등)별로 구분하고자 한다면 알림 객체에 넣고 활용하면 된다.

결론

svelte 너무 재밌다아~!

--

--

홍구

약간의 기술을 이용하여, 편리한 서비스와 기능을 만드는데 관심이 많음