디자인 시스템과 스토리북

sujin·2023년 3월 3일
5

디자인시스템

목록 보기
1/2
post-thumbnail

🤪 우당탕탕 디자인 시스템 도입기~!

입사를 한지도 3개월이 다되어가고 있는 지금 내가 입사하자마자 맡게된 업무는 바로 디자인 시스템을 구축하는 일이었다.

그 당시 디자인 시스템이라는 개념이 나에게는 다소 생소했지만 하면 할수록 고통과 쾌감을 동시에 느낄 수 있는 일이었고 지금은 잠시 디자인 시스템은 뒤로 미뤄두고 다른 일을 맡아서 하고 있지만… 바로 지금이 타이밍이라고 생각해서 디자인 시스템과 새롭게 배운 스토리북에 대해서 까먹기 전에 정리해보려고 한다.



☝🏻 디자인 시스템

디자인 시스템 이란?

디자인 시스템이란 디자인 원칙, 규격, 재사용 가능한 UI패턴과 컴포넌트 코드를 포괄하는 시스템이라고 정의할 수 있다. 단순한 스타일 가이드, 패턴 라이브러리 역할을 하는 디자인 시스템이 있는가 하면, 브랜드 원칙과 UX 원칙에 이르는 하나의 철학을 구성하는 시스템도 있다고 한다.

정리하자면, 디자인 시스템은 정해진 디자인 패턴과 컴포넌트를 재사용하여 제품을 구축과 개선 시간을 단축시켜주는 시스템이다.

디자인 시스템의 필요성

✅ 효율성 확보

디자인 시스템을 사용하면 반복되는 요소들을 매번 만들 필요가 없게된다.

프론트에서 레이아웃 작업을 하다보면 반복되는 요소들(버튼, 인풋박스, 체크박스, 텍스트 스타일 등등…)을 보게되는데 그때마다 매번 일일을 작업을 하는 것은 비효율적이고 귀찮은 일이다.

하지만 디자인 시스템을 구축한다면 재사용 가능한 컴포넌트, 패턴 등을 이용해 반복되는 컴포넌트 제작 시간을 줄이고 전체 제품 개발에 시간을 더 투자하여 더욱 빠르게 제품을 출시 할 수 있다.

✅ 일관성 있는 사용자 경험

디자인 시스템의 원칙에 따라 다른 페이지에서도 일관된 사용자 경험을 구축할 수 있다.

우선, 일관되지 않은 UI는 사용자 경험을 떨어트린다. 물론, 의도에 따라 다른 UI를 사용할 수 도 있지만 비슷한 화면임에도 폰트 사이즈, 굵기, 여백, 외관선의 둥글기 등 사소한 부분들이 다르다면 고객의 신뢰를 잃을 수 있으며 디자인 관리가 제대로 되고 있지 않다는 것을 의미한다.

실제로 과거 프로젝트를 했을 때 팀원들과 페이지를 나눠서 작업하 던 중 같은 레이아웃임에도 불구하고 사전에 커뮤니케이션이 원활하게 이루어지지 않아서 각자의 스타일대로 레이아웃 작업을 했고 나중에 합치고 보니 레이아웃 스타일이(여백, 너비, 높이 등…) 다 달라서 난감했던 경험이 있다 😅

따라서 디자인 시스템을 사용한다면 일관된 UI로 사용자의 경험을 해치는 일은 발생하지 않을 것이다.

✅ 다양한 제품에 대응

디자인 시스템을 통해 효율성과 일관성을 확보함으로써 다양한 규모의 제품들을 빠르고 쉽게 만들 수 있다.

예를 들어 원래 국내에서 서비스를 제공하던 A제품을 똑같이 복제해 해외에서 제공하는 서비스 B제품을 만든다고 했을 때, 디자인 시스템이 구축되어 있지 않은 상태라면 기존의 리소스를 그대로 복사해 사용해야하는 번거로움이 생길 것이다. 또한 새로운 기능을 개발 할 때마다 디자인을 다시 입혀야하는 상황이 초래될 수 있다.

✅ 협업에 기여

디자인 시스템은 디자이너, 개발자, PM등 프로젝트 팀원들 사이의 원활한 커뮤니케이션에 도움을 줄 수 있으며, 공통의 원칙을 숙지하여 협업에 기여할 수 있게 한다.

디자인 시스템을 구축하는 과정에서 UI 컴포넌트를 어떻게 쪼갤지와 이에 대한 네이밍 규칙에 대한 논의를 통해 커뮤니케이션에 오해를 방지할 수 있고 더 빠르고 효율적인 일처리를 할 수 있게 된다.

디자인 시스템이 없을 때는 버튼 하나에 대해서 논의를 하려고 해도 정해진 네이밍이 없기 때문에 ‘로그인 버튼, 확인 버튼, 둥근 버튼’ 등 다양한 이름으로 불려 커뮤니케이션에 혼란을 줄 수 있다. 하지만 디자인 시스템을 통해 네이밍 규칙을 정의한다면 ‘button-primary-large’ 등과 같이 확실한 이름으로 불릴 수 있기 때문에 일을 더 효율적으로 할 수 있다.


✌🏻 스토리북

스토리북 이란?

위에서 디자인 시스템은 재사용 가능한 컴포넌트를 구축하는 시스템을 말한다고 했다. 스토리북은 바로 이런 디자인 시스템을 구축하는데 도움을 주는 도구이다. 스토리북은 개발할 때 사용되는 여러 컴포넌트들을 문서화할 수 있는 오픈 소스 도구이다.

여러 협업되는 과정에서 사용될 수 있는 공통 컴포넌트들부터 시작해서 페이지들도 독립적으로 구축할 수 있기 때문에 개발자들이 개발된 컴포넌트 코드들을 사용하고자 할 때 스토리북은 참고하여 더 편리하게 개발할 수 있다.

스토리북의 필요성

✅ 독립적인 환경

프론트엔드 개발에서 컴포넌트는 외부 상태의 영향을 받지 않는 독립된 개채로서, 독립적인 환경에서도 자신만의 스타일과 상태를 가질 수 있어야한다. 하지만 개발을 하다보면 개발은 컴포넌트 단위로 진행하지만 실제 개발 환경은 페이지 단위로 만들어진다는 점이 있다.

이는 개발된 컴포넌트를 각각의 페이지에서 일일이 테스트해야한다는 문제가 생기게 되고 개발자는 온전히 개발에 집중하지 못하고 컴포넌트의 의존성을 파악하기 어려워 진다.

따라서 이런 문제를 해결하고자 컴포넌트 단위의 개발 환경을 지원해주는 스토리북이 등장하게 되었으며 이를 통해 컴포넌트를 완전히 독립시킬 수있다.

✅ 문서화 작업

스토리북은 Docs 로 문서화를 지원하며 일회성 생명주기를 가진 컴포넌트가 아닌 어떤 구조로 만들어졌고 어떤 속성 변화에 의존하여 UI가 변경되는지 문서화하는 작업이 가능하다.

또한 일반 문서처럼 단순히 설정한 값만 보이게 하는게 아니고 컴포넌트에서 전달받을 수 있는 props도 실시간으로 변경할 수 있으며 이를 통해 개발한 컴포넌트의 다양한 기능을 기획자, 디자이너가 손 쉽게 보고 테스트 할 수 있다.

스토리북 설치

스토리북을 시작하는데는 첫번째, 이미 만든 프로젝트에 스토리북을 설정하는 방법두번째, 스토리북 전용 프로젝트를 만드는 방법이 있는데 두번째 방법으로 해보도록 하겠다.

1. 실습 프로젝트 생성

mkdir 프로젝트 이름

cd 프로젝트 이름

yarn init -y or npm init -y

2.storybook 설치

npx -p @storybook/cli sb init --type react

yarn add react react-dom or npm i react react-dom

3.storybook 실행

yarn storybook or npm run storybook

스토리북을 실행하면 아래와 같은 화면이 나온다.

스토리북 사용하기

스토리북에서 컴포넌트를 어떻게 만들고 사용하는지 간단한 예시를 통해 살펴보자!

✅ typescript 환경세팅

우선 나는 TypeScript 를 사용해서 프로젝트를 진행할 것이기 때문에 추가적으로 TypeScript 를 설치하고 폴더 구조를 변경해 주었다.

// TypeScript 설치
$ yarn add typescript
$ npm install typescript

// TypeScript 프로젝트로 초기화
$ npx tsc --init
$ yarn run tsc --init

그리고 루트 경로에 만들어진 tsconfig.json 파일을 다음과 같이 세팅해주었다.

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "baseUrl": ".",
    "paths": { // 절대 경로 설정
      "src/*": ["src/*"],
      "components/*": ["components/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

💡tsconfig.json 파일을 세팅한 다음 오류가 날 수 있는데 이는 설치된 모듈이 vscode에 바로 적용되지 않아 생기는 오류일 수 있음으로 vscode 창을 껏다가 다시 켜면 해결될 것이다!

마지막으로 .jsx 확장자 파일을 .tsx 확장자 파일로 바꿔주고 폴더 구조도 정리해 주었다.

기존의 stories 디렉토리를 없애고 components 에서 관리될 수 있도록 폴더 구조를 바꿔주었고 이에 따라서 .storybook > main.js 파일도 변경해주었다.

// main.js
module.exports = {
  stories: ["../components/**/*.stories.mdx", "../components/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
  ],
  framework: "@storybook/react",
};

✅ Button 컴포넌트와 스토리 만들기

스토리북 실행시 기본으로 세팅 되어있는 Button컴포넌트에 TypeScript 를 적용해봤다.

// index.tsx
import React from "react";
import "./button.css";

interface buttonProps {
  isActive: boolean;
  backgroundColor: any;
  size: "small" | "medium" | "large";
  label: string;
}

export const Button = ({
  isActive,
  backgroundColor,
  size = "small",
  label,
}: buttonProps) => {
  const mode = isActive
    ? "storybook-button--primary"
    : "storybook-button--secondary";
  return (
    <button
      type="button"
      className={["storybook-button", `storybook-button--${size}`, mode].join(
        " "
      )}
      style={backgroundColor && { backgroundColor }}
    >
      {label}
    </button>
  );
};
//button.stories.tsx
import React from "react";
import { ComponentStory } from "@storybook/react";
import { Button } from ".";

export default {
  title: "components/Button", // 해당 컴포넌트의 경로 
  component: Button, // 컴포넌트 명 
  argTypes: { // 컴포넌트 props control type
		isActive: {options: [true, false], control: {type:"boolean"}},
		size: {options: ["small","medium", "large"], control: {type:"radio"}},
    backgroundColor: { control: "color" }, 
  },
};

const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />;

export const Primary = Template.bind({});
Primary.args = {
  primary: true,
  label: "Button",
};

export const Secondary = Template.bind({});
Secondary.args = {
  label: "Button",
};

export const Large = Template.bind({});
Large.args = {
  size: "large",
  label: "Button",
};

export const Small = Template.bind({});
Small.args = {
  size: "small",
  label: "Button",
};

💡컴포넌트.stories.tsx 파일은 항상 해당 컴포넌트 파일과 같은 경로에 위치시켜서 만들어 줘야한다.


  • canvas 에서는 해당 컴포넌트가 실행되고 있는 모습을 볼 수 있고 props를 실시간을 변경해서 확인할 수 있다.
  • Docs 에서는 해당 컴포넌트의 문서화된 모습을 볼 수 있다.

✨ 마무리

입사하자마 맡았던 일이라 정신없이 완성하기 바빠서 디자인 시스템과 스토리북에 대한 개념 정리를 못하고 넘어간 것이 아쉬웠는데 지금이라도 정리하게 되어서 다행이다…ㅎㅎ 새롭게 알게되거나 공부한 내용을 이렇게 기록을 남겨놔야 나중에 뒤돌아봤을 때 내가 그동안 뭘했는지 알 수 있는거 같다.

나는 프론트 개발자 답게 재사용 가능한 컴포넌트를 정리하고 개발하는 디자인 시스템이 흥미로웠고 개인적으로도 나만의 디자인 시스템을 구축해서 사이드 프로젝트를 할 때 사용해보고 싶은 욕심이 있다.

그 당시 알게된 내용을 그때그때 정리해 놓지 못해서 위의 내용이 과연 다른 사람에게 도움이 될지는 모르겠지만ㅠㅠ 앞으로도 계속해서 기록해 나갈 예정이니 그때는 좀 더 정돈된 내용을 갖고 와야겠다…!!



📚 reference

Storybook Tutorials

profile
개발댕발

1개의 댓글

comment-user-thumbnail
2023년 6월 7일

교내 동아리에서 디자인 시스템을 도입하려고 찾아보는 중이었는데, 정말 깔끔하게 정리해주셔서 잘 배우고 갑니다 감사합니다 🙏

답글 달기