이번에 회사 서비스의 개발 일정이 어느 정도 마무리되어 시간이 남았다. 그동안 바쁘게 개발하느라 하지 못했던 코드 리팩토링을 진행하면서, 협업 시 불편했던 부분을 개선하기 위해 디자인시스템 도입을 추진하게 되었다.
회사에 Storybook을 도입하게 된 이유는 다음과 같다.
이러한 문제들을 해결하기 위해 Storybook을 도입하게 되었으며, 이를 통해 개발 효율성 향상, 코드 중복 감소, UI 일관성 유지 등의 긍정적인 효과를 기대하고 있다.
디자인 시스템을 구축하기 위해 사용할 수 있는 여러 가지 툴이 있지만, 위에 문제들을 해결하려면 UI 컴포넌트 관리 및 문서화가 가능한 툴이 필요했다. 이를 위해 Storybook, Histoire, Ladle 등을 검토했다.
Histoire는 Vue 생태계에서 최적화된 UI 문서화 툴로, 성능이 가볍고 빠르다는 장점이 있다. 하지만, 우리 회사의 서비스는 Vue 기반도 일부 있지만, 대다수의 서비스가 React로 구축되어 있다.
➡️ Vue 전용 툴을 도입하는 것은 비효율적이므로 제외했다.
Ladle은 Storybook보다 가볍고 설정이 간단해 빠르게 적용할 수 있는 장점이 있다. 하지만, 사용자가 많지 않아 레퍼런스가 부족하고 Storybook만큼의 확장성과 커뮤니티 지원이 부족해 이후 유지보수에 어려움이 있을 가능성이 컸다.
➡️ 장기적인 유지보수를 고려해 Ladle은 사용하지 않기로 했다.
결과적으로 Storybook이 가장 적합하다고 판단했다. Storybook을 선택한 이유는 다음과 같다.
✅ 디자인 툴과 연동 가능 → Figma, Zeplin 등과 연결하여 디자이너-개발자 협업 효율성 향상
✅ 다양한 애드온 지원 → 접근성 검사(@storybook/addon-a11y), 인터랙션 테스트 등 기능 확장 가능
✅ 넓은 커뮤니티 및 레퍼런스 → 유지보수 및 개선이 용이
✅ CDD(Component-Driven Development) 방식 적용 가능 → 컴포넌트 단위 개발로 중복 코드 감소
Storybook이 어떤 역할을 하는지 자세히 알아보자.
Storybook은 UI 컴포넌트를 독립적으로 개발하고 문서화할 수 있는 도구로, 개발자와 디자이너 간 협업을 원활하게 만들어준다. 컴포넌트를 하나의 서비스에 종속되지 않고 개별적으로 확인하고 테스트할 수 있어 재사용성과 유지보수성을 높이는 데 효과적이다.
1️⃣ 독립적인 UI 개발 및 테스트
애플리케이션과 분리된 환경에서 UI 컴포넌트를 개별적으로 개발하고 확인할 수 있다.
다양한 상태(Props, Event 등)를 시뮬레이션하여 실제 서비스에서 발생할 수 있는 문제를 미리 검토할 수 있다.
2️⃣ 문서화 및 디자인 시스템 구축
Storybook을 사용하면 컴포넌트별 문서화를 자동화할 수 있어, 새로운 팀원이 쉽게 컴포넌트 사용법을 익힐 수 있다.
디자인 시스템을 체계적으로 관리하여 UI의 일관성을 유지할 수 있다.
3️⃣ 디자이너, 개발자, 기획자 간 원활한 협업
UI를 직접 실행하지 않아도, Storybook을 통해 디자인 피드백을 효율적으로 주고받을 수 있다.
Figma, Zeplin 같은 디자인 툴과 연동하면 디자인과 개발 간의 갭을 줄일 수 있다.
4️⃣ 다양한 UI 상태 및 반응형 테스트 지원
Controls, Viewport, a11y(웹 접근성) 등 다양한 애드온을 통해 다양한 환경에서 UI를 미리 검토할 수 있다.
다크 모드, 다국어 지원, 반응형 레이아웃을 쉽게 테스트할 수 있어 더욱 완성도 높은 UI 개발이 가능하다.
5️⃣ 컴포넌트 재사용성 증가
Storybook을 통해 UI 컴포넌트를 관리하면 여러 프로젝트에서 동일한 컴포넌트를 재사용하기 쉬워진다.
중복 코드 작성이 줄어들어 유지보수 비용을 절감할 수 있다.
Storybook을 설치하려면 먼저 프로젝트에 Storybook 패키지를 추가해야 한다.
npm create storybook@latest
이 명령어로 기본적인 Storybook 설정이 자동으로 추가된다. package.json에 Storybook 관련 스크립트가 추가된다.
Storybook에서 컴포넌트를 관리하려면 각 컴포넌트별로 스토리 파일을 만들어야 한다. 스토리 파일은 .stories.js 또는 .stories.tsx 형태로 작성된다.
예시: Button.stories.js
import React from 'react';
import { Button } from './Button';
export default {
title: 'Example/Button',
component: Button,
};
export const Primary = () => <Button primary>Primary Button</Button>;
export const Secondary = () => <Button>Secondary Button</Button>;
main.js는 Storybook의 핵심 설정 파일로, 애드온 추가, 스토리 파일 위치 지정, Webpack 혹은 Vite 설정 등을 할 수 있다.
module.exports = {
stories: ['../src/**/*.stories.js'], // 스토리 파일 위치 지정
addons: [
'@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/addon-knobs',
], // 사용할 애드온 목록
webpackFinal: (config) => {
// Webpack 커스터마이징 (필요 시)
return config;
},
};
preview.js 파일은 Storybook의 컴포넌트를 렌더링할 때 적용할 전역 데코레이터와 설정을 담당한다. 공통 스타일이나 CSS를 설정할 때 사용한다.
글로벌 스타일 및 폰트, 테마 등을 여기서 설정할 수 있다.
import '../src/styles.css'; // 글로벌 스타일 적용
export const decorators = [
(Story) => (
<div style={{ padding: '20px', backgroundColor: '#f0f0f0' }}>
<Story />
</div>
),
]; // 전역 데코레이터 설정
manager.js는 Storybook의 관리 UI를 커스터마이징하는 파일로, 사이드바, 레이아웃, 색상 등을 설정할 수 있다.
Storybook의 테마를 변경하거나 UI의 색상과 레이아웃을 설정할 수 있다.
import { addons } from '@storybook/addons';
import { create } from '@storybook/theming';
addons.setConfig({
theme: create({
base: 'light',
colorPrimary: '#FF4785', // 사이드바 색상 설정
colorSecondary: '#1EA7FD',
}),
});
아래 명령어로 Storybook을 실행할 수 있다.
npm run storybook
이 명령어로 로컬 서버에서 Storybook을 실행할 수 있고, 브라우저에서 확인할 수 있다. 기본적으로 http://localhost:6006에서 Storybook을 확인할 수 있다.
Storybook에서 다양한 애드온을 사용할 수 있다. 예시로 Action 애드온은 컴포넌트에서 발생하는 이벤트를 기록할 수 있다.
export const ButtonClicked = () => {
action('button-clicked')();
return <Button>Click me!</Button>;
};
https://www.daleseo.com/storybook/
https://storybook.js.org/docs/get-started/install