[React] CDD

sywoo0109·2023년 7월 17일
0

React

목록 보기
5/7
post-thumbnail

1. CDD

  리액트는 컴포넌트라는 단위를 기반으로 개발할 수 있는 라이브러리라고 했었다. 그 이전에 이런 라이브러리가 등장한 방법론이 바로 CDD(Component Driven Development)이다. 컴포넌트를 중심으로 기능적으로 독립된 컴포넌트를 개별적으로 설계, 개발, 테스트해가면서 전체 어플리케이션을 구현해 나가는 것이 이 방법론의 핵심이다. 리액트를 사용하면서 컴포넌트 단위로 계획하고 개발하는 것이 어떤 느낌인지 알 수 있었을 것이다. 한편 스타일링을 담당하는 CSS는 컴포넌트가 많아질수록 같이 복잡해질텐데 일관된 패턴에 대한 요구도 당연히 생겼을 것이다. 이렇게 CSS를 구조화하기 위한 CSS 전처리기라던가 SASS등의 기술이나 BEM, OOCSS 등의 컨벤션이 등장했지만 CSS의 용량이 지나치게 커지거나 컨벤션을 지키기 위해서 선택자가 지나치게 길어지는 등의 문제점이 발생했다. 궁극적으로는 CSS 코드를 캡슐화시킬 수 있는 개념이 필요했고 CSS 코드를 자바스크립트 코드 안에 작성하고 관리하는 개발 패턴인 CSS-in-JS 등장하게 되었다. 배경 설명은 여기까지 하고 이제 실제로 CDD 방법론에 따른 유용한 도구들의 활용법에 대해서 알아보려고 한다.

2. Styled Components

  Styled Components는 리액트에서 사용할 수 있는 CSS-in-JS 라이브러리이다. CSS 코드를 자바스크립트 코드 안에 작성한다는 방법론에 따라 컴포넌트 단위로 스타일링을 적용할 수 있으며 자바스크립트 코드 안에서 더 자유롭게 동적으로 스타일을 생성 및 변경하기도 편하며 다른 컴포넌트에 재사용까지 가능한 장점을 가지고 있다. 이 역시 외부 라이브러리이기 때문에 패키지 매니저를 통해 설치하고 원하는 자바스크립트 파일 상단에서 import 하면 바로 사용할 수 있다.

  위의 코드는 Styled Components를 사용하는 간단한 예시이다. 예시에서 볼 수 있는것처럼 스타일링을 적용했음에도 별도의 CSS 코드는 들어있지 않다. 리액트를 사용하면서 HTML과 자바스크립트를 합친 것에 이어 CSS-in-JS 라이브러리를 사용하면 CSS까지 하나로 합쳐서 한 개의 파일에서 관리가 가능한 것이다. 컴포넌트를 생성하는 것도 styled.(태그)로 간편하게 설정할 수 있으며 리액트의 여타 컴포넌트를 생성하는 것과 방법은 같다. 또한 해당 컴포넌트를 다른 컴포넌트에 쉽게 재활용 가능하며 그런 경우 기존 컴포넌트의 CSS 속성들이 전부 복사되며 여기에 필요한 속성들만 추가해서 사용할 수 있다. 또한 Styled Components로 생성한 컴포넌트 역시 속성을 받을 수 있으며 위의 예시처럼 삼항연산자의 조건문으로 활용할 수도 있고 값만 적당하다면 아예 CSS 속성의 값으로 사용하는 것도 가능하다. 예시에 한 가지 독특한 점을 찾아보라면 GlobalStyle 컴포넌트가 있는데 이것은 GlobalStyle.js라는 같은 디렉토리 내의 다름 폴더에서 가져온 것이다. 이것은 전역 스타일을 생성하는 간단한 예시로 Styled Components에서 createGlobalStyle을 불러와서 여기서 CSS 속성들을 설정하고 최상위 컴포넌트에서 상단에 배치하면 모든 컴포넌트에서 공유하는 전역 스타일링을 설정할 수 있다. 예시에서는 단순히 버튼들에 공통적인 스타일링을 설정했지만 전에 말했던 CSS 레아이웃 리셋 코드 등 전역적으로 필요한 스타일링을 Styled Components를 사용해도 적용할 수 있는 방법이다.

3. Storybook

  Storybook은 CDD가 트렌드로 자리 잡게 되면서 사용되기 시작한 UI 컴포넌트를 개발하고 문서화하기 위한 개발 도구이다. Storybook은 컴포넌트를 분리하고 독립적으로 개발, 시각화, 문서화할 수 있도록 도와주는 기능들을 가지고 있다.

npx storybook@latest init

  우선 Storybook을 설치한다. 이 명령어는 디렉토리 내의 package.json을 보고 사용 중인 라이브러리에 맞는 환경을 알아서 만들어주기 때문에 포스팅에서는 리액트를 기준으로 설명하지만 Vue, Angular와 같은 프론트엔드 프레임워크를 사용하는 프로젝트에서도 동일하게 사용할 수 있다. 설치가 완료되면 프로젝트 디렉토리 내부에 /.storybook 폴더와 /src/stories 폴더가 생성된다. /.storybook 폴더에는 Storybook 관련 설정 파일이 있고 /src/stories 폴더에는 Storybook 예시 파일들이 있다.

npm run storybook

  리액트 프로젝트를 로컬 서버로 켜듯이 Storybook을 실행시키면 localhost의 6006번 포트로 Storybook이 실행된다.

  위의 사진처럼 Storybook이 실행된 것을 볼 수 있다. 아직은 Storybook에 코드를 추가하지 않아서 미리 만들어진 예시만 확인할 수 있는데 버튼의 속성을 변경하거나 배경 색을 변경하는 등 따로 코드를 입력하지 않고도 컴포넌트를 시각화하고 테스트해 볼 수 있는 환경을 구현할 수 있다는 것을 알 수 있다. 만약 직접 작성한 컴포넌트들을 Storybook에 올려서 테스트하고 싶다면 같은 이름에 확장자는 .stories.js인 파일을 생성하면 된다.

import Title from "./Title";

// title : 스토리 분류
// component : 스토리에 사용되는 컴포넌트
export default {
  title: "Practice/Title",
  component: Title,
};

// 템플릿 생성
const Template = (args) => <Title {...args} />;

// 스토리 생성
// .bind({})는 스토리를 생성하면서 컴포넌트에 초기값을 바인딩하고 상태를 관리하는 정해진 문법
export const RedTitle = Template.bind({});

// 전달인자 작성
RedTitle.args = {
  title: "Red Title",
  textColor: "red",
};

// 또다른 스토리 생성 방법
export const Default = () => <Button>Default Button</Button>;

  위의 예시는 Title이라는 직접 작성한 컴포넌트를 Storybook에 올려서 컴포넌트 스토리를 작성하는 예시이다. 우선 원하는 컴포넌트를 import 한 뒤에 기본적인 설명을 작성한다. title은 스토리의 이름이고 component는 스토리에 사용되는 컴포넌트를 말한다. 이 항목에는 그 이외에도 컴포넌트에 필요한 전달인자의 종류와 타입을 지정하는 argTypes도 있으니 필요에 따라서 더 작성할 수 있다.

  스토리를 생성하는 방법은 크게 두 가지가 있는데 먼저 첫 번째 방법은 컴포넌트 템플릿을 정의하고 그것을 다른 스토리에 바인딩하는 방식이다. 이를 위해 템플릿 역할을 할 함수를 하나 선언하고 필요한 정의를 작성한다. 예시에서는 Title이라는 컴포넌트에 전달인자를 받아서 속성으로 전달하기 위해 템플릿을 작성했다. 이후 스토리를 생성하고 미리 작성한 템플릿을 바인딩해서 초기값을 설정할 수 있다. 이후에 전달인자에 들어갈 내용을 작성해주면 된다.

  다른 방법은 스토리를 직접 선언하는 방식으로 컴포넌트를 아예 직접 렌더링하는 방법이다. 위의 예시에서는 단순한 버튼 하나를 생성했으며 보통은 초기값을 설정할 필요 없는 컴포넌트를 렌더링하는 간단한 스토리에 적합하다. 당연히 위의 템플릿을 사용하는 방식이 템플릿 자체도 재사용할 수 있고 컴포넌트에 초기값을 설정해서 다양한 상태를 시각화할 수 있기 때문에 초기값이 필요없는 아주 간단한 컴포넌트가 아닌 이상 위의 방법을 택하는 편이 유용하다.

2개의 댓글

comment-user-thumbnail
2023년 7월 18일

가치 있는 정보 공유해주셔서 감사합니다.

답글 달기
comment-user-thumbnail
2023년 7월 18일

좋은 글 잘 읽었습니다, 감사합니다.

답글 달기

관련 채용 정보