Mantine 으로 프론트엔드 개발 컨벤션 확립하기!

프론트 깎는 개발자·2023년 2월 12일
1
post-thumbnail

Intro

개발을 하다 보면, 단시간에 프로토타이핑을 끝내거나, UI 컴포넌트 하나하나를 구현할 만큼의 여유가 없을 때 기존에 만들어진 디자인 시스템을 사용하면 좋다. 이번 프로젝트에서도 디자인 시스템을 채택을 앞두고 있었는데, 전면 오픈소스 디자인 시스템 중에서는 Chakra 와 Mantine 으로 좁혀졌고, 그 중 스타일링 커스텀화는 조금 어렵지만, hook 과 컴포넌트가 더 많은 Mantine 으로 하기로 하였다.

기존에 처음부터 모든 것을 만들던 프로젝트와는 달리 조금의 변화를 주어야했다. 특히나 우리가 처음부터 스타일링을 하는 것이 아니기 때문에 기존 프로젝트에서 변화가 많이 필요했다. 아래는 우리가 생각해낸 컨벤션이다.

정의


  • 페이지 컴포넌트
    • 하나의 URL 에 대응하는 페이지 전체에 나타나야 하는 컴포넌트 입니다.
    • 페이지 컴포넌트는 오로지 섹션 컴포넌트만 포함해야 합니다. (오로지 하나의 섹션 컴포넌트라 할 지라도)
    • 구체적으로는 아래의 디렉토리 안에 위치하는 모든 컴포넌트입니다.
      **src**
      ㄴ **pages**
      	ㄴ # 여기 위치하는 컴포넌트들. 
  • 공통 컴포넌트
    • 2개 이상의 페이지 컴포넌트에서 사용되는 컴포넌트입니다.
      (정확히는 2개 이상의 서로 다른 페이지를 구성하는 섹션 컴포넌트에서 사용되는)
    • 구체적으로는 아래의 디렉토리 안에 위치하는 모든 컴포넌트입니다.
      **src**
      ㄴ **components**
      	ㄴ **common**
      		ㄴ # 여기 위치하는 컴포넌트들. 
  • 섹션 컴포넌트
    • 페이지 컴포넌트의 직속 하위에 배치되는 컴포넌트입니다.
    • 섹션 컴포넌트는 다른 섹션 컴포넌트를 포함할 수 없습니다.
    • 구체적으로는 아래의 디렉토리 안에 위치하는 모든 컴포넌트입니다.
      **src**
      	ㄴ **components**
      		ㄴ pages
      			ㄴ **{페이지 이름}**
      				ㄴ **sections**
      				ㄴ # 여기 위치하는 컴포넌트들 
  • 섹션-공통 컴포넌트
    • 단일 페이지에서 사용되지만, 하나의 페이지 안의 여러 개의 섹션에서 공통적으로 사용되는 컴포넌트입니다.
    • 섹션-공통 컴포넌트는, 해당 컴포넌트가 위치한 페이지 외부에서 사용되어서는 안 됩니다.
    • 구체적으로는 아래의 디렉토리 안에 위치하는 모든 컴포넌트입니다.
      **src**
      ㄴ pages
      	ㄴ **{페이지 이름}**
      		ㄴ # 여기 위치하는 컴포넌트들 
       ...ㄴ **sections ...**

프로젝트 컨벤션


CASE 1. 가장 심플한 경우

A 라는 이름의 컴포넌트가 있다고 가정했을 때 …

그리고 AX, AY 컴포넌트는 A 컴포넌트에서 사용하는 컴포넌트인 경우,

  • A 가 공통 컴포넌트인 경우
    **src**
    ㄴ **components**
    	ㄴ **common**
    		ㄴ **A**
    			ㄴ index.ts # 외부에서 해당 컴포넌트 사용 시 import 할 것들을 여기서 export 합니다. 
    			ㄴ A.styles.ts # useAStyle() 생성위치, A, AX, AY 공통적으로 사용하는 style
    			ㄴ **AX**
    				ㄴ AX.tsx
    				ㄴ AX.styles.ts # useAXStyle() 생성위치, AX 만 사용하는 style
    			ㄴ **AY**
    				ㄴ AY.tsx
    				ㄴ AY.styles.ts # useAYStyle() 생성위치, AY 만 사용하는 style
    
  • A 가 공통 컴포넌트가 아닌 경우 (about.tsx 라는 페이지 컴포넌트에서 사용됐다고 가정)
    **src**
    ㄴ **components**
    	ㄴ **pages**
    		ㄴ **about**
    			ㄴ **A**
    				ㄴ index.ts # 외부에서 해당 컴포넌트 사용 시 import 할 것들을 여기서 export 함. 
    				ㄴ A.styles.ts # useAStyle() 생성위치, A, AX, AY 공통적으로 사용하는 style
    				ㄴ **AX**
    					ㄴ AX.tsx
    					ㄴ AX.styles.ts # useAXStyle() 생성위치, AX 만 사용하는 style
    				ㄴ **AY**
    					ㄴ AY.tsx
    					ㄴ AY.styles.ts # useAYStyle() 생성위치, AY 만 사용하는 style
    

CASE 2. 하나의 컴포넌트를 기반으로 하는 여러 병렬적인 컴포넌트

B1, B2, B3 라는 이름의 컴포넌트가 있고

이들 모두가 병렬적인 층위에 있으며, B 라는 컴포넌트를 기반으로 할 경우

  • B 가 공통 컴포넌트인 경우
    **src**
    ㄴ **components**
    	ㄴ **common**
    		ㄴ **bs** # 복수형 폴더명 및 camelCasing 유의  
    			ㄴ index.ts # B1, B2, B3 컴포넌트 export, B 는 export 하지 않음. 
    			ㄴ B.styles.ts # useCommonBStyle() 을 여기서 생성, B, B1, B2, B3 공통사용분
    			ㄴ **B1**
    				ㄴ B1.tsx
    				ㄴ B1.styles.ts # useB1Style() 을 여기서 생성
    			ㄴ **B2**
    				ㄴ B2.tsx
    				ㄴ B2.styles.ts # useB2Style() 을 여기서 생성
    			ㄴ **B3**
    				ㄴ B3.tsx
    				ㄴ B3.styles.ts # useB3Style() 을 여기서 생성
    			ㄴ **B**
    				ㄴ B.tsx
    				ㄴ B.styles.ts # useBStyle() 을 여기서 생성
    
  • B 가 공통 컴포넌트가 아닌 경우 (about.tsx 라는 페이지 컴포넌트에서 사용됐다고 가정)
    **src**
    ㄴ **components**
    	ㄴ **pages**
    		ㄴ **{페이지 이름}**
    			ㄴ **bs** # 복수형 폴더명 및 camelCasing 유의  
    				ㄴ index.ts # B1, B2, B3 컴포넌트 export, B 는 export 하지 않음. 
    				ㄴ B.styles.ts # useBStyle() 을 여기서 생성, B, B1, B2, B3 공통사용분
    				ㄴ **B1**
    					ㄴ B1.tsx
    					ㄴ B1.styles.ts # useB1Style() 을 여기서 생성
    				ㄴ **B2**
    					ㄴ B2.tsx
    					ㄴ B2.styles.ts # useB2Style() 을 여기서 생성
    				ㄴ **B3**
    					ㄴ B3.tsx
    					ㄴ B3.styles.ts # useB3Style() 을 여기서 생성
    				ㄴ **B**
    					ㄴ B.tsx
    					ㄴ B.styles.ts # useBStyle() 을 여기서 생성
    

그러나..

하지만 처음 확립한 컨벤션을 고수하는 중, 여러 가지 문제들이 발생했고, 아래와 같은 changes 들이 발생했다.

Change logs


  • 2023년 2월 6일 오후 5:00 - 공통 useStyles() 사용하지 않습니다.

    *Z 컴포넌트 하위의 모든 컴포넌트 Zx, Zy 등에 공통적으로 적용되는 스타일이 있다면, 그 스타일을 사용하는 컴포넌트는 (이를테면 Zxy 등으로) 분리돼야 한다*

    하나의 컴포넌트에는 하나의 useStyles() 를 사용하는 것이 좋을 것 같다.

    는 의견에 따라 아래와 같이 변경한다. (~~ ~~) 는 삭제함을 의미

    CASE 1. 가장 심플한 경우

    **src**
    ㄴ **components**
    	ㄴ **common 또는 pages/{페이지 이름}**
    		ㄴ **A**
    			ㄴ index.ts # 외부에서 해당 컴포넌트 사용 시 import 할 것들을 여기서 export. 
    			~~**ㄴ A.styles.ts # useAStyle() 생성위치, A, AX, AY 공통적으로 사용하는 style**~~
    			ㄴ **AX**
    				ㄴ AX.tsx
    				ㄴ AX.styles.ts # useAXStyle() 생성위치, AX 만 사용하는 style
    			ㄴ **AY**
    				ㄴ AY.tsx
    				ㄴ AY.styles.ts # useAYStyle() 생성위치, AY 만 사용하는 style
    			ㄴ **AXY**
    				ㄴ AXY.tsx
    				ㄴ AXY.styles.ts # useAXYStyle() 생성위치, AX, AY 등에 걸쳐 사용하는 style 이 적용된 "컴포넌트"
    			
    

    CASE 2. 하나의 컴포넌트를 기반으로 하는 여러 병렬적인 컴포넌트

    **src**
    ㄴ **components**
    	ㄴ **common 또는 pages/{페이지 이름}**
    		ㄴ **bs** # 복수형 폴더명 및 camelCasing 유의  
    			ㄴ index.ts # B1, B2, B3 컴포넌트 export, B 는 export 하지 않음. 
    			**~~ㄴ B.styles.ts # useCommonBStyle() 을 여기서 생성, B, B1, B2, B3 공통사용분~~**
    			ㄴ **B1**
    				ㄴ B1.tsx
    				ㄴ B1.styles.ts # useB1Style() 을 여기서 생성
    			ㄴ **B2**
    				ㄴ B2.tsx
    				ㄴ B2.styles.ts # useB2Style() 을 여기서 생성
    			ㄴ **B3**
    				ㄴ B3.tsx
    				ㄴ B3.styles.ts # useB3Style() 을 여기서 생성
    			ㄴ **B**
    				ㄴ B.tsx
    				ㄴ B.styles.ts # useBStyle() 을 여기서 생성
    			ㄴ **B(123)**
    				ㄴ B12.tsx
    				ㄴ B12.styles.ts # useB12Style() 생성위치, B1, B2, B3, B 중 전부 또는 일부 등에 걸쳐 사용하는 style 이 적용된 "컴포넌트"
    
  • 2023년 2월 9일 오후 4:27 - _elements 폴더 사용

    **계층 구조가 너무 deep 하게 들어가는 것도 좋지 않다.**

    는 의견에 따라

    components/common(또는 pages)/A/_elements/~ 그 이하로는 컴포넌트 계층 들어가지 않고, 이 단위에서는 모두 병렬적으로 컴포넌트를 처리합니다.

    아래와 같이 변경한다. (~~ ~~) 는 삭제함을 의미

    CASE 1 & CASE 2 통합.

    **src**
    ㄴ **components**
    	ㄴ **common 또는 pages/{페이지 이름}**
    		ㄴ **A**
    			ㄴ index.ts # 외부에서 해당 컴포넌트 사용 시 import 할 것들을 여기서 export. 
    			ㄴ A.tsx
    			ㄴ **_elements**
    				ㄴ **AX**
    					ㄴ AX.tsx
    					ㄴ AX.styles.ts # useAXStyle() 생성위치, AX 만 사용하는 style
    				ㄴ **AY**
    					ㄴ AY.tsx
    					ㄴ AY.styles.ts # useAYStyle() 생성위치, AY 만 사용하는 style
    				ㄴ **AXY**
    					ㄴ AXY.tsx
    					ㄴ AXY.styles.ts # useAXYStyle() 생성위치, AX, AY 등에 걸쳐 사용하는 style 이 적용된 "컴포넌트"
    			
    

결론

사실 어느 컨벤션이든, 프로젝트를 진행 함에 따라서, 예외 케이스는 발생하기 마련이고, 이는 컨벤션의 변화를 불러온다. 그래서 처음부터 100% 확정하고 들어간다기 보다는, 대규모 리팩토링을 각오하고서라도 일단 시작을 해야 프로젝트의 지연을... 막을 수 있다 😅

profile
Comfort Zone 에서 벗어나자!

0개의 댓글