Atomic Design과 Storybook

Do Ho Kim·2021년 9월 12일
0

작년 네이버 커넥트재단에서 열린 부스트캠프에 Final Project 때 Atomic Design과 Storybook을 사용했던 경험에 대해서 소개한 글입니다.

Atomic Design이란?

Atomic Design이란 원자가 결합해서 분자가 되는 것처럼 단계를 나눠 작은 컴포넌트를 만들고, 그것들을 결합해 조금 더 큰 단위의 뷰를 만드는 방법론이며, 5개의 구분된 단계가 있습니다.

출처: https://brunch.co.kr/@ultra0034/63

Atoms(원자)

원자는 물질의 기본 구성 요소로, label, input, button과 같은 HTML tag입니다.

Molecules(분자)

분자는 원자들이 함께 결합한 것이며, 화합물의 가장 작은 기본단위입니다. 분자들은 그 자체의 특성이 있습니다.

Organisms(유기체)

유기체는 비교적 복잡하며 인터페이스에서 구분된 영역을 형성하는 서로 결합되어 있는 분자 그룹입니다.

Templates

템플릿은 주로 페이지를 구성하기 위해 서로 묶인 유기체 그룹으로 구성되며, 디자인 확인 및 레이아웃 동작을 볼 수 있습니다.

Pages

페이지는 템플릿의 특정 인스턴스로, 사용자가 보는 디자인을 정확하고 구체적으로 구현합니다.

Atomic Design을 도입하게 된 이유

슬랙을 구현하면서 프로필 이미지나 메시지, 입력창 등 일관된 디자인의 컴포넌트들이 많다고 생각했습니다. 또한 재사용 가능한 컴포넌트를 만들면 불필요한 코드 중복을 줄이고, 개발 생산성을 높일 수 있다고 판단했기 때문에 Atomic Design을 도입하기로 했습니다.

Atomic Design의 각 단계를 나누는 기준에 대한 고민

처음에는 Atomic Design을 도입했을 때 어떤 기준을 가지고 각 단계를 나눠서 구현해야 할지 고민했었습니다.

페이지별로 필요한 컴포넌트들을 나누는 게 좋겠다고 판단을 해서 채팅방 페이지, 채널 리스트 페이지 등 화면 단위로 요구사항을 먼저 나누고, 그 안에서 채널 검색창과 채널 리스트 등 보이는 큰 단위로 Organisms를 정했습니다.

정해진 Organism를 구성하고 있는 컴포넌트를 잘게 나눠 Atom을 먼저 구현하고, Atom들이 모여서 Molecule이 되고, Molecule이 모여서 Organism가 되도록 기준을 잡았습니다.

하지만 시간이 지날수록 각 단계를 나누는 기준이 굉장히 어려워졌던 것 같습니다.

Storybook의 도입


Atomic Design Pattern을 쓰면서 많은 컴포넌트들이 생성되고 협업을 위해서는 다른 컴포넌트들이 무엇이 있는지 확인할 수 있는 장치가 필요했습니다. 그래서 Storybook을 도입하게 되었습니다.

이를 통해 많은 컴포넌트를 시각적인 Testing이 가능했고 다른 팀원과 원활한 소통이 가능해졌습니다.

폴더 구조 잡기

Atomic Design을 적용해 계층 구조를 기반으로 컴포넌트를 작성하기 위해서 atoms - molecules - organisms - templates - pages 로 FE 디렉터리 구조를 잡았습니다.

client
├── env
├── public
│   └── imgs
└── src
    ├── common
    │   ├── constants
    │   ├── socket
    │   │   ├── emits
    │   │   └── types
    │   ├── store
    │   │   ├── actions
    │   │   ├── reducers
    │   │   ├── sagas
    │   │   └── types
    │   ├── theme
    │   └── utils
    ├── components
    │   ├── atoms
    │   ├── molecules
    │   ├── organisms
    │   └── templates
    ├── pages
    └── shared

구현 예시


ActiveProfileImg 컴포넌트는 Side Bar의 DM 목록과 화면 우측 상단 로그인된 사용자의 상태를 나타내는 부분에 사용되는 컴포넌트입니다.

  1. 먼저 atoms에 가장 간단한 ActiveLight 컴포넌트와 ProfileImg 컴포넌트 구현했습니다.
/* client\src\components\atoms\ProfileImg\ProfileImg.tsx */

import React from 'react';
import styled from 'styled-components';
import Logo from '@imgs/logo.png';
import { color } from '@theme/index';

interface ProfileImgProps {
  size?: 'small' | 'medium' | 'large';
  isHover?: boolean;
  src?: string;
}

// 생략

const ProfileImg: React.FC<ProfileImgProps> = ({ size = 'medium', isHover = false, src = Logo, ...props }) => {
  return (
    <ProfileImgContainter size={size} isHover={isHover} {...props}>
      <Img size={size} isHover={isHover} src={src}></Img>
    </ProfileImgContainter>
  );
};

export { ProfileImg, ProfileImgProps };
  1. 구현한 컴포넌트의 디자인을 Storybook을 통해 쉽게 확인하기 위해 ActiveLight.storiesProfileImg.stories 작성했으며, 이를 통해 각 컴포넌트의 디자인을 수정하면서 효율적으로 개발을 했습니다.
/* client\src\components\atoms\ProfileImg\ProfileImg.stories.tsx */

import React from 'react';
import { Story, Meta } from '@storybook/react/types-6-0';
import { ProfileImg, ProfileImgProps } from './ProfileImg';

export default {
  title: 'atom/ProfileImg',
  component: ProfileImg
} as Meta;

const Template: Story<ProfileImgProps> = (args) => <ProfileImg {...args} />;

export const LargeProfileImg = Template.bind({});
LargeProfileImg.args = {
  size: 'large'
};

export const MediumProfileImg = Template.bind({});
MediumProfileImg.args = {
  size: 'medium'
};

export const SmallProfileImg = Template.bind({});
SmallProfileImg.args = {
  size: 'small'
};
  1. 구현된 ActiveLight 컴포넌트와 ProfileImg 컴포넌트를 활용해서 molecules에 ActiveProfileImg 컴포넌트를 구현했습니다. 마찬가지로 ActiveProfileImg.stories을 작성해 Storybook을 통해 디자인 수정 및 테스트를 진행했습니다.

느낀 점

처음에는 Atomic Design의 각 단계를 어떤 기준으로 나눠야 할지 고민이 많았는데, 직접 가장 작은 컴포넌트부터 제작하고, 제작된 컴포넌트들을 합쳐서 더 큰 뷰를 구성하는 과정에서 블록을 조립해나가듯 합쳐가는 과정이 재미있게 느껴졌습니다.

또한, 모달창이나 버튼과 같이 공통으로 사용되는 컴포넌트들을 만들어 재사용함으로써 코드 중복을 줄이고 생산성을 높일 수 있었으며, Storybook 또한 Atoms나 Molecules 같은 작은 단위의 컴포넌트들을 제작할 때 많은 도움이 되었습니다.

하지만 구조적인 부분에 있어서 이렇게까지 나눌 필요가 있었나? 하는 생각은 떠나지 않았던 것 같습니다.

마치며

Atomic Design을 도입하면서 화면 전체에서부터 아래로 내려가며 디자인을 설계하던 기존 방식과는 다르게 작은 컴포넌트부터 제작함으로써 훨씬 체계적으로 컴포넌트 설계를 진행할 수 있었습니다. 또한 Atomic DesignStorybook은 협업 관점에서 굉장히 잘 어울린다고 생각했습니다.

한편으로 Atomic Design의 각 단계를 어떤 기준으로 나눠야 할지 고민하면서 꼭 5단계가 아니더라도 프로젝트의 규모나 필요에 따라서 단계를 줄여서 사용해볼 수 있을 것 같다는 생각이 들었습니다. 실제로 기업에서도 Atomic Design을 부분적으로 도입해 프로젝트에 맞게 전략적으로 단계를 나누는 경우가 있다고 들었습니다.

Atomic Design의 장점을 최대한으로 가져가기 위해 어떻게 하면 재사용 가능한 컴포넌트를 만들 수 있을지, 단계는 어떻게 나눠야 할지 고민할 수 있었던 좋은 시간이었으며, 앞으로 Atomic Design을 적용해야 할 일이 있다면 이번 프로젝트를 하면서 느꼈던 고민이 많은 도움이 되리라 생각됩니다.

profile
Front-End Developer

0개의 댓글