S3. CDD 개발 도구 개요(Styled Components와 Storybook)

Haizel·2023년 2월 13일
0

Front-End Developer 되기

목록 보기
52/70
post-thumbnail

React로 CDD 할수 있는 대표적 도구인 Styled Components의 사용법과,
컴포넌트들을 문서화하고 관리할 수 있는 도구인 Storybook의 사용법을 알아보자.

01. **Styled Components**


  • Styled ComponentsCSS를 컴포넌트화해 React 환경에서 사용 가능한 라이브러리이다.

  • CSS in JS” 개념에서 파생된 라이브러리로, Styled Components를 사용하면 CSS도 javaScript 안에 넣어줄 수 있어

    ⇒ “HTML + JS + CSS” 까지 묶어 하나의 JS파일 안에서 컴포넌트 단위로 개발이 가능하다.

🔨 1. Styled Components 설치하기

  1. 터미널에 명령어 입력
# with npm
$ npm install --save styled-components
  1. package.json에 아래 코드를 추가
  • 필수는 아닌 권장사항으로써, 아래 코드를 추가하면 여러 버전의 Styled Components가 설치 시 발생하는 문제를 줄여준다.
{
  "resolutions": {
    "styled-components": "^5"
  }
}
  1. Styled Components를 사용할 파일로 불러온다.
import styled from "styled-components"

🔨 2. Styled Components 문법

🔧 2-1. 컴포넌트 만들기

  • Styled Components는 ES6의 Templete Literals 문법을 사용해 → 따옴표가 아닌 백틱(`)을 사용한다.
1)컴포넌트를 선언한 후
2)**styled.태그종류** 를 할당하고
3)백틱 안에 기존 CSS와 같이 스타일 속성을 작성한다.
4)완성한 컴포넌트는 react 컴포넌트를 사용하듯 리턴문 안에 작성해주면
=> 스타일이 적용된 컴포넌트가 렌더된다.
  • 예시
import styled from "styled-components";

//Styled Components로 컴포넌트를 만들고
const BlueButton = styled.button**`**
  background-color: blue;
  color: white;
**`**;

export default function App() {
  // React 컴포넌트를 사용하듯이 사용하면 됩니다.
  return <BlueButton>Blue Button</BlueButton>;
}

🔧 2-2. 컴포넌트를 재활용해 새로운 컴포넌트 만들기

  • 이미 만들어진 컴포넌트를 재활용하고 싶다면?
1)컴포넌트를 선언하고 
2)styled() 에 재활용할 컴포넌트를 전달한 다음
3)추가하고픈 스타일 속성을 작성한다.
  • 예시
import styled from "styled-components";

const BlueButton = styled.button`
  background-color: blue;
  color: white;
`;

//만들어진 컴포넌트를 재활용해 컴포넌트를 만들 수 있습니다.
const BigBlueButton = styled(BlueButton)`
  padding: 10px;
  margin-top: 10px;
`;

//재활용한 컴포넌트를 재활용할 수도 있습니다.
const BigRedButton = styled(BigBlueButton)`
  background-color: red;
`;

export default function App() {
  return (
    <>
      <BlueButton>Blue Button</BlueButton>
      <br />
      <BigBlueButton>Big Blue Button</BigBlueButton>
      <br />
      <BigRedButton>Big Red Button</BigRedButton>
    </>
  );
}

🔧 2-3. Props 활용하기

  • Styled Component로 만든 컴포넌트도 react 컴포넌트처럼 props를 내려줄 수 있고, 내려준props 값에 따라 컴포넌트를 렌더링할 수 있다.
  • Styled Components는 템플릿 리터럴 문법( **${ }**)을 사용해 JavaScript 코드를 사용할 수 있다.
    • props를 받아오려면? → props를 인자로 받는 함수를 만들어 사용한다.
      const 컴포넌트이름 = styled.태그종류`
        css 속성 : ${(props) => 함수코드}
      `

2-3-☝️. Props로 조건부 렌터링하기

  • 예제)
    • 삼항연산자를 활용해 <Button>컴포넌트에 skyblue라는 props가 있는지 확인하고

      → 있다면 배경색을 skyblue로, 없다면 white로 지정해준다.

const Button = styled.button `
  background: ${(props) => props.skyblue ? "skyblue" : "white" }
`;
  • 전체코드
import styled from "styled-components";
import GlobalStyle from "./GlobalStyle";

//받아온 prop에 따라 조건부 렌더링 가능하다.
const Button1 = styled.button`
  background: ${(props) => (props.skyblue ? "skyblue" : "white")};
`;

export default function App() {
  return (
    <>
      <GlobalStyle />
      <Button1>Button1</Button1>
      <Button1 skyblue>Button1</Button1>
    </>
  );
}

2-3-✌️.  Props 값으로 렌더링하기

  • props의 값을 통째로 활용해 컴포넌트 렌더링에 활용할 수 있다,
  1. 삼항연산자 사용하기
  • props.color 가 없다면 white를 ↔  props.color 가 있다면 props.color에 있는 스타일 속성 값 그대로를 리턴해준다.
const Button = styled.button`
 background: ${(props) => props.color ? props.color : "white"}
 `;
  1. 함수 코드 사용하기
  • 삼항연산자 외에도 JavaScript 코드 무엇이든 사용할 수 있으므로 → 원하는 값을 리턴하는 함수 코드를 만들어 사용할 수 있다.
  • 또한 props도 원하는 만큼 받아서 사용 가능하다.
const Button = styled.button`
 background: ${(props) => props.color || "white"}
 `;

2-3-🤟. 최종 코드

import styled from "styled-components";
import GlobalStyle from "./GlobalStyle";

//받아온 prop 값을 그대로 이용해 렌더링할 수도 있습니다
const Button1 = styled.button`
  background: ${(props) => (props.color ? props.color : "white")};
`;
//다음과 같은 형식으로도 활용할 수 있습니다.
const Button2 = styled.button`
  background: ${(props) => props.color || "white"};
`;

export default function App() {
  return (
    <>
      <GlobalStyle />
      <Button1>Button1</Button1>
      <Button1 color="orange">Button1</Button1>
      <Button1 color="tomato">Button1</Button1>
      <br />
      <Button2>Button2</Button2>
      <Button2 color="pink">Button2</Button2>
      <Button2 color="turquoise">Button2</Button2>
    </>
  );
}

🔧 2-4. 전역 스타일 설정하기

  • 스타일을 컴포넌트가 아닌 전역에 설정하고 싶다면?
  1. Styled Components에서 createGlobalStyle함수를 불러온다.
import { createGlobalStyle } from "styled-components";
  1. **createGlobalStyle 의 스타일을 설정한다.**
const GlobalStyle = createGlobalStyle`
	button {
		padding : 5px;
    margin : 2px;
    border-radius : 5px;
	}
`
  1. 만들어진 <GlobalStyle> 컴포넌트를 최상위 컴포넌트에서 사용하면 → 전역에 <GlobalStyle>컴포넌트의 스타일이 적용된다.
function App() {
	return (
		<>
			**<GlobalStyle />**
			<Button>전역 스타일 적용하기</Button>
		</>
	);
}

✍🏻 CSS → Styled Components의 컴포넌트로 바꾸기

import styled from "styled-components";
import { createGlobalStyle } from "styled-components";

//1. createGlobalStyle로 전역 스타일을 설정하고,
const GlobalStyle = createGlobalStyle`
 button {
  margin: 0.5rem;
  padding: 1rem;
  font-size: 2rem;
  border-radius: 1rem;
  transition: 0.5s;
 }
`;

//2. Styled Components로 컴포넌트를 만든다.
const Button = styled.button`
  background-color: powderblue;
  color: black;
  &:hover {
  background-color: cornflowerblue;
  color: white;
  transition: 0.5s;
   }
  ` ;

export default function App() {
  return (
   <>
    <GlobalStyle/>
  <Button id="practice">Practice!</Button>
   </>
  )
}

https://codesandbox.io/s/unruffled-tree-yiwv4?from-embed=&file=/src/App.js

💡 hover 속성 → Styled Components 컴포넌트에 적용하는 방법

import styled from "styled-components";

const Button = styled.button`
 & :hover {
  background-color : skyblue;
  color : blue
  } 
.
.
.
`;

02. Storybook


“ 컴포넌트 UI 개발을 위한 storybook”

  • UI 개발 도구 “Storybook

  • CDD가 트렌드로 자리 잡게 되면서 이를 지원하는 도구 중 하나인 component Explorer(컴포넌트 탐색기)가 등장했는데,

    → 이 컴포넌트 탐색기엔 많은 UI 개발 도구가 있고 그 중 하나가 바로 “storybook”이다.

🔨 1. 그래서 storybook이 뭔데?

  • “storybook”은 UI 개발, 즉 Component Driven Development를 하기 위한 도구를 말한다.
  • storybook의 기능
1)각각의 컴포넌트들을 따로 볼 수 있게 구성해주어 -> 한 번에 하나의 컴포넌트에서 작업할 수 있다.
=> 이를 통해 복잡한 개발 스택을 시작하거나 or 특정 데이터를 데이터베이스로 강제 이동하거나 or  애플리케이션을 탐색할 필요 없이  전체 UI를 한 눈에 보고 개발할 수 있다.
2)재사용을 확대하기 위해 컴포넌트를 -> 문서화하고, 자동으로 컴포넌트를 시각화해 시뮬레이션이 가능한 다양한 테스트 상태를 확인할 수 있다.
=> 이를 통해 버그를 사전에 방지할 수 있다.
3)테스트 및 개발 속도를 향상시키고,
4)애플리케이션도 의존성을 걱정하지 않고 빌드할 수 있다.

🔨 2. Storybook과 같은 UI 개발 도구를 왜 사용할까? 그리고 주요기능은?

사용이유

  1. storybook은 기본적으로 독립적인 개발환경에서 실행한다.
    → 덕분에 개발자는 애플리케이션의 다양한 상황에 구애받지 않고 UI 컴포넌트를 집중적으로 개발할 수 있다.
  2. 또 회사 내부 개발자들을 위해 문서화하여 → 회사의 UI 라이브러리로 사용하거나 or 외부 공개용 디자인 시스템을 개발 하기 위한 플랫폼으로도 사용할 수 있다.

Storybook의 주요 기능

  • UI 컴포넌트들을 카탈로그화하기
  • 컴포넌트 변화를 stories로 저장하기
  • 핫 모듈 재 로딩과 같은 개발 툴 경험 제공하기
  • 리액트를 포함한 다양한 뷰 레이어 지원하기

🔨 3. Storybook으로 컴포넌트를 문서화해 관리하는 방법 : 사용방법

3-1. 리액트 프로젝트 만들고, storybook 설치하기

  • storybook은 package.json을 통해 사용중인 프론트엔드 라이브러리에 맞는 storybook 사용환경을 만들어 주므로 → 리액트 외에도 다양한 프론트엔드 라이브러리에서 사용 가능하다.
npx create-react-app storybook-practice

cd ..

npx storybook init
  • 설치가 완료되면 /.storybook 폴더(in storybook 관련 설정 파일), /.src/stories 폴더(in Storybook 예시 파일)이 생성된다.

3-2. Storybook을 실행한다.

  • 명령어를 통해 react가 localhost:3000으로 접근하듯, localhost:6006으로 접근해 storybook을 실행한다.

  • 실행하면 /.src/stories 폴더에 있는 예시스토리를 확인 할수 있다.

    → storybook 사용으로 (애플리케이션을 실행하고 이벤트를 통해 상태를 변경하는)과정을 거치지 않아도 ⇒ 상태 변화에 따른 컴포넌트의 변화를 확인 할 수 있다.

npm run storybook

🔨 4. Storybook 실습

1. src 폴더 안에 Title.js 파일을 하나 만들고, 다음과 같은 간단한 React 컴포넌트를 하나 만들어 export 해준다.

#Title.js 파일

import React from "react";

// title은 h1 요소의 textContent, textColor은 글자색이 되는 props입니다.
const Title = ({title, textColor}) => (
<h1 style={{color: textColor}}>{title}</h1>
);

export default Title;

2. 같은 위치인 src 폴더 안에 Title.stories.js 파일을 만든다.

❗️ /.storybook 안에 있는 Storybook 설정 파일에 의해 컴포넌트 파일과 똑같은 파일 이름에 .stories를 붙여 파일을 만들면 → 알아서 스토리로 인식한다.

#Title.stories.js 파일

// 앞에서 작성한 컴포넌트를 불러옵니다.
import Title from "./Title";

// title : 컴포넌트 이름으로, '/'를 넣어 카테고리화 할 수 있습니다.
//         이후 예시에서 조금 더 자세히 설명합니다.
// component : 어떤 컴포넌트를 가져와서 스토리로 만들 것인지 명시합니다.
// argTypes : 컴포넌트에 필요한 전달인자의 종류와 타입을 정해줍니다.
//            지금은 title, textColor이라는 전달인자에 text 타입이 필요함을 의미합니다.
export default {
    title: "Practice/Title", 
    component: Title,
    argTypes: {
        title: { control: "text" },
        textColor: {control: "text"}
    }
}

// 템플릿을 만들어줍니다. 이 템플릿에서는
// Title 컴포넌트가 args를 전달받아 props로 내려줍니다.
const Template = (args) => <Title {...args} />

// Storybook에서 확인하고 싶은 컴포넌트는 export const로 작성합니다.
// 템플릿을 사용하여 Storybook에 넣어줄 스토리를 하나 만들어주었습니다.
// Template.bins({}); 는 정해진 문법이라고 생각하고 사용하시면 됩니다.
export const RedTitle = Template.bind({});

// 만들어준 스토리의 전달인자를 작성해줍니다.
RedTitle.args= {
    title: "Red Title",
    textColor: "red"
}

// 스토리를 하나 더 만듭니다.
export const BlueTitle = Template.bind({});

// 스토리의 전달인자를 작성해줍니다.
BlueTitle.args= {
    title: "Blue Title",
    textColor: "blue"
}

3. 중간점검 : Storybook 확인하기

❗️storybook은 핫 모듈 리로딩을 지원하므로 → 새로고침 하지 않아도 변경사항을 바로 확인할 수 있다.

  1. title: “Practice/Title”로 작성한 코드가 좌측 메에서 카테고리로 적용된다.
    • Practice라는 카테고리에 Title 외의 스토리도 담을 수 있다.
  2. title.stories.js 안에서 만든 두개의 스토리(RedTitle, BlueTitle)가 Title 안에 드러간다.
    • 각 스토리는 작성해준 전달인자와, 전달인자에 따라 달라진 결과물도 볼 수 있다.

4. 전달인자를 직접 받는 스토리를 추가하자. 그리고 storybook을 확인한다면?

  • 두 스토리 바로 밑에 스토리를 하나 더 추가한다.
  • 아래 스토리는 탬플릿을 활용하지 않고 바로 전달인자를 받는다.
#Title.stories.js 파일 이어서...

export const StorybookTitle = (args) =>{
    return <Title {...args} />
}

⇒ 해당 스토리는 전달인자 그대로 변한다.

5. 이번엔 전달인자를 직접 받으면서 & Styled Components를 사용해 만든 컴포넌트 스토리로 만들어보자.

1️⃣ Button.js 파일 만들고 컴포넌트를 작성한다.

#Button.js 파일

import React from "react";
import styled from "styled-components"

const StyledButton = styled.button`
 //props.color가 있으면 props.color를, 그렇지않다면 힌색 배경을 사용한다.
background: ${ (props) => props.color || "white" };
//props.size가 "big"이면 200px를, 그렇지 않다면 100px를 너비로 사용한다.
width: ${ (props) => (props size === "big" ? "200px" : "100px") };
//props.size가 "big"이면 80px를, 그렇지 않다면 4px를 높이로 사용한다.
height: ${ (props) => (props size === "big" ? "80px" : "40px") }
 `

const Button = ({color, size, text}) => (
//위에서 작성한 props + text를 받아 textContent로 사용한다.
<StyledButton color={color} size {size} >{text}</StyledButton>
 );

export default Button

2️⃣ Button.stories.js 파일도 작성한다.

#Button.stories.js 파일

// 컴포넌트를 불러옵니다.
import Button from "./Button";

export default {
    title: "Practice/Button",
    component: Button,

		// 이번에 작성한 전달인자의 타입은 Storybook을 보고 직접 확인해보세요.
    argTypes: {
        color: { control: 'color'},
        size: { control: { type:'radio', options : ['big', 'small'] }},
        text: { control: 'text'}
    }
};

export const StorybookButton = (args) => (
    <Button {...args}></Button>
)

6. 최종 storybook을 확인한다.

  • **control**로 작성한 control: ‘color’control: { type: ‘radio’, options: [] } 가 각각 어떤 형태로 인자를 전달하는지 확인할 수 있다.

참고 : Storybook 공식 문서

profile
한입 크기로 베어먹는 개발지식 🍰

0개의 댓글