All Articles

[20191029 TIL] 리액트 스타일 가이드


2019-10-29 TIL


아토믹 디자인

아토믹 디자인은 웹 제작에서 구축이나 유지 보수를 떠받치는 설계를 말하며, 이름 그래도 화학 원리에서 힌트를 얻은 것이라고 합니다.

자연계에서는 원자가 결합하여 분자가 되고 분자가 결합하여 더욱 복잡한 사물을 형성합니다. 이와 같은 화학 원리에 의해 우리가 생활하는 세상에는 풍부한 사물들이 생겨납니다. 이와 같은 프로세스를 사용자 인터페이스 설계와 개발에 적용함으로써, 다양해지는 웹 개발 환경에서 튼튼하고 고품질의 UI를 일관성 있게 제공할 수 있게 되었습니다.

아토믹 디자인의 기본 개념

컴포넌트를 이용하는 가장 큰 장점은 다시 사용할 수 있다는 데 있습니다. 웹에서는 특정 인터페이스를 다양한 곳에서 여러 번 사용하는 경우가 많습니다. 예를 들어 ‘보내기’ 버튼은 웹 사이트 안의 다양한 폼과 함께 사용되고, 계정 정보에 나타나는 ‘사용자 아이콘’은 로그인된 상태라면 여러 곳에서 표시됩니다.

컴포넌트를 활용한다는 것은 효율이나 일관성과 깊은 관계가 있으므로 사용자가 제품을 편리하게 이용하는 데 있어 빼놓을 수 없는 부분입니다.

페이지와 컴포넌트를 분할할 단위는 5종류 입니다.

  • Atoms_원자

  • Molecules_분자

  • Organisms_유기체

  • Templates_템플릿

  • Pages_페이지


Atoms

UI를 구성하는 요소 중 가장 작은 요소.

Atoms는 추상적인 요소이므로, 여러 개 조합해야 비로소 기능을 하게 됩니다.

ex. 버튼, 입력 영역, 제목, 아이콘, 체크박스, 라디오 버튼 등…


Molecules

여러 개의 Atoms을 조합하여 형성됨.

Molecules는 UI에 의미를 부여하기 때문에 UI를 어떻게 사용할 것인지를 구체적으로 나타냅니다.

단, 재사용성은 유지된다는 것이 핵심입니다.

예를 들면, 제목과 입력 영역, 버튼 각 요소는 Atoms이지만, 이 3개를 조합한 상태는 Molecules라 불립니다. 이러한 Molecules 컴포넌트인 검색 폼은 여러 페이지에서 다시 이용할 수 있는 부품입니다.

많은 Atoms을 조합하여 복잡한 Molecules를 만들면 재사용이 어려워지므로 가능한 한 단순한 상태로 만드는 것이 좋습니다.


Organisms

지금까지의 구성 요소와는 달리, Organisms은 보다 더 복잡한 UI이기 때문에 재사용성을 크게 요구하지 않는다는 점이 앞서 나온 요소들과 다른 점입니다.

대표적인 예로는 헤더(Header)나 푸터(Footer)를 들 수 있습니다. 헤더에 앞에서 소개한 검색 폼, 로고, 전역 내비게이션 3개의 구성 요소로 이루어질 수 있습니다.


Templates

페이지에 표시할 실제 데이터가 반영되기 전의 상태를 가리킵니다. 페이지 구조나 레이아웃 구성 등을 설명하기 위한 레이어입니다.


Pages

앞에서 설명한 Templates에 실제 데이터가 반영된 상태입니다.

프로그래밍으로 바꾸어 말하면 Pages는 Templates 클래스의 인스턴스라 할 수 있습니다.



소스 코드 빌드

빌드란 프로그램 소스 코드에 배포할 파일을 생성하거나 관련 문서를 생성하는 공정을 가리킵니다.

빌드의 이점을 간단하게 정리하면 ‘개발자가 머리를 써야 할 일’, ‘기계적으로 실행하는 것이 빠른 일’로 나누어 효율적으로 개발할 수 있다는 것입니다.

개발 현장의 효율을 올리는 것과 관련된 키워드로 최근 ‘자동화’가 자주 등장합니다.

사람이 실행하는 이상 실수는 피할 수 없습니다. 그러나 기계적으로 자동화하면 매번 확실하게 처리하여 실수를 줄일 수 있으며, 남는 시간은 다른 작업에 더욱 전념할 수 있습니다.

프론트엔드 개발에 개발 공정을 적용하면 구축 작업을 자동화하여 편리한 개발 환경을 만들 수 있습니다. 이를 통해 개발자는 고품질 코드를 만드는 데 집중할 수 있게 됩니다.


webpack

webpack은 ‘모듈 번들러’입니다. 주된 목적은 브라우저에서 사용할 Javascript 파일을 번들하는 것이지만, 이뿐만 아니라 다양한 리소스나 에셋을 변환, 번들링, 패키징할 수도 있습니다.

webpack 공식 홈페이지 (https://webpack.js.org/) 를 인용한 내용입니다.

일반적으로 ‘번들’이란 어떤 제품에 다른 제품을 덧붙인 상태로 배포하는 것을 말합니다.

컴퓨터를 산 후 바로 이용할 수 있도록 미리 애플리케이션이 설치된 상태가 그 예입니다.

이와 마찬가지로 webpack은 효율적인 개발을 위해 브라우저에서 동작하도록 모듈화한 상태의 JavaScript 파일을 번들한 도구라 할 수 있습니다.

webpack 구조의 기본은 Entry(진입)와 Output(출력)으로 단순합니다.

진입점(Entry Point)이라 불리는 프로그램 실행 기점이 되는 파일을 기준으로 의존 관계가 생깁니다.

각 모듈을 원래 독립 파일로 있었지만, webpack으로 번들했을 때 의존하는 것도 포함하여 새로운 파일로 결합한 다음 출력합니다.


webpack_bundle.jpg


로더

표준에서 webpack은 단순히 JavaScript 파일만 다룰 수 있지만, 로더가 존재하는 덕분에 유연성이 크게 향상되었습니다.

다양한 형식을 모듈 단위로 다루는 것이 webpack의 근본적인 사상이므로 이를 실현하기 위한 로더는 webpack의 가장 핵심 부분에 해당하는 사양이라 할 수 있습니다.

babel-loader

Babel 실행을 포함한 상태로 읽어 들일 수 있는 babel-loader를 이용하는 것이 일반적입니다.

babel-loader와 관련 패키지를 설치합니다. Babel을 실행하기 위한 코어 모듈(@babel/core) 외에도 리액트 또는 JSX 코드 변환에 필요한 프리셋도 함께 설치합니다.

  • babel-loader, @babel/core, @babel/preset-env, @babel/preset-react

webpack-dev-server

webpack은 편하게 개발할 수 있도록 강력한 로컬 서버 기능을 제공합니다.

watch 모드로 실행되므로 소스 코드의 변경을 감지하여 자동으로 다시 빌드를 실행하게 됩니다. 또한 다시 빌드하는 시점에 열려 있던 브라우저를 자동으로 새로고침하여 보여줍니다.

따라서 코드가 실제로 브라우저에서 어떻게 변하는지, 아무것도 하지 않아도 바로 알 수 있습니다.


서버 사이드 렌더링

React 등 JavaScript를 이용한 DOM 렌더링을 포함한 라이브러리에서는 서버에서의 HTML 조립 처리를 최소화하고 브라우저에서 렌더링하게 되어 있습니다.

이는 몇 가지 유념해야 할 점이 있습니다.

특히 주목해야 할 점은 SEO와 초기 표시의 성능입니다.


SEO

SEO(Search Engine Optimization)는 검색 엔진 최적화를 말합니다.

검색 엔진에 인덱스 되고 자연 검색에 의해 유입된 사용자 수가 중요한 경우, 이에 영향이 생기는 건 서비스 자체 존속에도 관련된 매우 민감한 주제입니다.

보통 검색 엔진에 등록되려면 크롤러라 불리는 웹상의 콘텐츠나 리소스를 수집하는 로봇 프로그램에 탐지되고 수집될 필요가 있습니다. 그러므로 크롤러에 대한 최적의 구현(높은 수집 능력)도 필요해지게 됩니다.

크롤러가 사이트에 접속했을 때 검색 엔진에 등록해야 하는 정보를 얻을 수 있어야 하므로 복잡한 프로그램으로 구성된 애플리케이션일지라도 크롤러는 이를 이해할 수 있어야 합니다.

현재의 구글 검색 크롤러는 JavaScript를 실행할 수 있으므로 초기 접속 시의 HTML 파일에 콘텐츠가 포함되지 않더라도 스크립트 실행 후의 요소를 인덱스합니다.

그러나 이 정보는 공식으로 공개된 것이 아니고 보증된 것도 아닙니다. 실행 가능하다고 해도 어디까지 구현이 올바르게 평가되는가도 명확하지 않습니다. 따라서 이미 대규모의 트래픽이 자연 검색을 통해 유입되는 서비스에서 크롤러의 성능만 믿는 것은 여전히 위험하다고 볼 수 있습니다.


초기 표시 성능

서버로 요청 송신 후 최초로 돌아오는 HTML에 콘텐츠가 포함되어 있으면 브라우저는 바로 렌더링할 수 있습니다. 그러나 JavaScript를 이용하여 DOM을 형성할 경우, 스크립트 로딩이 끝난 후 실행되어 그때 렌더링 됩니다.

이것은 이용하는 사용자에게 초기 표시가 느리다, 무겁다 등의 인상을 주게 되므로 웹 사이트 품질에 크게 영향을 미치게 됩니다.

특히 복잡한 애플리케이션일수록 번들된 JavaScript 파일도 커지는 경향이 있는데, 이는 사용자 경험상 아주 중요한 초기 표시에 직접 영향을 주게 됩니다.

물론 몇 가지 개선 방법이 있긴 하지만 이는 클라이언트만으로 DOM을 생성할 때 생기는 유념할 점 중 하나라 할 수 있습니다.


리액트로 서버 사이드 렌더링 구현

리액트는 서버 사이드 렌더링 장치를 라이브러리로 제공합니다.

예제로는 클라이언트 사이드(HTML 파일과 webpack-dev-server를 이용한 결과 확인)와 Node.js의 express 모듈을 이용하는 서버 사이드 처리를 진행할 것입니다.

서버 사이드 렌더링을 더욱 간단히 실현하고자 할 때는 Next.js라 불리는 프레임워크를 활용할 것을 추천드립니다. Next.js는 서버 사이드 렌더링을 전제로 한 리액트 애플리케이션 구현 프레임워크입니다.



CSS 구현

CSS 설계 방법

1. OOCSS

OOCSS(Object-Oriented CSS)는 구조와 겉모습을 나누어 생각하는 객체 지향형 CSS

구조만을 정의한 class를 기초로 하고, 겉모습을 확장하는 class는 별도로 준비하는 다중 클래스적인 작성 방법입니다.

<div class="box box-red">붉은 상자</div>
<div class="box box-blue">푸른 상자</div>
.box {
  width: 100px;
  height: 100px;
}
.box-red {
  background-color: red;
}
.box-blue {
  background-color: blue;
}

2. BEM

BEM은 Block Element Modifier의 약자입니다.

특정 UI(Block)를 구축할 때 그 자식 요소(Element)와 수식 요소(Modifier)라는 관점으로 class 구조를 만드는 방법입니다.

Element와 Modifier를 ’_‘나 ’-’ 등의 기호를 사용하여 어떤 block과 연결된 것인가를 class 이름으로 나타냅니다. 이러한 구조로 일정 규칙을 가지고 효율화를 꾀하는 특징은 아토믹 디자인에도 통하는 것이 있습니다.

<ul class="nav">
  <li class="nav__item">...</li>
  <li class="nav__item">...</li>
  ...
</ul>
<ul class="nav nav--hidden">
  <li class="nav__item">...</li>
  <li class="nav__item">...</li>
  ...
</ul>
.nav {
  padding: 20px;
}
.nav__item {
  font-size: 24px;
  border-bottom: 1px solid #000;
}
.nav--hidden {
  display: none;
}

3. SMACSS

SMACSS(Scalable and Modular Architecture for CSS)의 약자로, 확장성을 고려한 것이라 할 수 있습니다.

SMACSS는 CSS를 다음의 레이어로 분할하여 정의합니다.

  • Base (사이트 전체의 기본 스타일)
  • Layout (페이지 안의 영역을 분할한 레이아웃)
  • Module (재사용 가능한 UI를 부품화함)
  • State (특정 상태에 따라 스타일을 덮어씀)
  • Theme (색이나 그림 등 겉모습에 관련된 스타일을 재정의할 수 있음)

CSS in JS

  • CSS modules

  • styled-components

  • styled-JSX

CSS 분리

  • PostCSS

  • Portals


품질

테스트
  • Jest
  • enzyme


참고

  • (더 괜찮은 웹 개발자가 되기 위한) 리액트 스타일 가이드 [프리렉]