스토리북은 UI 컴퍼넌트를 독립된 환경에서 개발할 수 있게 만든 도구 입니다. 조건에 따라서 변하는 UI를 독립적으로 테스트 해 볼 수 있고, Addon을 추가해 다양한 기능을 사용할 수 있습니다.
Addon : Storybook addon은 스토리북에 다양한 기능을 추가해 줄 수 있는 패키지
내 깃허브 : https://github.com/gyuhwanglee/storybook
Storybook은 재사용을 위해 구성 요소를 문서화하고 버그를 방지하기 위해 요소를 시각적으로 테스트하는 데 도움이 됩니다.
개발 : 각각의 조건의 story를 작성하여 컴포넌트 들을 확인해 볼 수 있고, 별도의 코드 수정 없이도 손쉽게 표시해 줄 내용이나, 조건을 변경해 볼 수도 있습니다.
커뮤니케이션 : 피그마로 구현된 디자인이 개발적으로 제대로 구현되었는지 시각적으로 확인할 수 있다.
실제 애플리케이션의 컴포넌트 조합을 검증할 수 없다.
당연한 이야기지만, 개별 컴포넌트가 시각적으로 문제없이 표시된다는 것이 전체 애플리케이션이 시각적으로 문제없이 표시된다는 의미가 될 수 없다. 특히 HTML/CSS로 이루어진 UI는 각 DOM 엘리먼트의 부모/자식 관계 및 순서, CSS 선택자, z-index 등 많은 요인에 의해 영향을 받는다. 실제 애플리케이션이 문제없이 표시되는지를 확인하려면 각 컴포넌트들이 올바른 순서로 조합되어 있는지, 서로 영향을 주고 있지 않은지 등을 확인해야만 한다.
부모 컴포넌트의 내부 구현 변경 시 깨지기 쉽다.
디자인적인 변경 사항이 없더라도 리팩토링 등으로 인해 부모 컴포넌트의 내부 구현이 바뀌게 되면 스토리가 제대로 표시되지 않는다. 즉, 부모 컴포넌트의 내부 구현이 변경될 때마다 스토리를 같이 변경해야만 한다.
또한 컴포넌트의 prop 값을 직접 주입해주고 있기 때문에, 해당 컴포넌트의 prop 인터페이스가 변경되는 경우에도 스토리를 함께 변경해 주어야 한다. 사실 어떤 컴포넌트의 props 인터페이스가 변경되든, 그 컴포넌트를 사용하는 부모 컴포넌트 입장에서는 내부 구현이 변경되는 것이나 마찬가지다. 보통 컴포넌트를 작은 단위로 사용할수록 영향을 받는 부모 컴포넌트의 수가 늘어난다는 점을 생각해보면, 컴포넌트 단위가 작아질수록 스토리에 대한 관리 비용이 증가한다고 볼 수 있다
기존 프로젝트의 루트 디렉토리에서 다음을 실행합니다.
npx storybook init
storybook을 실행하여 모든 것이 작동하는지 확인합니다.
yarn storybook
파일 구성
── .storybook
│ ├──── main.js
│ └──── preview.js
└─── ...
main.js에서는 addon을 추가할 수 있고, TypeScript 설정, path alias 설정 등, 다양한 webpack 설정들을 해 줄수 있습니다.
preview.js에서는 global css 파일들을 import해서 프로젝트에서 적용되는 global css들을 storybook 에서도 적용되도록 할 수 있고, Storybook의 canvas 배경 색 설정등 storybook에 global하게 적용될 부분들을 설정해 줄 수 있습니다.
개별 컴포넌트가 스토리북에 보여지는 것이므로 저런 Provider가 제공된 상태가 아니기에 theme와 store를 사용하였을 경우에 에러가 발생하거나 원하는대로 동작하지 않습니다.
따라서 Decorator를 통해서 Provider를 개별 스토리에 다 제공해줘서 store와 theme을 제공받도록 해아합니다.
개별 스토리마다 decorator를 추가할 수도 있지만, 모든 스토리에 공통적으로 적용되어야 하는 decorator라면 Preview.js에 전체적으로 데코레이터를 추가해주는 방식이 간편합니다.
예시 (preview.js)
import React from 'react';
import { addDecorator } from '@storybook/react';
import { ThemeProvider } from 'styled-components';
import Theme from '../src/styles/Theme';
import { withRouter } from 'storybook-addon-react-router-v6';
export const decorators = [
(Story) => (
//글로벌 css
{/ /}
{/ /}
{/ /}
),
withRouter, //라우터 설정
];
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
layout: 'centered',
controls: {
matchers: {
color: /(background|color)/,
},
},
};
Storybook에는 사용자를 위해서 docs를 추가할 수 있습니다.
mdx파일을 추가하는 방식과 PropTypes를 통해서 간단하게 표현해줄 수 있는 방법이 있습니다.
저의 경우에는 propTypes를 통해서 간략하게 문서화 하는 식으로 진행하였습니다.
React에서 기본적으로 제공하는 prop-types 라이브러리를 통해서 Props의 타입을 명시할 수 있고, 이와 주석을 결합하여 간략하게 해당하는 prop의 documentation을 스토리북에 포함할 수 있습니다.
(1) export default + export const
스토리북 파일을 작성하는 방법은 크게 두가지가 있는데 Stories of 를 사용하는 방식과, export default로 title과 component를 정의해준 다음, export const <표현하고싶은 이름> 을 통해서 하는 방식 2가지가 있는
Story of 보다는 export default + export const를 사용하는 방식이 더 최신문법이고 권장사항
export default {
title: 스토리북에 올릴 component폴더 계층 구조,
component: 스토리를 만들 컴포넌트 이름
args: { //모든 구성 요소의 스토리에 적용된다. (preview.js에서 전역 설정가능)
isCheck: true,
},
parameters: { //story 기능 및 애드온의 동작을 제어하는데 사용되는 정적 데이터 (preview.js에서 전역 설정가능)
layout: 'centered' //위치 설정
}
decorators: [ //렌더링 기능으로 추가 마크업, 스토리를 래핑하는 방법
(Story) => (
<div style={{ margin: '3em' }}>
<Story />
</div>
),
],
}
export const 스토리이름 = () => 해당스토리에서 테스트할 인자가 담긴 컴포넌트
(2) jsx 파일 [defaultProps , propTypes]
defaultProps는 처음 storybook이 실행될 때 default Props값을 설정할 수 있습니다.
react에서 기본적으로 제공하는 prop-types를 이용하여 documentation 기능 외에 추가로 storybook안에 옵션, 필수값 등을 설정할 수 있습니다.
1) Position:fixed
해결 :
Component를 싸고있는 iframe의 크기를 설정해줌으로서 해결
문제 :
Storybook에서 컴포넌트를 보여주는 형태는 storybook페이지 안에 iframe을 통해서 다른 html문서를 추가하고 그 안에 컴포넌트가 있는 방식
그래서 position:fixed, bottom:0이 설정되어있는 컴포넌트가 있을 경우에 docs페이지에서 docs페이지 전체의 bottom에 모든 컴포넌트가 위치
파일 빌드
yarn build-storybook
Storybook은 웹 서버에서 제공할 수 있는 정적 웹 애플리케이션을 생성합니다. (로컬에서 미리 확인)
npx http-server ./path/to/build
Chromatic으로 스토리북 출판
Storybook을 정적 웹 앱으로 구축한 후에 웹 호스트에 게시할 수 있습니다.
Chromatic 설치
yarn add --dev chromatic
패키지가 설치되면 깃허브 계정으로 크로마틱에 로그인하고 새로운 프로젝트를 만들고 앞서 설정한 깃허브 저장소 와 동기화합니다.
프로젝트를 위해 생성된 고유한 project-token을 복사해주세요.
빌드
yarn chromatic --project-token=
완료되면 배포된 스토리북의 https://random-uuid.chromatic.com링크를 받으실 것입니다. 해당 링크를 팀과 공유하여 피드백을 받으세요.
참조
스토리북 제대로 활용하기
Storybook 설정하기
Storybook Tutorials
Storybook의 유용함
Links Addon | Storybook: Frontend workshop for UI development
[Storybook] StoryBook을 이용한 컴포넌트 단위 개발 - 기본세팅(CRA + Redux + styled-Component)
[Storybook] 스토리북에 대해 알아보자
스토리북에서 스토리를 작성하는 방법
How to write stories
[addon-docs] Component with position:fixed leaks out from Preview · Issue #8011 · storybookjs/storybook