컴포넌트 관리의 필요성과 스토리북 도입배경
입사 초기에 다른 개발자님이 스토리북 작성하는 법에 대해 간단히 알려준 적이 있었다.
하지만 나는 스토리북의 쓰임새에 공감하지 못했고 스프린트 하기도 바쁜데 스토리북으로 컴포넌트 관리까지 해야 한다는 것에
공감하지 못했고, 흐지부지 되어서 스토리북은 머릿속에서 사라졌다.
어느새 나도 곧 2년 차 개발자가 될 정도로 시간이 흐르면서 여러 사람들과 프로젝트를 동시에 진행하고
두세 개의 다른 프로젝트 환경을 겪으면서 불편함이 느껴지기 시작했다.
가장 큰 불편함은 이미 구현되어 있는 재사용 컴포넌트를 내가 찾지 못해서 다시 만드는 경우가 있었고
기획자나 디자이너가 생각하기에는 예전에는 요구사항에 있었던 건데,
내가 새로만든 컴포넌트는 과거의 요구사항들을 충족하지 못하니 두 번 소통해야 하는 일들이 생겼다.
그리고 동시에 작업을 진행하는 다른 개발자와 비슷한 기능을 가진 컴포넌트를 동시에 만드는 일도 있었다.
다른 개발자에게 "이런 역할을 하는 버튼은 여기서 쓰시면 됩니다", "저런 역할을 하는 캘린더는 이거 쓰시면 됩니다"
하는 식의 소통이 점점 많아졌고 폴더 여기저기에 산재해 있는 비슷한 컴포넌트가 굉장히 신경이 쓰였다.
두 번째 이유는 우리 회사도 곧 ui라이브러리를 따로 관리할 계획이므로 스토리북을 미리 적용해 보고 싶기도 했다.
그래서 나는 이런 상황을 해결하고 생산성을 조금이라도 높일 수 있는 방법이 필요했고, 스토리북을 이제야 보게 되었다.
스토리북은 여러가지 에드온도 있고 테스트도 가능한 툴이지만
내가 불편함을 겪는 이유는 컴포넌트를 시각적으로 관리하고 다른 사용자도 쉽게 사용할 수 있게 하기 위함이므로
최대한 진입장벽이 낮게 하고 다른 개발자들도 쉽게 참여할 수 있는 정도로만 시작하기로 했다.
그렇다면 가장 중요한것은 어떤 컴포넌트에 스토리가 필요한지 명확히 하는 것이라고 생각했다.
원래 하고싶은대로 하세요가 가장 어려운 법이니까..
나는 재사용컴포넌트에 대해 알고 싶다. 어떤 컴포넌트가 있는지, 어떻게 쓰는 건지 알고 싶다.
재사용 컴포넌트를 폴더단위로 구분하기 위해 Atomic Pattern을 사용했다.
현재 진행 중인 프로젝트에는 Atoms, Molecules, Organisms, Templates, Pages폴더까지 나눌 필요가 없다고 판단했다.
Atoms, Molecules에서 모든 재사용 컴포넌트를 관리하고 Organisms은 기능과 결합되어 재사용이 될 확률이 낮고 page에
바로 들어가는 파일을 관리하기로 했다.
그러면 자연스럽게 사용자(다른 개발자)는 Atoms, Molecules이 궁금하다.
Atoms의 각 파일을 폴더단위로 구분하여 스토리북파일과 함께 위치한다.
앞으로 재사용 컴포넌트가 필요하면 스토리북에서 기존에 만들어진 게 있는지 확인한 후 없다면 atoms나 molecules에 만든다.
그리고 꼭 스토리북을 추가하여 다른 사용자에게도 알려준다.
import type { Meta, StoryObj } from '@storybook/react';
import InputBox from '.';
const meta: Meta<typeof InputBox> = {
component: InputBox,
tags: ['autodocs'],
parameters: {
layout: 'centered',
},
};
export default meta;
type Story = StoryObj<typeof InputBox>;
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/react/api/csf
* to learn how to use render functions.
*/
export const Primary: Story = {
args: {
keyword: 'value 입니다',
handleChange: () => {},
title: '제목',
},
};
export const Disabled: Story = {
args: {
handleChange: () => {},
title: '제목',
disabled: true,
placeholder: '입력불가',
},
};
args로 props를 각기 다르게 부여해서 사용자에게 어떻게 사용할 수 있는지 알려주고
export const NoFuture: Story = {
render: () => {
const { date, setDate, handleChangeDate } = useDateControl();
return (
<Calender
date={date}
setDate={setDate}
handleChangeDate={handleChangeDate}
preventFuture
/>
);
},
};
위처럼 훅과 결합되는 경우에는 render함수를 통해 jsx를 랜더링 할 수도 있다.
yarn storybook
스토리북을 설치하면 알아서 스크립트를 추가해 준다. yarn storybook 스크립트를 입력하면 6006 포트에서 아래 화면이 나온다.
이렇게만 관리해도 다른 개발자에게 "이런 컴포넌트 혹시 있나요..?"라고 물어보지 않아도
중복되지 않게 컴포넌트를 한눈에 파악할 수 있어서 생산성이 좋아질 것으로 기대한다.