개발자를 위한 친절한 UI 컴포넌트 라이브러리 만들기

notion imagenotion image
안녕하세요. LINE UIT 팀 프런트엔드 엔지니어 이상철입니다(GitHub ID: 1ilsang). 세션을 진행하기 전에 이 세션의 내용을 관통하는 질문을 하나 던지려고 합니다. 개발자 친화적이란 무엇일까요? 여러 가지 많은 요소가 있겠지만 저는 무엇보다도 개발자 경험 향상과 맞물려 있다고 생각합니다. 프런트엔드에서는 UI와 UX가 굉장히 중요한 요소입니다. 사용자가 서비스를 쉽고 편하게 사용하면서 좋은 경험을 하는 것이 매출과 직접 연관되는 중요한 포인트이기 때문입니다. 이와 마찬가지로 개발자를 위한 라이브러리를 개발하는 사람들은 라이브러리를 사용하는 서비스 개발자의 경험을 향상시키기 위해 노력해야 합니다. 이번 세션에서는 UI 컴포넌트 라이브러리를 만드는 메인테이너를 대상으로 개발자 경험과 문서화를 엮어 보다 친절한 라이브러리를 만들면서 문서화라는 귀찮은 작업을 효율적이고 의미 있는 작업으로 변신시킬 수 있는 방법을 공유하고자 합니다.
글은 다음과 같은 순서로 진행합니다. 먼저 세션 내용을 이해하기 위한 백그라운드를 살펴보고, 다음으로 기존 UI 라이브러리에 어떤 문제점이 있었는지 짚어본 뒤, 마지막으로 이와 같은 문제를 TypeScript와 Storybook을 이용해 어떻게 해결했는지 공유하겠습니다.

들어가며

먼저 UI 컴포넌트 라이브러리란 무엇일까요? UI 컴포넌트 라이브러리란, 프런트엔드에서 작동하는 다양한 컴포넌트를 묶어 직접 구현하지 않아도 바로 사용할 수 있도록 제공하는 라이브러리입니다. 주로 NPM이나 Yarn과 같은 패키지 매니저를 통해 다운로드해서 서비스에 적용합니다.
NPM 패키지를 분석해 보면, 2021년 11월 기준으로 약 1,750,000개의 패키지가 존재하고 매주 300억 번 이상의 다운로드가 발생하고 있습니다. 다수의 개발자가 프로젝트를 진행하면서 수많은 라이브러리에 의존하고 있다는 것을 알 수 있습니다. 개발자들이 많은 라이브러리에 의존한다는 것은 그만큼 많은 수의 문서를 찾아봐야 한다는 뜻이기도 합니다. 혹시라도 문서화가 제대로 돼 있지 않다면 해당 라이브러리를 사용하는 개발자는 무척이나 피곤해질 것입니다.
당연한 말이겠지만 대부분의 개발자는 직관적이고 친절한 UI 라이브러리를 원합니다. 물론 라이브러리를 제공하는 측에서도 나름 문서화를 진행해서 사용자에게 제공하고 있을 테지만, 개발 인력 부족과 촉박한 일정 등의 다양한 이유로 제대로 된 예시 페이지나 문서를 제공하는 것은 늘 쉽지 않은 일입니다. 그리고 무엇보다도, 많은 개발자에게 문서화는 재밌는 일이 아닙니다. 코드를 변경한 뒤 같은 내용으로 문서도 변경해야 하는, 마치 반복 작업 같은 문서화 작업은 메인테이너에겐 참을 수 없이 따분한 일이면서 의미를 찾기 어려운 일이 됩니다.
이번 글에서는 LINE의 동영상 플레이어인 UVP를 개편하며 얻은 인사이트를 바탕으로 위와 같은 문제를 점진적으로 해결해 나간 내용을 공유하겠습니다. UVP는 'Universal Video Player'의 줄임말로 LINE News와 LINE Live, LINE Official Account 등 LINE의 다양한 서비스에서 사용하는 동영상 UI 컴포넌트 라이브러리입니다.

기존 UVP 문서화 과정의 문제점

UVP는 이번 개편 전에는 문서화에 큰 어려움을 겪고 있었습니다. 개발자를 위한 가이드를 리포지터리의 README로 관리했기 때문에 아래와 같이 UVP를 적용한 예시 코드를 샘플 프로젝트로 제공하고 있었습니다.
UVP에서 사용할 API와 옵션에 관한 내용, FAQ는 또 다른 README 페이지를 작성해 링크로 제공하고 있었습니다.
UVP는 순수 JavaScript로 작성했고 JSDoc을 별도로 제공하지 않았기 때문에 API README 문서에서 자세하게 설명할 필요가 있었습니다. 이는 UVP를 사용하는 개발자들이 UVP에 기여하기 어렵게 만드는 요소 중 하나였고 문서와 코드를 동기화하고 지속적으로 유지 보수하기 어렵게 만들었습니다.
UVP와 같은 UI 컴포넌트 라이브러리를 사용하려면 라이브러리에서 제공하는 다양한 옵션과 메서드를 이해할 필요가 있습니다. 따라서 개발자는 문서를 읽으면서 컴포넌트를 빌드하기 위한 다양한 옵션과 메서드의 조합을 이해해야 합니다. 예시 코드를 보면서 UVP를 사용할 때 어떤 옵션이 있었고, 그 옵션을 사용하려면 어떻게 해야 하는지 숙지해야 합니다. 예를 들어 아래 코드를 보면서 setResolution이라는 메서드를 사용할 때 어떤 객체 배열을 넣어야 하는지 알아야 합니다.
이 모든 걸 이해하고 난 다음에야 자신의 프로젝트에 UVP 적용을 시작할 수 있습니다. 단순한 UI 컴포넌트 하나를 사용하기 위해서도 이와 같은 과정을 거쳐야 합니다. 이 과정에서 개발자는 리포지터리의 README와 코드 워크스페이스를 반복해서 오가며 코드를 작성하게 됩니다.
또한, 최종 결과물을 스크린숏으로 제공하고 있었기 때문에 문서와 이미지가 강하게 연결돼 있었습니다. 이는 풍부한 예제를 보여주기가 어렵다는 뜻이 됩니다. 어떤 옵션을 적용하면 어떤 컴포넌트로 그려지는지 일일이 스크린숏으로 제공하기에는 한계가 있습니다. 지속적으로 관리하기도 어렵습니다. 이는 메인테이너에게만 국한된 문제가 아닙니다. UVP를 처음 사용하는 모든 개발자는 UVP를 화면에 그리기 위해 위 단계를 거쳐야 할 것입니다. README 페이지와 코드 워크스페이스를 반복적으로 오가게 된다는 뜻입니다.
UI 컴포넌트 라이브러리가 우리 프로젝트에 잘 적용되는지 확인하기 위해서는 React 혹은 Vue 등으로 만든 프로젝트에서 Getting Started를 보고 컴포넌트를 만들어 Webpack 혹은 Parcel 등으로 빌드하는 과정을 거쳐야 합니다. 그런데 단순한 UI 컴포넌트 라이브러리를 사용하기 위해서 이런 사전 작업을 꼭 거쳐야 하는 것일까요? 저는 라이브러리를 개발하면서 이런 의문이 들었습니다. 모든 개발자가 많은 시간을 소비하고 불필요한 트래픽을 발생시키면서 이런 작업을 거쳐야 하는 것일까요?
다시 첫 질문으로 돌아가 보려고 합니다. 개발자 친화적이란 무엇일까요? 앞서 이야기한 UI 컴포넌트 라이브러리 적용 과정에서의 불편함을 중심으로 이야기해 보겠습니다. 제가 생각하는 개발자 친화적의 세 가지 요소는 쉬운 사용과 친절함, 그리고 유용성이라고 생각합니다. 라이브러리는 쉬워야 합니다. 사용하는 개발자가 라이브러리를 쉽고 편하게 사용할 수 있어야 합니다. 또한 라이브러리는 친절해야 합니다. 문서를 통해 적절한 예시와 다양한 사례를 제공해서 다른 개발자의 시간을 아껴줘야 합니다. 마지막은 유용성입니다. 다양한 환경에서 사용할 수 있어야 한다고 생각합니다.
UVP는 그중 앞의 두 가지, 쉬운 사용과 친절함이 부족했습니다. 코드 단계에서 컴포넌트를 사용하는 과정이 어려웠고, 제공한 문서가 친절하지 않았습니다. 이에 이 부분을 개선하는 작업을 진행했습니다.

개발자 친화적인 라이브러리 만들기

개선 작업의 가장 중요한 목표는 개발자 친화적인 UI 컴포넌트 라이브러리로 변경하는 것이었습니다. 이 목표를 중심에 두고 라이브러리를 사용하는 개발자와 메인테이너 양쪽 측면에서 방안을 수립했습니다.
먼저 우리 라이브러리를 사용할 개발자를 위해 앞서 언급한 세 가지 요소, 쉽고, 친절하며, 범용성 높은 라이브러리를 만들기 위한 방안을 수립했습니다. 구체적으로 워크스페이스 코드 단계에서 컴포넌트를 쉽게 적용할 수 있게 개선하고, 다양한 예시와 옵션을 제공해 사용하면서 라이브러리가 친절하다고 느끼도록 만들어 개발자 경험을 향상시키고자 했습니다.
메인테이너 측면에서는, 개발자를 위한 개선 과정에서 과도한 문서화 작업으로 의욕이 꺾이지 않도록 문서화 과정에 의미를 부여하고 작업을 편리하게 할 수 있도록 개선하고자 했습니다. 지속적으로 문서화를 진행하고 라이브러리의 안정성을 높이면서 가능한 부분을 자동화해 작업의 효율을 높이고자 했습니다. 이를 통해 친절한 문서와 함께 개발자 친화적인 환경이 갖춰지면 개발자가 기여하는 것도 한결 쉬워질 것이라고 기대했습니다.
이를 위해 TypeScript와 Storybook을 도입했습니다.
개선 작업에서 TypeScript와 Storybook은 서로 목표가 조금 다릅니다. TypeScript는 TSDoc과 선언 파일을 활용해 코드와 문서를 동기화하고 IDE의 인텔리 센싱을 활용하는 것이 목표입니다. IDE, 코드 워크스페이스의 최적화와 TypeScript의 장점을 이용해 개발자의 사용성을 향상시키는 것을 노리는 것입니다. 반면 Storybook은 IDE 코드 단계가 아니라 더 넓은 범위의 샘플 페이지를 제공하는 것이 목표입니다. Storybook의 다양한 애드온을 이용해 개발자 친화적인 샘플 페이지를 쉽게 구성할 수 있습니다.

TypeScript 도입

먼저 TypeScript 도입 과정을 살펴보겠습니다. UVP는 순수한 JavaScript로 구성했고 JSDoc이 없기 때문에 여러 개의 마크다운 문서가 이곳저곳에 산재해 있었습니다. 이에 이번 기회에 TypeScript로 바꾸면서 TSDoc을 도입했습니다. 마크다운 문서를 코드 내부로 옮겨 사용자가 리포지터리의 README가 아니라 코드 단계에서 가이드를 읽으며 UVP를 쉽게 적용할 수 있도록 개선했습니다. 또한, 선언 파일을 적절하게 활용해 타입 분리와 주석 관리를 쉽게 할 수 있도록 만들었습니다.
TypeScript 자체를 이 글에서 자세하게 설명하진 않겠습니다. 간단하게 말씀드리면, TypeScript는 아래 코드처럼 변수나 메서드 타입을 추가해 들어온 값을 미리 예측할 수 있게 하고, 런타임 전에 인텔리 센싱을 통해 코드에서 발생할 수 있는 여러 문제점을 바로 찾을 수 있는 강점이 있습니다.
UVP의 경우, 기존에는 메서드를 사용할 때 어떤 값을 어떤 타입으로 넣어야 하는지에 대한 설명이 없었기 때문에 아래 코드처럼 setAudience라는 메서드를 정확하게 사용하려면 다시 문서를 찾아봐야 했습니다. 하지만 TypeScript를 사용하면 IDE에서 타입을 추론할 수 있습니다. 라이브러리를 사용하는 개발자에게는 이렇게 타입을 적용하는 것만으로도 인자를 코드 단계에서 알 수 있다는 분명한 이점이 있습니다.
이때 여기에 TSDoc을 추가하면 그 효과가 배가 됩니다. TSDoc은 주석과 간단한 문법을 통해 별다른 작업 없이 IDE의 인텔리 센싱을 향상시킬 수 있는 도구입니다. 아래 슬라이드를 살펴보겠습니다. @example이라는 키워드를 사용하고 있고, jsx 형태의 마크다운 태그를 제시하고 있습니다.
이와 같이 사용하는 메서드나 인터페이스의 TSDoc을 작성해 두면, 개발자는 아래와 같이 실제 코드처럼 하이라이트가 적용된 예제 코드의 모습이나 추가 설명을 볼 수 있습니다.
이제 TSDoc의 여러 키워드를 활용해 개발자의 IDE 환경을 더욱 다채롭게 채워 나가보겠습니다. 먼저 아래 왼쪽의 주석을 확인해 보겠습니다.
Video 인스턴스를 생성할 때 들어올 인자에 대한 설명을 @param으로 정의해 나눴습니다. 이를 통해 사용자가 작성하는 옵션의 위치에 따라 적절한 가이드를 제공할 수 있습니다. 또한, @see 키워드와 @link 키워드를 이용해 비디오 클래스 내부의 controls 메서드에 대한 링크를 전달하고 있습니다. 동영상을 통해 UVP를 사용하는 개발자 입장을 살펴보겠습니다.
인자의 위치가 변할 때마다 IDE의 설명이 변하는 것을 확인할 수 있습니다. 또한 예제 코드를 제공해서 코드 작성 가이드를 명확하게 전달할 수 있고, 인스턴스 빌드의 중요한 역할을 하는 내부 메서드의 링크를 제공해서 내부 흐름을 더 이해하고 싶은 개발자를 해당 코드의 위치로 직접 안내할 수 있습니다.
이와 같이 공식 문서를 탐색하는 과정을 IDE에서 제공함으로써 개발자가 코드 워크스페이스를 벗어나는 빈도를 줄일 수 있습니다. 이는 시사하는 바가 굉장히 크다고 생각합니다. 라이브러리를 사용하는 개발자가 워크스페이스를 벗어나지 않아도 되므로 개발할 때 더욱 몰입해서 진행할 수 있기 때문입니다. TSDoc은 설치 의존성이 없으며 WebStrom이나 Visual Studio Code와 같은 IDE에서 지원한다는 것 또한 상당한 이점입니다.
앞서 말씀드린 @link 키워드를 잘 활용하면 개발자에게 콕 집어서 가이드할 수 있습니다. UVP의 경우 Video 클래스를 생성할 때 controls 메서드가 중요한 역할을 합니다. 따라서, 해당 메서드의 존재와 위치를 알리기 위해 @link 키워드로 Video.controls를 작성하면 IDE에서 똑똑하게 해당 위치로 보내줍니다.
대부분의 라이브러리는 항상 호환성을 고민합니다. 큰 기능을 변경하면서 특정 메서드나 변수를 더 이상 지원하지 않게 되는 브레이킹 포인트가 발생할 경우, 문서나 예제 페이지를 잘 작성한다고 해도 라이브러리를 사용하고 있는 개발자가 모두 제대로 알림을 받을 수 있다고 생각하기는 어렵습니다. UVP 또한 하위 호환성을 보장하기 위해 다양한 문서와 메일링을 통해 사전 공지를 했는데요. 사실 이런 과정은 메인테이너에게 결코 유쾌하지 않은 작업입니다. 이때 @deprecated 키워드로 명시적인 브레이킹 포인트를 제공할 수 있습니다.
또한 @link를 포함한 여러 키워드를 제공해 마이그레이션 혹은 버전 업데이트를 진행하는 사용자에게 명시적으로 해당 변수나 메서드가 더 이상 사용되지 않으며, 그 이유가 무엇인지, 이와 비슷한 기능을 사용하기 위해서는 어떻게 해야 하는지에 대한 가이드도 코드 단계에서 제공할 수 있습니다. 이를 통해 개발자는 코드를 작성하면서 필요한 정보만 쉽고 빠르게 읽고 적용할 수 있습니다. 이는 개발자 경험을 크게 향상시킵니다.
TSDoc은 또한 Playground를 제공합니다. 각 키워드나 기능이 실제로 어떻게 적용되는지 직접 적용해 보면서 다양한 예제도 살펴볼 수 있습니다.
여기서 두 가지 의문이 생길 수 있습니다. 첫 번째는 '주석과 코드가 섞이면 비즈니스 로직을 작성할 때 어려움이 생기지 않을까?', 두 번째는 '보여주고 싶지 않은 타입이나 메서드가 있을 때는 어떻게 처리할 수 있을까?'입니다.
이 두 가지 의문은 선언 파일을 통해 깔끔하게 해결할 수 있습니다. 선언 파일에 보여줄 타입이나 메서드만 작성하고 TSDoc을 추가하면 보여줄 타입과 그에 대한 설명만 개발자에게 노출되며, 비즈니스 로직과 TSDoc이 완전히 분리되기 때문에 '관점의 분리'라는 이점 또한 함께 얻을 수 있습니다.
이는 메인테이너와 사용하는 개발자, 모두에게 좋습니다. 타입을 선언 파일에 정리하고 package.json에 내보낼 타입만 정리하면, 사용하는 개발자 입장에선 불필요한 타입이 보이지 않기 때문에 좋고, 메인테이너 입장에서는 관리해야 하는 퍼블릭 타입과 TSDoc이 모여 있기 때문에 관리 포인트가 types로 줄어든다는 이점이 있습니다.
이와 같이 단순히 메서드의 사용법을 문서로 다시 작성하는 게 아니라 TypeScript를 도입하면서, 추가한 내용이 자연스럽게 문서로 녹아들며 메인테이너는 두 번의 문서 작업에서 어느 정도 벗어날 수 있었습니다.

Storybook 도입

TypeScript는 코드 작성 단계의 개발자 경험을 향상시키는 데 초점을 두었습니다. 이것만으로도 개발자 경험을 크게 향상시킬 수 있었지만, 워크스페이스에 라이브러리를 설치하고 옵션을 적용해야 한다는 문제가 아직 남아 있었습니다. 또한 다양한 예제를 가이드하기에도 한계가 있었습니다. 특히 UI 컴포넌트 라이브러리라면 옵션을 적용한 다양한 예제 컴포넌트의 결과물을 제공하는 것이 일반적이기 때문에 예제 페이지가 필요하기 마련인데요. 이를 직접 만들기로 한다면 이에 필요한 공수와 유지 보수 비용도 고려해야 합니다.
이런 작업을 Storybook으로 쉽게 만들 수 있습니다. Storybook은 간단하게 말하자면, 특정 UI 컴포넌트를 잘라내 웹 페이지에서 바로 확인해 볼 수 있도록 도와주는 라이브러리입니다.
Storybook은 위와 같이 컴포넌트에 들어가는 props, 즉 옵션별 컴포넌트의 상태를 확인할 수 있다는 장점이 있습니다. 따라서 메인테이너 입장에서 UI 컴포넌트 라이브러리를 개발할 때 Storybook을 활용하면 해당 컴포넌트를 그리기 위한 전처리를 생략할 수 있습니다. 만약 팝업 이후 UI 형태가 변경되는 컴포넌트가 있다면 원래 해당 컴포넌트를 테스트하기 위해선 팝업을 실행하는 과정이 필요하지만, Storybook을 활용하면 팝업 프로세스를 건너뛰고 해당 컴포넌트의 UI를 바로 확인해 볼 수 있습니다.
또한 오픈소스 생태계가 잘 발전했고, 다양한 애드온이 존재한다는 것도 Storybook의 매력 포인트입니다. Storybook에서 제공하는 기능과 애드온을 활용해 샘플 페이지를 더욱 쉽게 만들 수 있습니다.
UVP는 Storybook을 채용해 메인테이너의 생산성을 높이면서, 동시에 Storybook이 예제 페이지의 기능도 담당하도록 작업했습니다. 앞서 말씀드린 UVP 문서의 문제점을 간단하게 복기해 보겠습니다. UVP에 어떤 메서드나 옵션이 있는지 확인하기 위해서 문서를 찾아봐야 했고, 기능을 변경하면 문서를 수정해야 했습니다. 또한 각 옵션을 사용했을 때의 결과물을 스크린숏으로 일일이 갱신해야 했습니다.
문서에는 기본적으로 컴포넌트에 어떤 API가 있는지와 그 사용법이 들어가야 하고, 설정 가능한 옵션과 그 결과물이 어떤 모습인지를 보여줘야 하는데요. 이 부분을 Storybook을 통해 개선했습니다. 적용된 페이지의 결과를 바로 확인해 보겠습니다.
먼저 동영상 컴포넌트를 적용한 모습을 확인할 수 있습니다. 이때 코드 샌드박스를 사용해 코드 수정에 따라 컴포넌트가 변하는 것을 바로 확인할 수 있도록 만들었습니다. 코드를 수정하면 즉시 컴포넌트에 반영됩니다.
어떤 옵션이나 메서드가 있는지 프리뷰를 제공해 해당 옵션 설정에 따른 UI 컴포넌트의 변화 또한 직관적으로 보여줬습니다.
또한 문서와 예제를 일대일로 묶었습니다. 마크다운 문서에 각 컴포넌트의 설명을 작성하고 그 컴포넌트만 잘라내 테스트해 볼 수 있습니다. 이를 통해 문서화 작업과 예제 페이지 작업을 하나로 묶어 메인테이너가 개발하는 과정에서 필요한 Storybook이 그대로 개발자의 문서가 된다는 이점을 얻을 수 있습니다.
이제 하나씩 살펴보겠습니다. UVP의 메인테이너는 샘플 페이지를 별도로 만드는 공수를 줄이고 싶었습니다. 개발 과정이 자연스럽게 샘플 페이지와 연계되는 방향을 원했고, 그 결과 Storybook을 선택했습니다. Storybook에서 제공하는 기본(essential) 기능을 활용하면 예제 페이지를 아주 쉽게 구축할 수 있으며, 컴포넌트 개발 또한 Storybook 내에서 할 수 있습니다.
먼저 stories 디렉터리를 만들고 스토리가 포함된 파일을 만듭니다.
이후 보여줄 컴포넌트를 반환하는 템플릿을 바인드하면 오른쪽 아래와 같은 문서가 생깁니다. 페이지를 만드는 과정은 이게 전부입니다.
controls를 통해 해당 컴포넌트의 옵션을 바로 확인해 볼 수 있기 때문에 메인테이너가 개발할 때도 편리하고, 사용하는 개발자 또한 옵션이 적용된 모습을 확인하기 위해 별도 패키지를 다운로드하고 빌드하는 모든 과정을 생략할 수 있습니다.
이때 Storybook에 MDX 파일을 활용하면 문서화의 범용성을 더욱 향상시킬 수 있습니다.
MDX는 기존 마크다운 문법에 JSX 컴포넌트를 임베드해서 사용할 수 있도록 해줍니다. JSX 문법을 그대로 사용할 수 있으므로 코드에서 사용한 컴포넌트를 불러와서 적용할 수 있다는 장점이 있습니다. 아래 가운데와 같이 import와 export 및 JSX 문법을 마크다운 파일에서 자유롭게 사용할 수 있고 JS 파일의 컴포넌트로 데이터를 넘길 수 있습니다. 이를 통해 아래 오른쪽처럼 넘어온 데이터에 따라 동적으로 마크다운을 그릴 수 있습니다.
MDX를 사용하면 범용성 있는 NPM의 여러 라이브러리를 마크다운에서 직접 사용할 수 있으므로 차트나 SVG, 테이블 등의 컴포넌트 라이브러리를 활용해 문서화의 잠재 능력을 무궁무진하게 향상시킬 수 있습니다. UVP에서는 UI 컴포넌트별로 스토리를 작성했으며 해당 스토리와 MDX를 일대일로 매칭해 컴포넌트별 문서와 빌드 결과물이 MDX에 하나로 반영될 수 있도록 했습니다.
또한 UVP는 MDX의 유연함을 활용해 CodeSandbox를 추가했습니다. UVP에는 다양한 옵션이 존재했고 옵션별로 적용 방법이 조금씩 달랐는데요. 이에 개발자가 사전 테스트를 보다 쉽고 편하게 진행할 수 있도록 CodeSandbox를 도입했습니다.
CodeSandbox를 활용하면 다양한 예제와 그 예제에 따른 환경을 샌드박스로 제공할 수 있기 때문에 빌드한 결과물이 바로 나타납니다. React나 Vue, Vanilla 등 다양한 환경에서의 적용 방식을 샌드박스로 제공할 수 있어서 어떤 옵션을 적용해야 하는지 고민하는 데 드는 시간을 줄이고 사용법을 익힐 때의 허들을 낮출 수 있습니다.
MDX Embed 애드온을 활용하면 Storybook의 MDX 파일에 CodeSandbox 혹은 CodePen과 같은 실제 코드 환경을 쉽게 제공할 수 있습니다. 사용법은 굉장히 간단합니다. 아래와 같이 CodeSandbox 컴포넌트를 넣고 codesandbox.io에서 만든 워크스페이스 ID를 제공하면 끝입니다.
이제 라이브러리를 사용하고자 하는 개발자는 개인 워크스페이스에 설치하고 빌드하는 과정을 거치지 않고 웹 사이트에서 바로 원하는 기능을 확인하고 적용해 볼 수 있습니다.
이 외에도 Storybook에서 제공하는 다양한 애드온을 사용해 더욱 풍성한 예제를 제공하고 개발 단계의 불편함을 줄일 수 있습니다. 두 가지 애드온을 소개하려는데요. 첫 번째는 기본으로 제공하는 Viewport 애드온입니다. 반응형 디자인을 적용한다면 Storybook을 통해 Viewport 예시를 쉽게 제공할 수 있습니다.
두 번째는 메인테이너에게 효과적인 Storyshots 애드온입니다. Storyshots 애드온은 Jest의 스냅숏 기능을 Storybook에서 쉽게 사용할 수 있도록 해줍니다. 메인테이너는 개발을 진행하면서 Storybook을 많이 참고하는데요. 내부 로직에 변동이 있을 경우 UI 컴포넌트가 정상적으로 그려지고 있는지 Storybook을 통해 확인하며 검사합니다. 이때 Storyshots 애드온을 이용하면 자동화 및 PR 단계에서의 검증을 자동으로 해줍니다.
이제 완성한 Storybook을 배포해 보겠습니다. Storybook을 사용하면 정적 빌드를 통해 문서의 버전 작업을 간편하게 진행할 수 있습니다. 아래와 같이 Storybook에서 기본으로 제공하는 빌드 스크립트를 통해 정적 결과물을 추출할 수 있습니다.
이 결과물에 버전을 프리픽스로 붙여 배포하면 버전별 UI를 분리할 수 있습니다. 빌드 결과물을 CDN에 올리면 바로 사이트가 동작하기 때문에 서버에 대한 고려를 할 필요가 없습니다. 이는 예제 페이지 관리 이슈를 현저하게 줄여줍니다. 라이브러리를 개발하고 운영하는 측에선 버전 작업에 관심이 많은데요. 버전별로 UI나 메서드가 추가 혹은 삭제될 수 있기 때문에 문서화 또한 버전 작업이 필요합니다. 이때 Storybook의 정적 빌드를 통해 버전 작업을 해결하고 예제 사이트 작업에 들어가는 공수를 획기적으로 줄일 수 있습니다. 이를 통해 아래와 같이 메인테이너와 라이브러리를 사용하는 개발자 모두를 위한 예제 페이지를 쉽게 만들 수 있습니다.

마치며

이와 같이 UVP는 TypeScript와 Storybook을 활용해 메인테이너에겐 지속적인 문서화 작업을 쉽고 편하게 진행할 수 있으면서 안정적인 라이브러리 개발 환경을 제공하고, 라이브러리를 사용하는 개발자에겐 코드 단계에서 쉽게 적용할 수 있는 라이브러리를 친절한 예제 페이지와 함께 제공할 수 있었습니다. 긴 글 읽어주셔서 감사합니다.