* 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가 발생할 수 있습니다.
개인적인 결론
개인적인 결론으로는 스타일 컴포넌트를 최대한 분리하는 쪽으로 가되,
스타일 컴포넌트를 몇 개 사용안하는 곳에서는 스타일 컴포넌트를 분리시키지 말고,
스타일 컴포넌트가 많아지는 곳에서는 파일 & 모듈로 구분하는 것이 좋을 것 같습니다.
상황에 맞게 유연하게 컴포넌트들을 관리해주면 어떨까 싶습니다.
여기까지 제가 고민한 내용을 정리했습니다.
혹시 더 좋은 구조 & 방법이 있다면 알려주세요! ㅎㅎㅎ
'Web' 카테고리의 다른 글
[Web] Discord 채팅채널에 Github Action을 이용해서 Vercel 배포 알림 보내기 (Vercel Hobby Plan) (0) | 2024.05.08 |
---|---|
[Web] Storybook를 시작해보자 (with Typescript, Next.js) (0) | 2023.07.07 |
[Web] Git 원격저장소의 브랜치 추적하기 (0) | 2023.05.24 |
[Web] Gitlab-runner 명령어 몇 가지 정리해보기 (0) | 2023.04.29 |
[Web] Gitlab-runner 설치 & Runner 등록하기 (Amazon Linux 2 - Centos 계열) (0) | 2023.04.28 |