Storybook를 가볍게 활용해보고 느낀 장점들

내가 프로젝트에서 Storybook을 활용한 방법

2023년 07월 23일| by유연

스토리북이란

Storybook: Frontend workshop for UI development

스토리북은 UI 컴포넌트와 페이지를 독립적인 환경에서 만들어 볼 수 있는 툴입니다. 스토리라는 컴포넌트 조건을 잘 작성해 두면 API 같은 외부 조건과 관계없이 원하는 상태의 컴포넌트를 그려보고 확인해 볼 수 있습니다.

42gg 디자인 리팩토링 작업을 하면서 보다 간편한 테스트를 위해서 스토리북을 이용하기로 했는데, 써 보니 단순 테스트 이상의 장점을 느껴서 소개해 보려고 합니다.

독립적인 환경에서 컴포넌트를 테스트하고 문서화할 수 있다.

독립적인 환경이라고 하는 것이 잘 와닿지 않을 수도 있을 것 같은데, 42gg의 상황을 예로 들어 설명해 보겠습니다.

42gg 메인 화면에는 게임 스코어 아이템 컴포넌트가 있습니다. (화질이 너무 좋지 않네요…)

각각

  1. 현재 게임이 진행 중인 상태
  2. 게임이 완료되었지만, 점수가 입력되지 않은 상태
  3. 게임이 완료되고 점수가 입력된 상태

의 컴포넌트입니다. 이 컴포넌트들을 다 테스트해 보기 위해서는

  1. 게임 매칭을 위해 상대 사용자 모집
  2. 게임 시작을 위해 최대 15분 기다리기 (1번 상태 테스트 가능)
  3. 게임 시간이 끝나기까지 기다리기 (15분) (2번 상태 테스트 가능)
  4. 게임 스코어 입력하기 (3번 상태 테스트 가능)

이렇게 꽤 복잡한 절차를 걸쳐야 하는데요. 단계가 많은 것뿐만 아니라 실제 서비스의 시간을 기반으로 동작하기 때문에 짧게는 15분, 길게는 30분이라는 시간을 들여야만 모든 테스트케이스를 확인해 볼 수 있습니다.

게다가 이 상태들은 모두 API를 통해서 변화하기 때문에 백엔드 서버에 문제가 있다거나 해서 API 연결이 잘되지 않을 경우에는 개발 자체가 불가능한 문제도 있었습니다.

이렇게 외부 요소와 많이 연관되는 컴포넌트를 개발하면서 여러 문제로 개발이 지연되는 것을 경험하다 보니 자연스럽게 독립적인 환경의 필요성을 느끼게 되었습니다.

이때 스토리북을 이용해서 스토리를 아래처럼 각각의 상태에 맞게 스토리를 만들면 외부의 변화를 기다릴 필요 없이 각 상태의 컴포넌트를 확인하며 개발할 수 있습니다.

1
const meta: Meta<typeof GameResultBigItem> = {
2
title: 'Game/GameResultBigItem',
3
component: GameResultBigItem,
4
tags: ['autodocs']
5
};
6
7
export default meta;
8
type Story = StoryObj<typeof GameResultBigItem>;
9
10
export const Live: Story = {
11
args: {
12
game: {
13
status: 'LIVE' as const,
14
...RANKTEAMS,
15
},
16
},
17
};
18
19
export const Wait: Story = {
20
args: {
21
game: {
22
status: 'WAIT' as const,
23
...RANKTEAMS,
24
},
25
},
26
};
27
28
export const End: Story = {
29
args: {
30
game: {
31
status: 'END' as const,
32
...RANKTEAMS,
33
},
34
},
35
};

더 나은 구조를 고민할 수 있다.

아래 내용은 프로젝트에서 직접 적용해 본 것은 아니지만… 제가 스토리를 만들면서 느꼈던 바를 기반으로 쓰였습니다!

스토리북에서도 MSW를 이용해서 Mock API를 사용할 수 있고, Recoil 같은 상태 관리 라이브러리도 사용할 수 있습니다.

하지만 라이브러리를 사용하기 위한 설정이 상당히 번거롭기도 하고, 상태를 설정하거나 Mock API를 사용해야 하는 상황이라면 Mock API를 만드는 작업 등의 추가적인 작업이 생각보다 많기 때문에 단순히 컴포넌트의 외관만 확인하기 위해서 스토리북을 사용하는 것이었다면 ‘이 구조가 정말로 맞는 것인가?’ 하는 생각을 자연스럽게 하게 되는 것 같습니다.

컴포넌트의 크기가 너무 커서 내부에서 하는 역할이 너무 많아지게 되면, 이 컴포넌트를 스토리북으로 옮기기 위해서 해야 하는 작업 또한 많아지기 때문에 컴포넌트 스토리를 만들면서 설계의 고민도 하게 되는 장점 또한 있을 것 같다는 생각이 들었습니다… 만

저희는 짧은 개발 기간 때문에 설계의 고민보다는 ‘일단 되게 하라!’가 모토였기 때문에 스토리북으로 옮기기 좀 힘들면 스토리북으로 확인하는 것의 비용 절감 효과와 그 추가적인 작업을 하는 것의 비용을 비교해서 추가 작업이 너무 크다 싶으면 그냥 스토리를 만들지 않는… 그런 결정을 내렸습니다. 하하… 지금 생각하니 좀 아쉬운 부분이긴 하네요.

마무리

제가 다른 곳에서 스토리북을 활용하는 예시를 본 것들을 떠올려보면 대부분 디자인 시스템 문서화같이 컴포넌트 문서를 공개하기 위한 것들이 많았던 것 같습니다. (지금 생각해 보니 공개된 스토리북의 목적은 대부분 공개하기 위함이었을 테니 어쩔 수 없었던 것 같기도 하네요. ^_^...;;) 잘 정리해서 공개적으로 배포해 보는 것이 좋겠다는 다른 분의 말씀도 듣기도 해서 배포하지 않으면 스토리북을 사용한 의미가 없었던 건가? 하는 생각을 했었는데요. 이렇게 정리해 보니 좀 어리바리 쓰긴 했어도 이것 역시 나름대로 컴포넌트 시나리오를 문서화해서 내부적으로 공유한 것이기 때문에... 사소하긴 해도 의미가 있었던 것 같긴 합니다. 하하

하지만 좀 아쉬움이 남긴 해서, 여유가 되면 중복된 스타일링 코드들을 좀 손보고 컴포넌트 문서화도 좀 하고, 구조를 개선하지 못해서 스토리북으로 못 옮긴 컴포넌트들도 리팩토링해서 스토리북으로 옮겨 보고 싶습니다…