사이드 프로젝트 storybook 도입기

사이드 프로젝트 storybook 도입기

생성일
2023년 05월 31일
태그
React.js
storybook

Background

필자는 ‘트위터 DM 없는 아이돌 굿즈 거래 서비스’인 저스트페이를 개발하고 있다. 한창 컴포넌트를 나누어 개발하고 있는데, 개발을 하면서 느낀점이 각자 개발한 컴포넌트가 공통적으로 쓰일 때 이를 쉽게 사용할 수 있도록 문서화하는 방법이 없을까라는 고민을 했다.
또한, 만든 컴포넌트를 웹에서 확인할 때 여러 케이스에 따른 컴포넌트들을 하나하나 확인하는게 꽤 번거로운 작업처럼 느껴졌다.
찾다보니 storybook이 이러한 팀의 번거로움을 해결해줄 수 있을 것이라 판단했다.
사용해보면서 더 명확한 이점을 직접 느끼고 정리하려고 한다.

Installation

$ npx storybook@latest init
storybook 내에서 eslint를 신경쓰지 않으려고 커맨드에 옵션을 추가하였다.
"scripts": { "storybook": "DISABLE_ESLINT_PLUGIN=true storybook dev -p 6006" }
다음과 같이 실행한다. 필자의 프로젝트는 yarn berry로 이루어져있다.
$ yarn storybook
실행하면 다음과 같이 storybook cli가 로컬에 생성된다.
notion image

Storybook 알아보기

story가 뭔데?

storybook 공식문서에서는 story를 다음과 같이 정의한다.
A story captures the rendered state of a UI component. Developers write multiple stories per component that describe all the “interesting” states a component can support.
즉, story는 컴포넌트의 렌더링된 상태를 감지하고, storybook을 이용하여 컴포넌트의 여러 상태를 테스트할 수 있다.

템플릿 뜯어보기

storybook cli가 열리면서 다음과 같은 파일들을 확인할 수 있다.
notion image
Button 컴포넌트를 예시로 살펴보겠다.
  • Button.tsx
평소에 리액트에서 컴포넌트 개발할 때의 파일과 동일하다. 다만, 다른점이 하나 존재한다. 아까 storybook을 도입하기로 결정하게 된 이유 중 하나가 문서화인데, 주석을 통하여 문서화를 하고, 이를 배포하여 팀원들과 공유할 수 있다.
아래는 Button.tsx 파일의 코드이다.
import React from 'react'; import './button.css'; // 아래처럼 주석으로 Button 속성을 문서화할 수 있다. interface ButtonProps { /** * Is this the principal call to action on the page? */ primary?: boolean; /** * What background color to use */ backgroundColor?: string; /** * How large should the button be? */ size?: 'small' | 'medium' | 'large'; /** * Button contents */ label: string; /** * Optional click handler */ onClick?: () => void; } /** * Primary UI component for user interaction */ export const Button = ({ primary = false, size = 'medium', backgroundColor, label, ...props }: ButtonProps) => { const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary'; return ( <button type="button" className={['storybook-button', `storybook-button--${size}`, mode].join(' ')} style={{ backgroundColor }} {...props}> {label} </button> ); };
storybook cli에서 다음과 같이 확인할 수 있다.
notion image
너무 신기하다. 이미 이 기능만으로도 너무 강력하게 느껴진다. 매번 공통 컴포넌트를 작성하고, 이를 PR에 작성해야하는 번거로움을 줄이고, 팀원들은 내가 만든 공통 컴포넌트를 문서로 쉽게 이해하고 사용할 수 있다.
또한, 해당 문서로 컴포넌트의 여러가지 상태를 바꿔가면서 테스트할 수 있다는 점이 놀랍다.
 
  • Button.stories.ts
해당 파일에 스토리들을 작성해서 케이스별로 컴포넌트를 확인할 수 있다. 해당 파일은 직접 적용하면서 살펴보도록 하겠다.

적용해보기

저스트페이에서 가장 대표적으로 사용하는 공통 컴포넌트는 역시 버튼이다. 버튼에는 여러가지 상태가 존재하고, 상태마다 보여지는 UI가 다르기 때문에, storybook을 사용해보려고 한다.
첫번째로 컴포넌트 파일이다.
import React from 'react'; import styled, { css } from 'styled-components'; import theme from 'styles/theme'; interface FullButtonProps { /** * 버튼 내부에 들어가는 텍스트입니다. */ text: string; /** * 버튼 색상입니다. 색상은 초록색 혹은 검은색입니다. */ color: 'green' | 'black'; /** * 버튼을 클릭했을 때 작동하는 함수입니다. */ onClick?: () => void; } export default function FullWidthButton({ text, onClick, color }: FullButtonProps) { return ( <StyledButton onClick={onClick} color={color}> {text} </StyledButton> ); } const StyledButton = styled.button` width: 100%; border: none; ${({ color }) => color === 'green' ? css` background-color: rgba(22, 215, 192, 0.15); color: ${theme.colors.green_text}; font: ${theme.fonts.M_14}; padding: 1rem 0; border-radius: 1px; ` : css` background-color: ${theme.colors.button_black}; color: ${theme.colors.white}; font: ${theme.fonts.M_17}; padding: 14px 0; border-radius: 10px; `} `;
 
두 번째로, 스토리 파일이다.
해당 파일에서 Meta 타입으로 컴포넌트의 정보를 작성하고 export 하면 storybook에서 해당 정보를 가지고 컴포넌트를 생성한다.
import { Meta, StoryObj } from '@storybook/react'; import FullWidthButton from './FullWidthButton'; const meta = { // 문서 제목 title: 'FullWidthButton', // 자동으로 문서 생성 tags: ['autodocs'], component: FullWidthButton, } satisfies Meta<typeof FullWidthButton>; export default meta; type Story = StoryObj<typeof meta>; export const Black: Story = { args: { text: '결제하기', color: 'black', }, }; export const Green: Story = { args: { text: '이 거래글 링크 복사하기', color: 'green', }, };
문서 기능을 사용하기 위해서는 meta 태그에 반드시 tags 프로퍼티를 설정해줘야 한다.
해당 파일에서는 Black, Green 2개의 스토리가 존재하고, 각 스토리별 보여지는 UI를 storybook cli를 통해 확인할 수 있다.
notion image
notion image
 
스토리북을 이제 도입해서 잘 활용하고 있는 단계는 아니지만, 점점 사용성을 높여볼 생각이다.
다음에는 문서화한 스토리북을 팀원들에게 공유할 수 있도록 빌드하고 배포해보도록 하겠다.

References

댓글

guest