Web

[Web] 스타일 컴포넌트를 어떻게 잘 관리할 수 있을까? (feat. Emotion.js)

철스커 2023. 3. 18. 19:25
반응형

* Emotion.js를 사용해서 스타일 컴포넌트를 생성하려고 합니다.
* React 디자인 패턴인 Presentational - Container 패턴을 사용한 기준으로 설명하였습니다.

 

 

 

 

고민

Native하게 HTML Element + CSS or Sass를 사용할 수도 있겠지만, CSS in JS의 편리함 때문에 스타일 컴포넌트를 많이 사용하고 계실 겁니다.

 

스타일 컴포넌트는 페이지 / 컨테이너 / 컴포넌트 어느 곳이든 사용할 수 있을 텐데요.

개발을 진행하면 할수록, 계속 쌓여가는 스타일 컴포넌트를 어떻게 관리해야 할지? 에 대한 고민이 생깁니다.

 

 

 

1. 페이지 Level

// Page.js
import styled from '@emotion/styled';
import Container from '@/containers/Container';

function Page() {
    // 비즈니스 로직...

    return (
        <PageWrapper>
            <Container />
            {/* JSX... */}
        </PageWrapper>
    )
}

// styled
const PageWrapper = styled.main``;

// 다른 스타일 컴포넌트들...

 

 

2. 컨테이너 Level

// Container.js
import styled from '@emotion/styled';
import Component from '@/components/Component';

function Container() {
    // 비즈니스 로직...

    return (
        <ContainerWrapper>
            <Component />
            {/* JSX... */}
        </ContainerWrapper>
    )
}

// styled
const ContainerWrapper = styled.section``;

// 다른 스타일 컴포넌트들...

 

 

3. 컴포넌트 Level

// Component.js
import styled from '@emotion/styled';

function Component(props) {
    return (
        <ComponentWrapper>
            {/* JSX... */}
        </ComponentWrapper>
    )
}

// styled
const ComponentWrapper = styled.div``;

// 다른 스타일 컴포넌트들...

 

 

 

 

스타일 컴포넌트를 별도의 파일로 관리하기

비즈니스 로직도 많아지고, 스타일 컴포넌트도 많아지면 한 개의 파일 안의 코드가 방대해집니다.

그러면 가독성도 떨어지고, 개발을 할 때 코드를 찾는 시간이 오래 걸릴 것입니다. (생산성 DOWN)

 

스타일 컴포넌트를 별도의 파일 안에 모아 놓고, 모듈로 내보내서 필요할 때 가져쓰는 방법이 있습니다.

스타일 컴포넌트를 사용하는 쪽에서는 모듈로 불러와서 사용하기만 하면 되고, 스타일 관리에 대한 관심사를 분리시킬 수 있습니다.

 

그리고 코드량이 줄어들어 보다 코드가 깔끔해집니다.

 

 

// Container.js
import styled from '@emotion/styled';
import Component from '@/components/Component';
import { ContainerWrapper } from './styles';

function Container() {
    // 비즈니스 로직...

    return (
        <ContainerWrapper>
            <Component />
        </ContainerWrapper>
    )
}
// styles.js
import styled from '@emotion/styled';

export const ContainerWrapper = styled.section``;

// 다른 스타일 컴포넌트들...

 

 

장점

  • 스타일 관리에 대한 관심사를 분리시킬 수 있다.
  • 페이지 / 컨테이너 / 컴포넌트 파일에서 코드량이 줄어든다.

 

단점

  • 공통 컴포넌트 (버튼, 팝업 등..) 와 스타일 컴포넌트의 구분이 어려울 수 있다.
  • 이름 중복이 발생할 수 있다. -> 인터페이스 또는 다른 컴포넌트와 이름이 겹치면, 이름이 안 겹치도록 네이밍을 잘 지정해줘야 합니다.

 

 

 

 

스타일 컴포넌트를 별도의 파일로 관리 + 네임스페이스 지정

이름 중복 이슈를 막으려면, 이름만 안 겹치도록 하면 되는데요.

실제 개발을 하면 유일한 이름을 짓기가 쉽지 않는 경우가 많습니다.

 

다행하게도, named export 모듈들을 as 키워드를 통해 그룹핑할 수 있습니다.

그러면 스타일 컴포넌트들을 별도의 네임스페이스 안에서 관리할 수 있는 것입니다.

 

 

// Container.js
import styled from '@emotion/styled';
import Component from '@/components/Component';
import * as S from './styles';

function Container() {
    // 비즈니스 로직...

    return (
        <ContainerWrapper>
            <Component />
            <S.Contents>
                <S.Title>제목</S.Title>
                <S.Description>설명</S.Description>
            </S.Contents>
        </ContainerWrapper>
    )
}

스타일 컴포넌트는 S라는 네임스페이스 안에 있습니다.

그래서 공통 컴포넌트 Component와 구분이 가능해집니다.

 

 

// styles.js
import styled from '@emotion/styled';

export const ContainerWrapper = styled.section``;

export const Contents = styled.div``;

export const Title = styled.h1``;

export const Description = styled.p``;

// 다른 스타일 컴포넌트들...

 

 

장점

  • 스타일 관리에 대한 관심사를 분리시킬 수 있다.
  • 페이지 / 컨테이너 / 컴포넌트 파일에서 코드량이 줄어든다.
  • 공통 컴포넌트 (버튼, 팝업 등..) 와 스타일 컴포넌트의 구분을 쉽게 할 수 있다.
  • 이름 중복을 막을 수 있다.
  • 네임스페이스 내부의 스타일 컴포넌트를 코드 에디터가 자동완성으로 알려준다.

 

단점

  • 네임스페이스 이름을 붙여야 하기 때문에, 코드가 조금 지저분해보일 수 있다? 안 예쁠 수 있다.

 

 

자동완성 시, 비슷한 이름의 컴포넌트들이 목록에 많이 나타날 수 있다.

 

스타일 컴포넌트를 모듈로 관리할 때, 또 발생하는 문제점이 있는데요.

컴포넌트들을 자동완성으로 불러오려고 할 때, 비슷한 이름인 것들이 많아질 수 있다는 것입니다.

네임스페이스로 구분하면 이름 중복을 피할 수 있지만, 이런 문제점? Trade-off가 발생할 수 있습니다.

 

 

 

 

개인적인 결론

개인적인 결론으로는 스타일 컴포넌트를 최대한 분리하는 쪽으로 가되,

 

스타일 컴포넌트를 몇 개 사용안하는 곳에서는 스타일 컴포넌트를 분리시키지 말고,

스타일 컴포넌트가 많아지는 곳에서는 파일 & 모듈로 구분하는 것이 좋을 것 같습니다.

 

상황에 맞게 유연하게 컴포넌트들을 관리해주면 어떨까 싶습니다.

여기까지 제가 고민한 내용을 정리했습니다.

 

 

혹시 더 좋은 구조 & 방법이 있다면 알려주세요! ㅎㅎㅎ

반응형