CDD (Component Driven Development)

  • 디자인과 개발 단계에서부터 재사용할 수 있는 UI 컴포넌트를 미리 디자인하고 개발
  • 부품 단위로 UI 컴포넌트를 만들어 나가는 개발을 Component Driven Development (CDD)

Storybook

CDD를 지원하는 도구인 Component Explorer(컴포넌트 탐색기) 중에 UI 개발도구Storybook

  1. 각각의 컴포넌트들을 따로 볼 수 있게 구성해주어 한 번에 하나의 컴포넌트에서 작업 가능

  2. 복잡한 개발 스택을 시작하거나 특정 데이터를 데이터베이스로 강제 이동하거나 애플리케이션을 탐색할 필요 없이 전체 UI를 한눈에 보고 개발 가능

  3. 재사용성을 확대하기 위해 컴포넌트를 문서화하고 자동으로 컴포넌트를 시각화하여 시뮬레이션할 수 있는 다양한 테스트 상태를 확인 가능
    =>
    이를 통해 버그를 사전에 방지할 수 있도록 도와주고 테스트 및 개발 속도를 향상시키는 장점이 있으며 애플리케이션 또한 의존성을 걱정하지 않고 빌드 가능

  4. Storybook은 기본적으로 독립적인 개발환경에서 실행되서 개발자는 애플리케이션의 다양한 상황에 구애받지 않고 UI 컴포넌트를 집중적으로 개발 가능

  5. 회사의 내부 개발자들을 위해 문서화(documentation)를 하여 회사의 UI 라이브러리로써 사용하거나 외부 공개용 디자인 시스템(Design System)을 개발하기 위한 기본 플랫폼으로 사용 가능

주요 기능

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

구조적인 CSS 작성 방법의 발전

프로젝트의 규모나 복잡도가 점점 커지고 함께 작업해야할 팀원 수도 많아지고 다양한 디바이스들의 등장으로 웹사이트들이 다양한 디스플레이를 커버해야 하기 때문에 CSS 작업을 효율적으로 하기 위해 구조화된 CSS의 필요성이 생겼다.

CSS 전처리기(CSS Preprocessor)

CSS 전처리기(CSS Preprocessor)란 CSS가 구조적으로 작성될 수 있게 도움을 주는 도구
=> CSS의 문제점들을 프로그래밍 개념(변수, 함수, 상속 등)을 활용하여 해결

CSS 전처리기(CSS Preprocessor) 자체만으로는 웹 서버가 인지하지 못하기 때문에 각 CSS 전처리기에 맞는 Compiler를 사용해야 하고 컴파일을 하게 되면 실제로 우리가 사용하는 CSS 문서로 변환
=> CSS 파일들을 잘 구조화할 수 있게 되었고 최소한 CSS 파일을 몇 개의 작은 파일로 분리할 수 있는 방법이 생김

SASS

CSS 전처리기 중에서 가장 유명한 SASSSyntactically Awesome Style Sheets의 약자로 CSS를 확장해 주는 스크립팅 언어

반복되는 CSS 코드가 있으면 변수를 활용해서 재사용이 가능 => 변수를 선언할 때는 $기호를 사용

SASS는 SCSS 코드를 읽어서 전처리한 다음 컴파일해서 전역 CSS 번들 파일을 만들어 주는 전처리기(preprocessor)의 역할

전처리기(preprocessor)가 내부에서 어떤 작업을 하는지는 알지 못한 채 스타일이 겹치는 문제를 해결하기 위해 단순히 계층 구조를 만들어 내는 것에 의지하게 되었고 그 결과 컴파일된 CSS의 용량은 어마어마하게 커지게 됨

CSS 방법론

CSS 전처리기의 문제를 보완하기 위해 BEM, OOCSS, SMACSS 같은 CSS 방법론이 대두

CSS 방법론의 지향점

  • 코드의 재사용
  • 코드의 간결화(유지보수 용이)
  • 코드의 확장성
  • 코드의 예측성(클래스 명으로 의미 예측)

BEM

대표적인 CSS 방법론인 BEMBlock, Element, Modifier로 구분하여 클래스명을 작성하는 방법이며 Block, Element, Modifier 각각은 __로 구분

클래스명은 BEM 방식의 이름을 여러 번 반복하여 재사용할 수 있도록 하며 HTML/CSS/SASS 파일에서도 더 일관된 코딩 구조를 만들어 줌

클래스명 선택자가 장황해지고 이런 긴 클래스명 때문에 마크업이 불필요하게 커지며 재사용하려고 할 때마다 모든 UI 컴포넌트를 명시적으로 확장해야만했다.

SASS와 BEM도 고치지 못했던 몇 가지 문제들은 언어 로직 상에 진정한 캡슐화(encapsulation : 객체의 속성과 행위를 하나로 묶고 실제 구현 내용 일부를 외부에 감추어 은닉하는 개념)의 개념이 없다는 것이었고 이로 인해 개발자들이 유일한 클래스명을 선택하는 것에 의존할 수 밖에 없었다.

CSS-in-JS

CSS도 컴포넌트 영역으로 불러들이기 위해서 CSS-in-JS가 탄생

CSS-in-JS의 대표적인 Styled-Components는 기능적(Functional) 혹은 상태를 가진 컴포넌트들로부터 UI를 완전 분리해 사용할 수 있는 아주 단순한 패턴을 제공

CSS 방법론들의 특.장.단점

특징장점단점
CSS기본적인 스타일링 방법관심사 분리일관된 패턴을 갖기 어려움, !important의 남용
SASS프로그래밍 방법론을 도입하여 컴파일된 CSS를 만들어내는 전처리기변수/함수/상속 개념을 활용하여 재사용가능, CSS의 구조화전처리 과정이 필요, 디버깅의 어려움, 컴파일한 CSS 파일이 거대해짐
BEMCSS 클래스명 작성에 일관된 패턴을 강제하는 방법론네이밍으로 문제 해결, 전처리 과정 불필요선택자의 이름이 장황하고 클래스 목록이 너무 많아짐
Styled-Components컴포넌트 기반으로 CSS를 작성할 수 있게 도와주는 라이브러리CSS를 컴포넌트 안으로 캡슐화, 네이밍이나 최적화를 신경 쓸 필요가 없음빠른 페이리 로딩이 불리

Styled-Componets

Styled Component는 React 의 컴포넌트 기반 개발 환경에서 스타일링을 위한 CSS의 성능 향상을 위해 탄생

const Button = styled.a`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
`;

Styled Component를 사용하면 기존 CSS 문법으로도 스타일 속성이 추가된 React 컴포넌트를 만들 수 있다.

특징

  • Automatic critical CSS
    Styled Component는 화면에 어떤 컴포넌트가 렌더링 되었는지 추적해서 해당하는 컴포넌트에 대한 스타일을 자동으로 삽입해서 코드를 적절히 분배해 놓으면 사용자가 어플리케이션을 사용할 때 최소한의 코드만으로 화면이 띄워지도록 할 수 있다.

  • No class name bugs
    Styled Component는 스스로 유니크한 className을 생성하기 때문에 className의 중복이나 오타로 인한 버그를 줄여줌

  • Easier deletion of CSS
    기존에는 더 이상 사용하지 않거나 삭제한 컴포넌트에 해당하는 스타일 속성을 제거하기위해 CSS 파일 안의 className을 이리저리 찾아야 했지만 Styled Component는 모든 스타일 속성이 특정 컴포넌트와 연결되어 있기 때문에 만약 컴포넌트를 더 이상 사용하지 않아 삭제할 경우 이에 대한 스타일 속성도 함께 삭제됨

  • Simple dynamic styling
    className을 일일이 수동으로 관리할 필요 없이 React props나 전역 속성을 기반으로 컴포넌트에 스타일 속성을 부여하기 때문에 간단하고 직관적

  • Painless maintenance
    컴포넌트에 스타일을 상속하는 속성을 찾아 다른 CSS 파일들을 검색하지 않아도 되기 때문에 코드의 크기가 커지더라도 유지보수가 어렵지 않음

  • Automatic vendor prefixing
    개별 컴포넌트마다 기존의 CSS 를 이용하여 스타일 속성을 정의하면 이외의 것들은 Styled Component가 알아서 처리

Styled Componenttagged template literals이라는 ES6 문법을 사용하여 컴포넌트를 만들 때에 해당 문법을 사용하여 컴포넌트의 스타일 속성을 정의하면 별도의 CSS 파일없이도 스타일 속성을 지닌 컴포넌트를 만들 수 있다.

props Styles

// Button component
...
  background: ${(props) => (props.primary ? "palevioletred" : "white")};
  color: ${(props) => (props.primary ? "white" : "palevioletred")};
...

// App component
...
  <Button>Normal</Button>
  <Button primary>Primary</Button>
...

Styled Component는 스타일 속성을 지닌 컴포넌트를 정의할 때에 함수를 전달하고 그 함수 안에서 props를 사용 가능

Extending Styles

// 기존의 Button 컴포넌트에 Tomato 컴포넌트만을 위한 새로운 속성 추가
const Tomato = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

같은 스타일 속성을 지닌 여러개의 컴포넌트들 중 몇 개의 컴포넌트에는 약간의 변화를 주고 싶은 경우 상속받고자 하는 스타일 속성을 지닌 컴포넌트를 styled() 로 감싼 뒤 변경하고 싶은 속성만 새로 정의해 주면 기존 속성을 확장하여 사용 가능

Passed props

컴포넌트에 props로 스타일 속성이 전달된다면 해당 컴포넌트는 props전달된 속성을 우선 적용하며 전달되는 속성이 없다면 기본으로 설정된 속성을 적용한다. 이는 Styled Component가 개발자에 의해 설정된 속성과 기본 속성을 구분할 수 있기 때문이다.

Advanced

Styled Component는 각 element와 해당 element에 대한 스타일 규칙의 조합
=> 컴포넌트 이름으로 인해 서로 충돌하지 않고 React Developer ToolsWeb Inspector에서 쉽게 구분 가능

Styled Component의 정의는 render 메소드 밖에 정의
=> 만약 Styled Component리턴문 안에서 정의되면 컴포넌트가 리렌더링 될 때마다 스타일 속성을 지닌 컴포넌트가 매번 새로 정의되서 렌더링 속도 저하에 큰 영향을 끼침

const Thing = styled.div`
  color: blue;

  &:hover {
    color: red; // <Thing> when hovered
  }

  & ~ & {
    background: tomato; // <Thing> as a sibling of <Thing>, but maybe not directly next to it
  }

  & + & {
    background: lime; // <Thing> next to <Thing>
  }

  &.apple {
    background: orange; // <Thing> tagged with an additional CSS class ".apple"
  }

  .banana & {
    border: 1px solid; // <Thing> inside another element labeled ".banana"
  }

  .blueberry {
    background-color: yellow; // an element labeled ".blueberry" inside <Thing> without ampersand(&)
  }
`;

Styled Component는 중첩 스타일링을 위해 SCSS 와 같은 전처리 기능을 자동으로 지원하며 중첩 스타일링을 하기 위해서는 ampersand(&) 기호를 사용

=> 만약 ampersand(&) 를 사용하지 않으면 평범한 후손 셀렉터처럼 동작

=> ampersand(&)는 컴포넌트 안에서 적용되는 CSS 규칙을 확장해 줌으로써 특히 순수 CSSStyled Component를 혼용해서 사용해야 하는 경우에 각 스타일 간의 충돌을 피하는 데에 유용하게 사용 가능


useRef Hook

React에서 DOM 엘리먼트의 주소값을 활용해야 하는 경우

  • focus
  • text selection
  • media playback
  • 애니메이션 적용
  • d3.js, greensockDOM 기반 라이브러리 활용

useRef로 DOM 노드, 엘리먼트, 그리고 리액트 컴포넌트 주소값을 참조 가능

const 주소값을_담는_그릇 = useRef(참조자료형)
// 이제 주소값을_담는_그릇 변수에 어떤 주소값이든 담을 수 있다.
return (
    <div>
      <input ref={주소값을_담는_그릇} type="text" />
        {/* React에서 사용 가능한 ref라는 속성에 주소값을_담는_그릇을 값으로 할당하면*/}
        {/* 주소값을_담는_그릇 변수에는 input DOM 엘리먼트의 주소가 담김 */}
        {/* 향후 다른 컴포넌트에서 input DOM 엘리먼트를 활용 가능 */}
    </div>
  );

제시된 상황 제외한 대부분의 경우 기본 리액트 문법을 벗어나 useRef를 남용하는 것은 부적절하고 React의 특징이자 장점인 선언적 프로그래밍 원칙에 위배되기 때문에 조심해서 사용해야함


디자인 시스템

디자인 시스템이란 서비스를 만드는 데 사용한 공통 컬러, 서체, 인터랙션, 각종 정책 및 규정에 관한 모든 컴포넌트를 정리해놓은 것이며 불필요한 커뮤니케이션을 없애기 위해 체계적으로 정리한 시스템

UI 컴포넌트는 사용자 인터페이스를 이루는 조각들의 시각적이고 기능적인 속성을 캡슐화

디자인 시스템은 재사용이 가능한 UI 컴포넌트들로 이루어져 복잡하고 견고하며 사용자가 접근하기에 용이한 사용자 인터페이스를 구축 가능

빌드 컴포넌트

  • ⚛️ 리액트(React): 선언 중심 컴포넌트 UI(create-react-app)를 사용

TailWind CSS

Utility-first CSS로서 각 class가 담당할 스타일을 미리 정의하고 필요한 class들을 조합해서 적용하는 식으로 사용하는 방법중 대표적인 TailWind CSS

<div class="max-w-sm mx-auto flex p-6 bg-white rounded-lg shadow-xl">
  <div class="flex-shrink-0">
    <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
  </div>
  <div class="ml-6 pt-1">
    <h4 class="text-xl text-gray-900 leading-tight">ChitChat</h4>
    <p class="text-base text-gray-600 leading-normal">You have a new message!</p>
  </div>
</div>
profile
둔필승총(鈍筆勝聰) - 기억보다는 기록을

0개의 댓글