Logo

Storybook 소개 / 기본 사용법

Storybook이란?

스토리북(Storybook)은 한 문장으로 정의가 어려울 정도로 다양한 방식으로 사용되고 있는 UI 컴포넌트 개발 도구입니다. 단순히 회사의 UI 라이브러리를 내부 개발자들을 위해 문서화(documentation)하기 위해서 사용할 수 있고, 외부 공개용 디자인 시스템(Design System)을 개발하기 위한 기본 플랫폼으로도 사용할 수 있습니다.

스토리북(Storybook)을 기본 구성 단위는 스토리(Story)이며 하나의 UI 컴포넌트는 보통 하나 이상의 Story를 가지게 됩니다. 각 Story는 해당 UI 컴포넌트가 어떻게 사용될 수 있는지를 보여주는 하나의 예시라고 생각하시면 이해가 편하실 것 같습니다.

Storybook을 사용하면 UI 컴포넌트가 각각 독립적으로 어떻게 실제로 랜더링되는지 직접 시각적으로 테스트하면서 개발을 진행할 수 있습니다. 해당 UI 라이브러리를 사용하는 개발자 입장에서도 코드를 보지 않고도 미리 각 UI 컴포넌트를 체험해보고 사용할 수 있어서 매우 유용합니다.

실습 프로젝트 생성

CRA(Create React App)을 사용해서 실습용 React 프로젝트를 하나 생성합니다.

$ npx create-react-app <프로젝트 디렉터리>
cd <프로젝트 디렉터리>

Storybook 설치

그 다음 Storybook CLI를 사용해서 Storybook을 프로젝트에 설치합니다.

$ npx @storybook/cli sb init

설치가 끝나면 package.json 파일에 2개의 스크립트와 4개의 개발 의존성이 추가된 것을 확인하실 수 있으실 겁니다.

  "scripts": {
    // 생략
    "storybook": "start-storybook -p 9009 -s public",
    "build-storybook": "build-storybook -s public"
  },
  "devDependencies": {
    "@storybook/addon-actions": "^5.2.8",
    "@storybook/addon-links": "^5.2.8",
    "@storybook/addons": "^5.2.8",
    "@storybook/react": "^5.2.8"
  }

Storybook 설정

.storybook 디렉터리를 열어보시면 Storybook 관련 2개의 설정 파일이 있을 것입니다. addons.js파일은 Storybook 애드온을 추가할 때 사용하고, config.js 파일은 그 밖에 다른 설정을 할 때 사용됩니다.

.storybook/config.js 파일을 열고, src 디렉터리 내부에 stories.js로 끝나는 모든 파일이 Story로 인식되도록 설정해줍니다. (기본 설정은 src/stories 디렉터리 하위만 탐색하므로 주석 처리가 하거나 삭제합니다.)

import { configure } from "@storybook/react";

// automatically import all files ending in *.stories.js
// configure(require.context('../src/stories', true, /\.stories\.js$/), module);
configure(require.context("../src", true, /\.stories\.js$/), module);

React 컴포넌트 작성

지금부터 단순한 텍스트를 랜더링하기 위한 <Text/>라는 짧은 React 컴포넌트를 하나 작성해보도록 하겠습니다. 먼저 src/components 디렉터리를 생성하고, 그 안에 Text.jsx 파일을 생성하고, 그 파일 안에 아래 코드를 작성합니다.

이 UI 컴포넌트 props로 넘어온 color, italic, underline에 따라서 다른 스타일이 적용된 children prop을 랜더링해줍니다.

import React from "react";
import PropTypes from "prop-types";

export function Text({ children, color, italic, underline }) {
  const style = {
    color: color,
    fontStyle: italic ? "italic" : "normal",
    textDecoration: underline ? "underline" : "none",
  };
  return <span style={style}>{children}</span>;
}

Text.propTypes = {
  children: PropTypes.string.isRequired,
  color: PropTypes.string,
  italic: PropTypes.bool,
  underline: PropTypes.bool,
};

Text.defaultProps = {
  color: "black",
  italic: false,
  underline: false,
};

Story 추가

자 이제, 위에서 작성한 React 컴포넌트를 어떻게 사용할 수 있는지를 알려주기 위해서 몇 가지 Story를 작성해보도록 하겠습니다. 관례상 하나의 UI 컴포넌트에 대해 하나 이상의 Story를 위에서 설정했던 것 처럼 <컴포넌트 이름>.stories.js라는 하나의 파일 안에 추가합니다.

먼저 src/components 디렉터리를 안에 Text.stories.js 파일을 생성하고, 그 파일 안에 아래 코드를 작성합니다.

default 임포트는 해당 UI 컴포넌트에 대한 메타 정보를 객체로 작성하는데 title은 Storybook 메뉴에서에서 해당 컴포넌트가 뭐라고 표시될지를 결정하고, component에는 위에서 작성한 React 컴포넌트를 지정합니다. 그 다음 4개의 named 임포트에는 UI 컴포넌트의 활용 예시를 나타내는 Story를 하나씩 함수 형태로 작성합니다.

import React from "react";
import { Text } from "./Text";

export default {
  title: "Text",
  component: Text,
};

const STORY_TEXT = "I love Storybook!";

export const Default = () => <Text>{STORY_TEXT}</Text>;

export const Red = () => <Text color="red">{STORY_TEXT}</Text>;

export const Italic = () => <Text italic>{STORY_TEXT}</Text>;

export const Underline = () => <Text underline>{STORY_TEXT}</Text>;

StoryBook 구동

마지막으로 Storybook 구동 스크립트를 실행하면, 브라우저에서 http://localhost:9009/이 열릴 것입니다.

$ npm run storybook

결국 Storybook은 프로젝트에서 개발하는 매인 애플리케이션과 별개로 따로 구동이 가능한 웹사이트입니다. 좌측 사이드바에 있는 메뉴 트리에서 Text를 선택하면, 그 하위에 4개의 Default, Red, Italic, Underline 이라는 Story가 보일 것입니다. 각 Story를 선택하면 해당 Story가 실제 브라우저에서 어떻게 랜더링되는지 우측 패널을 통해 확인하실 수 있으실 것입ㄴ다.

마치면서

지금까지 Storybook에 대한 간단한 소개와 기본적인 사용법에 대해서 살펴보았습니다. 이것은 Storybook의 빙산의 일각이며, Storybook에서 제공하는 애드온(add-on)을 사용하면 다양하고 강력한 추가 기능을 사용할 수 있습니다. 게다가 Storybook은 React 뿐만 아니라 Vue와 Angular에서도 사용이 가능하므로 사용하시는 자바스크립트 라이브러라에 구애받지 않고 사용해보셨으면 좋겠습니다.