[StoryBook] StoryBook



StoryBook 이란?

UI 컴포넌트를 직접 보면서 개발을 할 수 있는 환경을 제공하는 툴

토리북은 프로젝트 내에서 독립된 환경으로 실행 되기 때문에, 앱의 특정한 의존성에서 벗어나서 순수 UI 개발에 집중 할 수 있도록 한다

또한, 스토리북은 리액트 웹(Web) 뿐만 아니라 리액트 네이티브(React Native) 환경에서도 사용 할 수 있다.

스토리북을 활용하면 개발자 본인 뿐 아니라, 팀(기획자, 디자이너)과의 협업 구조에서도 원할한 커뮤니케이션과 빠른 이터레이션(iteration)을 통한 개발 생산성 향상 효과도 누릴 수 있다.

UI 개발을 하다 보면 빈번하게 일어나는 디자인 스펙 오류, 기획 프로세스 오류 등을 빠르게 확인 하여 수정 할 수 있으며, 개발자는 컴포넌트를 더욱 유연하고, 재사용 가능한 컴포넌트 개발을 할 수 있도록 도와준다.

install

React에서 사용하기

npm install -g @storybook/cli

getstorybook init

npm run storybook 또는
yarn storybook

stories 디렉토리와 .storybook 디렉토리가 생성된 것을 확인 할 수 있다.

Start

Setting

경로 ../src/*/.stories.js확인

# .storybook/config.js
module.exports = {
  stories: ['../src/**/*.stories.js'],
  addons: [
    '@storybook/preset-create-react-app',
    '@storybook/addon-actions',
    '@storybook/addon-links',
  ],
};

Example

예제 코드

# src/Components/Hello.js
import React from 'react';

const Hello = ({ name, big }) => {
  if (big) {
    return <h1>안녕하세요 {name}!</h1>;
  }
  return <p>안녕하세요, {name}!</p>;
};

export default Hello;

스토리 작성

스토리를 작성할 때에는 .stories.js 확장자로 작성하면됨.

Storybook v5.2 부터는 Component Story Format (CSF) 형식을 사용하여 문서를 작성함.

# src/stories/Hello.stories.js
import React from 'react';
import Hello from '../Components/Hello';

export default {
  title: 'components|basic/Hello', // 스토리북에서 보여질 그룹과 경로를 명시
  component: Hello, // 어떤 컴포넌트를 문서화 할지 명시
};

export const standard = () => <Hello name="Storybook" />;
export const big = () => <Hello name="Storybook" big />;

yarn storybook

실행화면

storyboard-1

StoryBook의 가장 기본적인 기능이다.

애드온

StoryBook Addon을 적용하면 더욱 다양하고 편리한 기능들을 붙여줄 수 있다.

  • Knobs
  • Action
  • Docs
  • Viewport

Knobs

컴포넌트의 props를 스토리북 화면에서 바꿔서 바로 반영시켜줄 수 있는 애드온

Install

yarn add --dev @storybook/addon-knobs

Setting

.storybook/main.js 에 @storybook/addon-knobs/register 추가

module.exports = {
  stories: ['../src/**/*.stories.js'],
  addons: ['@storybook/preset-create-react-app', '@storybook/addon-actions', '@storybook/addon-links', '@storybook/addon-knobs/register'],
};
# src/stories/Hello.stories.js
import React from 'react';
import Hello from '../Components/Hello';
import { withKnobs } from '@storybook/addon-knobs';

export default {
  title: 'components|basic/Hello', // 스토리북에서 보여질 그룹과 경로를 명시
  component: Hello, // 어떤 컴포넌트를 문서화 할지 명시
  decorators: [withKnobs] // 애드온 적용
};

export const standard = () => <Hello name="Storybook" />;
export const big = () => <Hello name="Storybook" big />;

Example - Knobs 생성

Knobs 를 사용 할 때 넣어주어야 하는 주요 인자로는 Knobs 의 이름, 기본값 그리고 GROUP ID 가 있다. (GROUP ID 의 경우 생략가능)

# src/stories/Hello.stories.js
import React from 'react';
import Hello from '../Components/Hello';
import { withKnobs, text, boolean } from '@storybook/addon-knobs';

export default {
	title: 'components|basic/Hello', // 스토리북에서 보여질 그룹과 경로를 명시
	component: Hello, // 어떤 컴포넌트를 문서화 할지 명시
	decorators: [withKnobs] // 애드온 적용
};

export const hello = () => {
	// knobs 만들기
	const big = boolean('big', false, 'Group 1');
	const name = text('name', 'Storybook');
	return <Hello name={name} big={big} />;
};
hello.story = {
	name: 'Default'
};

export const standard = () => <Hello name='Storybook' />;
export const big = () => <Hello name='Storybook' big />;

실행 화면

storyboard-2

Knobs 종류

  • text: 텍스트를 입력 할 수 있습니다.
  • boolean: true/false 값을 체크박스로 설정 할 수 있습니다.
  • number: 숫자를 입력 할 수 있습니다. 1~10과 같이 간격을 설정 할 수도 있습니다.
  • color: 컬러 팔레트를 통해 색상을 설정 할 수 있습니다.
  • object: JSON 형태로 객체 또는 배열을 설정 할 수 있습니다.
  • array: 쉼표로 구분된 텍스트 형태로 배열을 설정 할 수 있습니다.
  • select: 셀렉트 박스를 통하여 여러가지 옵션 중에 하나를 선택 할 수 있습니다.
  • radios: Radio 버튼을 통하여 여러가지 옵션 중에 하나를 선택 할 수 있습니다.
  • options: 여러가지 옵션을 선택 하는 UI 를 커스터마이징 할 수 있습니다 (radio, inline-radio, check, inline-check, select, multi-select)
  • files: 파일을 선택 할 수 있습니다.
  • date: 날짜를 선택 할 수 있습니다.
  • button: 특정 함수를 실행하게 하는 버튼을 만들 수 있습니다.

Actions

컴포넌트를 통하여 특정 함수가 호출됐을 때 어떤 함수가 호출됐는지, 그리고 함수에 어떤 파라미터를 넣어서 호출했는지에 대한 정보를 확인 할 수 있게 해줌.

간단한 함수 호출부터 시작해서, 나중에는 리액트 라우터의 주소가 변경될 때를 확인하거나, 리덕스 스토어의 dispatch를 mocking하여 디스패치 되는 액션의 정보를 볼 수 도 있음.

Storybook CLI로 만든 프로젝트에 기본적으로 적용이 되어있기 때문에 별도로 설치하실 필요가 없다.

Example

# src/Components/Hello.js

import React from 'react';

const Hello = ({ name, big, onHello, onBye }) => {
  return (
    <div>
      {big ? <h1>안녕하세요 {name}!</h1> : <p>안녕하세요 {name}!</p>}
      <div>
        <button onClick={onHello}>Hello</button>
        <button onClick={onBye}>Bye</button>
      </div>
    </div>
  );
};

export default Hello;

# src/stories/Hello.stories.js

import React from 'react';
import Hello from '../Components/Hello';
import { withKnobs, text, boolean } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';

export default {
  title: 'components|basic/Hello', // 스토리북에서 보여질 그룹과 경로를 명시
  component: Hello, // 어떤 컴포넌트를 문서화 할지 명시
  decorators: [withKnobs], // 애드온 적용
};

export const hello = () => {
  // knobs 만들기
  const big = boolean('big', false, 'Group 1');
  const name = text('name', 'Storybook');
  return <Hello name={name} big={big} onHello={action('onHello')} onBye={action('onBye')} />;
};
hello.story = {
  name: 'Default',
};

export const standard = () => <Hello name="Storybook" />;
export const big = () => <Hello name="Storybook" big />;

실행 화면

storyboard-3

Docs

MDX형식으로 문서를 작성 할 수 있게 해주고, 컴포넌트의 props와 주석에 기반하여 문서를 자동생성해줌.

Install

yarn add --dev @storybook/addon-docs

Setting

1) .storybook/main.js에 @storybook/addon-docs/react/preset 추가 2) .mdx 확장자도 처리하도록 정규식을 수정

module.exports = {
  stories: ['../src/**/*.stories.(js|mdx)'],
  addons: ['@storybook/preset-create-react-app', '@storybook/addon-actions', '@storybook/addon-links', '@storybook/addon-knobs/register'],
};

StoryBook 서버 종료 후 재시작

상단에 Docs 가 생성된 것을 확인 할 수 있다.

storyboard-4

Start

지금은 Props 부분이 “No props found for this component” 라고 보여지면서 비어있다.

이 부분을 채우려면 prop-types 또는 TypeScript를 사용해야합

문서화 방법

# src/Components/Hello.js

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

const Hello = ({ name, big, onHello, onBye }) => {
  return (
    <div>
      {big ? <h1>안녕하세요 {name}!</h1> : <p>안녕하세요 {name}!</p>}
      <div>
        <button onClick={onHello}>Hello</button>
        <button onClick={onBye}>Bye</button>
      </div>
    </div>
  );
};

Hello.propTypes = {
  /** 보여주고 싶은 이름 */
  name: PropTypes.string.isRequired,
  /** 이 값을 `true` 로 설정하면 h1 태그로 렌더링 됩니다. */
  big: PropTypes.bool,
  /** Hello 버튼 누를 때 호출할 함수 */
  onHello: PropTypes.func,
  /** Bye 버튼 누를 때 호출할 함수 */
  onBye: PropTypes.func,
};

Hello.defaultProps = {
  big: false,
};

export default Hello;

propTypes 를 설정 할 때 각 props 위에 /** **/ 주석으로 문구를 넣어주면 이 문구가 나중에 문서에서 나타나게 됨.

실행 결과

storyboard-5

** 컴포넌트 부제목 및 설명 넣기**

parameters 추가

# src/stories/Hello.stories.js

import React from 'react';
import Hello from '../Components/Hello';
import { withKnobs, text, boolean } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';

export default {
  title: 'components|basic/Hello', // 스토리북에서 보여질 그룹과 경로를 명시
  component: Hello, // 어떤 컴포넌트를 문서화 할지 명시
  decorators: [withKnobs], // 애드온 적용
  parameters: {
    componentSubtitle: '"안녕하세요"라고 보여주는 컴포넌트'
  }
};

export const hello = () => {
  // knobs 만들기
  const big = boolean('big', false, 'Group 1');
  const name = text('name', 'Storybook');
  return <Hello name={name} big={big} onHello={action('onHello')} onBye={action('onBye')} />;
};
hello.story = {
  name: 'Default',
};

export const standard = () => <Hello name="Storybook" />;
export const big = () => <Hello name="Storybook" big />;

설명추가

# src/Components/Hello.js

/**
 * 안녕하세요 라고 보여주고 싶을 땐 `Hello` 컴포넌트를 사용하세요.
 *
 * - `big` 값을 `true`로 설정하면 **크게** 나타납니다.
 * - `onHello` 와 `onBye` props로 설정하여 버튼이 클릭했을 때 호출 할 함수를 지정 할 수 있습니다.
 */
const Hello = ({ name, big, onHello, onBye }) => {
  return (

실행 결과

storyboard-6

MDX로 문서 작성하기

MDX는 언제 사용하는가?

Docs 애드온을 통하여 자동으로 만들어진 문서에서 제공하는 정보로는 컴포넌트의 기능을 자세하게 표현하기 어려운 상황에 MDX를 사용하면 된다.

(대부분의 경우, 자동으로 생성되는 문서만으로도 충분 할 때가 많다.)

추가적으로, 컴포넌트가 아닌 문서를 작성해야 하는 상황에는 (예: Introduction, Colors, Typography 등..) MDX-only로 작성하면 된다.

컴포넌트에 대한 MDX를 작성하실 때에는 MDX-only로 문서를 작성하는 것은 권장하지 않는다.

그 이유는 나중에 TypeScript를 사용하게 된다면 IDE에서 .mdx 확장자에 대한 TypeScript 지원이 제대로 이루어지지 않는다.

Viewport

storyboard에서 반응형 구성 요소를 작성하고 확인할 수 있음.

Install

yarn -D @storybook/addon-viewport

Setting

.storybook/main.js에 ‘@storybook/addon-viewport/register’ 추가

# .storybook/main.js

module.exports = {
  addons: ['@storybook/addon-viewport/register'],
};

참고자료

https://velog.io/@velopert/start-storybook

https://velog.io/@velopert/create-your-own-design-system-with-storybook