React + Storybook.js

eunji hwang·2020년 7월 7일
0

REACT

목록 보기
1/16
post-thumbnail

스토리북

참고:

스토리북 == 비주얼테스터

컴포넌트/UI를 상태별로 확인 할 수 있는 라이브러리로 react뿐만아닌 다른 프레임워크에서도 지원된다!
이런거 굳이 알아야 되나? 했지만 막상 간단한 실습만으로도 왜 쓰는지 알 것 같다.

컴포넌트 수정할 때마다 UI가 정삭 작동 하는지 서버켜고 확인하고 코드 수정하고 반복.. 하지않고,
먼저 스토리북에서 props 설정에 따라 반영된 UI를 나열해두고 볼수있고, (일단 여기까지만 실습해봤다)
협업할 때도 공유해서 보기좋은 듯! 나도 보기 좋고!

스토리북 장점

  • UI 컴포넌트의 다양한 예시를 보여줄 수 있다.
  • 다수의 프론트엔드 개발자가 참여한다면 코드이해, 커뮤니케이션에 들이는 비용을 낮춰준다.
  • 다양한 확장도구(addon) 지원 & 직접 구현 가능

설치

npm i -D @storybook/react

package.json


  "scripts": {
    "storybook": "start-storybook -p 9001 -c .storybook",
     ...
  }

스토리북 시작을 위한 스크립트를 추가한다.

사용법

  • src/stories/파일명.js : 스토리 파일을 만든다.
  • /.storybook/config.js : 루트에 .storybook 안에 설정파일 config.js를 생성하여, 스토리파일을 불러들인다.

1. 스토리파일 만들기

// inputStory.js
import React from 'react';
import { storiesOf } from '@storybook/react'; // 스토리북 모듈 가져오기
// 추가할 컴포넌트 가져오기
import Input1 from '../components/Input1'; 
import Input2 from '../components/Input2'; 
import Button1 from '../components/Button1'; 
import Button2 from '../components/Button2'; 

// storiesOf('스토리북에 표시할 스토리이름', module).add('스토리북에 표시할 메뉴이름',()=><해당 컴포넌트 />>)

storiesOf('Input', module)
  .add('기본인풋', () => <Input1 />)
  .add('블랙모드', () => <Input2 />);


// 버튼 UI도 여기에 포함시켰는데.
// ButtonStory.js를 만들고 config.js에서 스토리북에 추가시키길 추전
storiesOf('Button', module)
  .add('기본버튼', () => <Button1 />)
  .add('블랙모드', () => <Button2 />);

스토리 파일은 src/stories폴더에 위치시킨다.

  • storiesOf('좌측-대메뉴', module) : 스토리를 생성한다.
  • .add('좌측-소메뉴', ()=> <추가컴포넌트명/>) : 컴포넌트를 CB으로 전달한다.

2. 스토리북 설정파일

// .storybook/config.js

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

function loadStories() {
  // 여기에 스토리파일을 추가 할 수 있다.
  require('../src/stories/InputStory');
}

configure(loadStories, module);

3. 활용

// src/stories/InputStory.js

...중략

storiesOf('Input', module)
  .add('기본인풋', () => <Input value='기본인풋' />)
  .add('블랙모드', () => <Input value='블랙모드' color='dark' />);

UI의 모습을 props에 따라 다르게 반응하도록 설정하고 스토리북 서버에서 해당 UI를 확인할 수 있다.
협업에도 도움되고, 나도 보기 좋고~!

4. UI Story 구분

  • 컴포넌트 단위 UI 스토리정리 : 컴포넌트(기능) > 포함하는 UI 모두 포함
  • UI 종류단위 스토리정리 : Input, Button 등 종류단위로 UI 구분
  • Story파일은 src/stories 경로에 위치한다.

위 예제에서 InputStory.jsButtonInput을 모두 함께 등록하였다. UI 종류 단위로 스토리를 정리하기위해 분리해보자

  1. stories/InputStory.js : input UI만 담는다
  2. stories/ButtonStory.js : Button UI만 담는다
  3. .storybook/config.js : InputStory, ButtonStoryrequire()한다.
  4. 스토리북 서버에서 확인하면 이전과 동일한 모습으로 정리되어 있다.

5. 스토리북 자동추가 설정

config.js를 수정해 ...Story.js로 끝나는 파일을 자동등록 하도록 설정해보자.

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

// ...Story.js 자동 등록을 위한 모듈
import interopRequireDefault from 'babel-runtime/helpers/interopRequireDefault';

function loadStories() {
  // + 하나씩 추가하는 법
  // require('../src/stories/InputStory');

  // + 자동 추가하는 법
  const context = require.context(
    '../src/stories',
    true,
    /Story\.js$/ || /Story\.jsx$/ // js or jsx
  );
  context.keys().forEach((srcFile) => {
    interopRequireDefault(context(srcFile));
  });
}

configure(loadStories, module);

스토리북 서버를 재부팅 하면 config.js를 수정하지 않아도 추가로 Story가 추가된다.

참고 : require.context()

6. 확장도구(addon) 사용하기

  • addon-actions : 이벤트 작동 테스트를 위한 확장도구
  • addon-jsx : 컴포넌트 사용 코드를 출력을 위한 확장도구

1) 설치

npm i -D @storybook/addons @storybook/addon-actions
npm i -D storybook-addon-jsx

2) 설정

설정파일에 import '확장도구들' 해주지 않으면 백날.. 코드 두드려봐야 스토리북 서버에 확장도구 패널이 나타나질 않는다!

.storybook/addons.js 파일에 import 모듈

// .storybook/addons.js
// 스토리북 확장도구(addon)은 이곳에 추가
import '@storybook/addon-actions/register'
import 'storybook-addon-jsx/register'

3) addon-actions 사용하기

addon-actions github repository

확장도구는 src/stories/...Story.js(x)파일에 적용할 수 있다.
사용전에 2)설정 먼저 진행하는 거 잊지말기!

// inputStory.js
import React from 'react';
import { storiesOf } from '@storybook/react'; // 스토리북 모듈 가져오기

// addon 추가
import { action } from '@storybook/addon-actions';

// 컴포넌트 추가
import Input from '../components/Input'; // 추가할 컴포넌트 가져오기

storiesOf('Input', module)
  .add('기본인풋', () => <Input value='기본인풋' />)
  .add('블랙모드', () => <Input value='블랙모드' color='dark' />)
  .add('onChange예제', () => (
    <Input onChange={action('onChange 이벤트 발생')} /> 
  )); // action()을 사용

4) addon-jsx 사용하기

addon-jsx github repository

사용전에 2)설정 먼저 진행하는 거 잊지말기!

addon-jsx를 사용하기 위해서는 스토리북 설정파일 .storybook/config.js 와 적용할 스토리파일(...Story.js)을 수정해야 한다.


// .storybook/config.js 수정

import { configure } from '@storybook/react';
import interopRequireDefault from 'babel-runtime/helpers/interopRequireDefault';

// addon-jsx를 위한 추가 import
import {setAddon} from '@storybook/react';
import JSXAddon from 'storybook-addon-jsx';

function loadStories() {
  const context = require.context(
    '../src/stories',
    true,
    /Story\.js$/ || /Story\.jsx$/
  );
  context.keys().forEach((srcFile) => {
    interopRequireDefault(context(srcFile));
  });
}

setAddon(JSXAddon) // setAddon 함수호출
configure(loadStories, module);

전체를 보면 좀 길어보이지만 이전 자동 스토리 추가하기 코드에서 딱 3줄 추가되었다.

  • import {setAddon} from '@storybook/react';
  • import JSXAddon from 'storybook-addon-jsx';
  • setAddon(JSXAddon)

// src/stories/...Story.js 스토리 파일들 수정

...생략

storiesOf('Input', module)
  .addWithJSX('기본인풋', () => <Input value='기본인풋' />)
  .addWithJSX('블랙모드', () => <Input value='블랙모드' color='dark' />)
  .addWithJSX('onChange예제', () => (
    <Input
      onChange={action('이벤트 반응!', (e) => console.log(e.target.value))}
    />
  ));
  • 기존 add() 함수를 addWithJSX()로 변경한다. 이후 스토리북 서버 재부팅 하고 확인한다.

7. stylesheet 적용

1) SASS/SCSS

프로젝트의 style을 sass로 진행중이라면 스토리북에서는 sass가 적용되지 않고 보일 것이다.
스토리북을 위해 sass-loader 패키지 설치와 webpack.config.js 설정이 필요하다.

  • npm i -D sass-loader : 스토리북 웹팩 설정을 위해 설치
  • .storybook/webpack.config.js : 스토리북 폴더에 웹팩 설정을 추가
// .storybook/webpack.config.js

const path = require('path');

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        loaders: ['sass-loader'],
        include: path.resolve(__dirname, '../'),
      },
    ],
  },
};
  • ...Story.js 파일에서 적용할 stylesheet 파일 import
// src/stories/...Story.js
// 적용할 스타일 추가
import '../sass/materialize.scss';

2) styled-components

npm i styled-components 패키지 설치 후 하던대로 작성하고 사용하면 됨!


profile
TIL 기록 블로그 :: 문제가 있는 글엔 댓글 부탁드려요!

0개의 댓글