안녕하세요 오늘은 tailwind css를 사용할 때 classname을 정렬하는 방법에 대해 알아보겠습니다. yarn berry Pnp mode를 사용할 때 흔히 겪을 수 있는 문제점과 해결방안도 함께 소개해드리겠습니다!
tailwind를 사용하다보면 개발자마다 className을 적는 순서가 달라질 수 있습니다.
똑같은 코드를 누군가는 아래처럼 적기도 하고
<input className={'flex flex-col w-full'}/>
누군가는 아래처럼 적기도 합니다.
<input className={'w-full flex-col flex'}/>
이렇게 코드를 작성하다보면 코드의 일관성이 떨어지고 불필요한 변경점이 생길 수 있습니다. 저희가 코드 컨벤션을 잘 맞춰두어야 하는 이유이기도 하죠.
저희 프로젝트에서는 이 부분을 방지하기 위해 두가지 방법을 두고 고민했습니다.
1. IDE에서 제공하는 tailwind formatter 플러그인을 사용하는 것
2. prettier의 플러그인을 활용하는 것
저희는 yarn install
외에 개발자간 선행되어야 하는 세팅이 적었으면 좋겠다 판단했고 prettier의 플러그인을 사용하기로 했습니다.
첫번째 문제점 - plugin 적용이 안됨
tailwind의 자동 포맷팅 기능을 사용하려면 prettier-plugin-tailwindcss
라는 플러그인을 사용하면 되는데요. .prettierrc
파일의 plugin 배열에 아래와 같이 추가해주면 되는 줄 알았는데 안되더군요.. ㅠㅠ
//.prettierrc
{
"plugins": ["prettier-plugin-tailwindcss"]
}
알고보니 yarn berry의 pnp를 사용할 때 prettier의 plugin을 잘 인식하지 못하는 이슈가 있었습니다. 그래서 파일명을 .prettierrc.js
로 바꾸고 plugin 모듈을 직접 require 해주었더니 해결되었습니다.
//.prettierrc.js
module.exports = {
plugins: [require.resolve('prettier-plugin-tailwindcss')],
};
이제 자동포맷팅 기능이 잘 동작하게 되었습니다. 하지만 예외 케이스가 생기기 시작했습니다. 반복되는 classname의 묶음을 처리할 때는 어떻게 해야할까요?
두번째 문제점 - 반복되는 classname은 어떻게 포맷팅해주지?
관리자 프로젝트에서 react-paginate
라는 외부 라이브러리를 사용한적이 있습니다. 페이지네이션을 위한 컴포넌트를 제공해주는데요.
저희는 tailwind css를 사용하고 있기 때문에 하위 요소 하나하나를 스타일링 하려면 아래와 같이 다양한 className을 사용했어야 했습니다. 문제는 아래처럼 똑같이 link를 꾸며주는 className이 같을 때였습니다.
<ReactPaginate
breakLinkClassName={"size-8 flex cursor-pointer items-center ..."}
previousLinkClassName={"size-8 flex cursor-pointer items-center ..."}
nextLinkClassName={"size-8 flex cursor-pointer items-center ..."}
pageLinkClassName={"size-8 flex cursor-pointer items-center ..."}
/>
굉장히 찝찝하지 않나요?! 고민끝에 저희는 이렇게 같은 class들의 묶음을 상수로 정의하여 사용하기로 했습니다.
const LINK_CLASS_NAME = "size-8 flex cursor-pointer ..."
<ReactPaginate
breakLinkClassName={LINK_CLASS_NAME}
previousLinkClassName={LINK_CLASS_NAME}
nextLinkClassName={LINK_CLASS_NAME}
pageLinkClassName={LINK_CLASS_NAME}
/>
하지만 이렇게 하면 LINK_CLASS_NAME
에 정의된 class들이 자동 정렬되지 않는 문제가 있었습니다. 저희는 일단 prettier-plugin-tailwindcss
의 공식문서를 들여다보기로 했습니다.
여러 방법이 있었지만 저희는 custom tagged template literals를 사용하는 방법을 택했습니다. (clsx 라이브러리를 사용하신다면 prettier config 파일에 clsx를 추가하는 방법을 추천드립니다.)
여기서 tagged template literals
라는 개념이 익숙하지 않으신 분들이 있으실 것 같습니다. 하지만 아래 코드를 보신다면 오! 하고 반가워하실거에요
const StyledMessage = styled.p`
${body5FontStyle};
margin-top: 0.5rem;
color: ${({ theme }) => theme.colors.green700};
`;
styled component를 정의할 때 흔히 사용하는 패턴으로 JavaScript에서 템플릿 리터럴을 사용할 때 태그 함수를 붙여 템플릿 리터럴의 내용과 표현식을 특정한 방식으로 처리할 수 있는 기능입니다.
const tw = (strings, ...values) => String.raw({ raw: strings }, ...values)
const LINK_CLASS_NAME = tw`size-full inline-block flex ...`
이렇게 tw 함수를 정의해준 뒤 아래처럼 .prettierrc.js 파일에 tailwindFunction을 추가해주었습니다. 이제 prettier가 돌다가 tw라는 function을 만나면 그 안의 class들을 sorting 해주게 됩니다!
//.prettierrc.js
module.exports = {
plugins: [require.resolve('prettier-plugin-tailwindcss')],
tailwindFunctions: ['tw'],
};
'프로젝트 개선' 카테고리의 다른 글
Next/Image 커스텀로더로 서버 부하 줄이기 (1) | 2024.10.28 |
---|---|
라이브러리 크기가 클 때 성능 개선하기 (코드 스플리팅, 부분 import) (1) | 2024.10.28 |