스토리북에서 Component Story Format (CSF) 란?

스토리북에서 Component Story Format (CSF) 란?

CSF란 스토리북에서 사용하는 포맷이라고 생각하면 된다. 스토리북 5.2버전 이후로 추천하는 스토리 작성 포맷이다. 스토리들은 ES6 모듈 형태로 정의된다. 모든 스토리북 파일(보통 .stories.js) default export와 named export를 섞어서 사용한다. 리액트 네이티브 제외한 모든 프레임워크에서 CSF를 지원하며 리액트 네이티브에서는 기존 버전의 storiesOf API를 사용해야 한다.

Default export

*.stories.js에서 default export로 메타데이터가 담긴 객체를 내보내면 그 정보를 활용해서 스토리북을 구성한다. 이렇게 생겼다.

import MyComponent from './MyComponent'; export default { title: 'Path/To/MyComponent', component: MyComponent, decorators: [ ... ], parameters: { ... } }

title : 여기에 적어준 경로대로 스토리북 네비게이션에 표시된다.

component: 이 스토리 그룹에서 이 컴포넌트를 사용한다. 라고 알려주기 위해서 넣는것같은데 굳이 지정 해주지 않아도 잘 동작하고 심지어 다른 컴포넌트를 넣어도 잘 동작하는걸 봐서 아직까진 왜 필요한지 정확히는 모르겠다.

decorators: 여기에 스토리북 애드온을 정의할 수 있다.

parameters: custom metadata이다. 스토리북은 기본적으로 default로 export된 객체에 적힌 metadata를 참고하는데 그 metadata와 함께 여기에 적어준것들을 추가로 참고하게 만들 수 있다.

Named story exports

CSF와 함께 모든 named export된 스토리들은 하나의 스토리를 나타낸다.

import MyComponent from './MyComponent'; export default { ... } export const Basic = () => ; export const WithProp = () => ;

named export된 Basic과 WithProp는 스토리로 표시된다. 근데 자바스크립트상에서 이름을 표현하는데 한계가 많기 떄문에 내가 어떤 이름으로 스토리북에 표시할건지 다음과 같이 지정해줄수있다.

import MyComponent from './MyComponent'; export default { ... } export const Basic = () => ; Basic.story = { name: '특수문자도 가능합니다!' }

이렇게 이름을 지정해주지 않으면 스토리북은 스토리의 이름을 다음과 같이 "start case"로 해석한다. (파스칼 케이스와 비슷한듯?)

name -> 'Name' someName -> 'Some Name' someNAME -> 'Some NAME' some_custom_NAME -> 'Some Custom NAME' someName1234 -> 'Some Name 1234' someName1_2_3_4 -> 'Some Name 1 2 3 4'

카멜케이스에서 첫문자를 대문자로 만들고 언더바는 공백으로 대체하는것?외엔 특이한게 없는것같다.

스토리 단위로도 decorators와 parameters를 지정할 수 있다.

export const Simple = () => ; Simple.story = { name: 'So simple!', decorators: [ ... ], parameters: { ... } };

스토리북이 자동으로 이름을 지정하게 할 것인가 vs 내가 스토리의 이름을 지정할것인가?

둘은 미묘하게 다르다. story.name 을 지정하게 되면 보여지는 이름만 달라지고(display name) 내부적으로 스토리북이 관리하는 스토리에 대한 ID는 달라지지 않는다.

다음과 같은 상황에서 스토리의 name을 커스텀하면된다.

1. 자바스크립트에서 허용하지 않는 특별한 문자를 사용하고 싶을때 (이모지, 특수문자, 예약어 등)

2. display name과 스토리의 ID를 따로 관리하고 싶을때 (스토리의 ID를 안정적으로 유지하는것이 다른 라이브러리와의 충돌 가능성을 줄여준다.)

스토리가 아닌것을 export하고 싶을땐?

import React from 'react'; import MyComponent from './MyComponent'; import someData from './data.json'; export default { title: 'MyComponent', component: MyComponent, includeStories: ['SimpleStory', 'ComplexStory'] } export const simpleData = { foo: 1, bar: 'baz' }; export const complexData = { foo: 1, { bar: 'baz', baz: someData }}; export const SimpleStory = () => ; export const ComplexStory = () => ;

이 예제를 살펴보면 SimpleStory, ComplexStory 뿐만 아니라, 각 스토리에서 필요한 데이터를 named export 해주고 있다. 아무런 메타데이터 설정 없이 이렇게 하면 스토리북은 모든 named export를 스토리로 생각하기 때문에 에러가 날 것이다. 하지만 상단에 default export 메타데이터 부분에 includeStories란에 SimpleStory와 ComplexStory를 지정해줬기 때문에 스토리북이 이 두개의 스토리만 스토리로 인식할 수 있게 되는 것이다. 데이터는 다른곳에서 가져와서 사용할 수 있게 되었다.

아래 방식대로 정규 표현식도 사용 할 수 있다.

includeStories: ['SimpleStory', 'ComplexStory'] includeStories: /.*Story$/ excludeStories: ['simpleData', 'complexData'] excludeStories: /.*Data$/

포함할 스토리, 제외할 스토리를 스토리의 이름 또는 정규표현식으로 지정하면 된다.

출처

https://storybook.js.org/docs/formats/component-story-format/

from http://simsimjae.tistory.com/394 by ccl(A) rewrite - 2020-03-25 16:20:17

댓글

이 블로그의 인기 게시물

단위 테스트 환경 구축

Coupang CS Systems 채용 정보: Front-end 개발자를 찾습니다!

스토리북에서 스토리를 작성하는 방법