컨벤션의 의의와 사용되는 컨벤션

윤뿔소·2023년 9월 17일
0

CS 지식 / 다양한 팁

목록 보기
4/21

우리 개발자들은 코드를 읽고 쓰는 것에 인생 전부를 쏟고 있다. 그러니 자연스럽게 쓰기 쉽고, 읽기 쉬운 효율적인 규칙을 정해 개발 생산성을 보다 키우는 것을 생각하게 된다. 여기서는 그 의의와 규칙을 정하여 계속 추가하는 식으로 써보겠다.

컨벤션이란?

Convention, 특정한 분야나 활동에서 널리 사용되고 인정받는 규칙 또는 관행을 의미

말 그대로 지키면 좋을 규칙이라는 얘기다. '표준'이라는 말과도 비슷하게 쓰일 수 있다. 그렇다면 이 컨벤션을 지켰을 때는 어떤 상황이 벌어질까?

컨벤션의 의의

  1. 가독성 향상
    시기적절한 네이밍과 코드 스타일을 사용하면 코드가 더 읽기 쉬워진다. 가독성이 좋은 코드는 다른 개발자들이 코드를 이해하고 유지보수하기 쉽다. 또한 자신의 코드를 나중에 다시 읽을 때도 이점이 있다.
  2. 협업 용이성
    코드 컨벤션을 준수하면 익숙한 코드이니 팀 내에서 코드를 공유하고 협업하는 것이 더 쉬워진다. 모든 팀원이 일관된 스타일을 보다 따르면 혼란과 오해를 줄일 수 있다.
  3. 버그 예방
    명확하고 증명된 네이밍과 코드 구조는 실수를 줄이고 버그를 예방하는 데 도움이 된다. 그러한 규칙들은 의도를 명확히 전달하므로 개발자가 실수로 잘못된 변수를 사용하는 경우를 줄여준다.
  4. 자동화 도구 활용
    이렇게 합의된 규칙이 증명된 원칙으로 발전하고, 다양한 커뮤니티에서 쓰인다면 자동화 도구를 사용해 신경쓸 Depth를 줄여줄 수 있다. 예를 들어 자동 포맷팅을 통해 반점, 세미콜론 등을 신경 쓰게 하지 않을 수 있다.

이러한 장점들이 있어 진리로서 다뤄지는 컨벤션, 쓰면 좋을 효율적인 컨벤션, 나만의 컨벤션 등을 만들어 효율적인 개발을 진행할 수 있다.

코드 컨벤션

보통 코드 컨벤션은 개발 환경, 회사, 프로젝트 성격 등에 따라 많은 규칙들이 있다. 그래서 자주 달라지는 컨벤션만 다루고 넘어가겠다.

들여쓰기

들여쓰기는 코드 블록을 구분하고 중첩된 코드를 시각적으로 나타내는 데 사용된다. 일반적으로 스페이스 또는 탭 문자로 들여쓰기를 한다. 들여쓰기에는 특정한 스페이스 수 또는 탭 크기를 사용하는 것이 규칙화될 수 있다.
보통 2개, 4개로 쓰이는데 4개는 조금 많이 넓어 중첩이 여러개가 있는 JSX나 함수 등을 보기 힘들다면 2개로 통일하는 것이 더 좋을 수도 있다. 나는 물론 2개다.

중괄호

중괄호도 지키면 아주 좋은 컨벤션이다. 보통 중괄호를 항상 새로운 줄에 두는 스타일과 중괄호를 이전 줄의 끝에 붙이는 스타일들을 가지고 갑론을박이 많이 오간다.
나는 코드가 길어지더라도 가독성을 중시해 3개 이상일 시 항상 줄바꿈과 마지막 반점을 항상 찍도록 한다.

예시로 useQuery 사용을 들겠다.

const {
  isLoading,
  isError,
  data,
  refetch,
} = useQuery<CustomerProfileResponse | null>(

변수 및 함수 네이밍

가장가장가장 중요하면서 어려우면서 의논이 많이 일어나는 부분이다. 다양한 컨벤션이 존재한다.

  • PascalCase, camelCase, snake_case, kebab-case 등
  • 몇 자 이내로 제한할 지
  • 어떠한 내용이 들어갈 지
  • 명사형, 동사형 등 통일
  • 축약형(Abbreviation) 사용을 허가할지, 어떤 축약형으로 통일할 지
  • 상수(constant)는 어떻게 작성할 지

등 많이 달라진다. 나를 예시로 들자면 회사에서 변수 컨벤션을 15자 안팎, 명사형을 주로, 축약형을 통일해 사용한다. 로 정했다.

예시

customerProfileModal, selectedCate(Cate는 Category), curProfileId(cur는 current), org-mgmt(organization-management), ITEMS_PER_PAGE 등등

물론 예외는 있다. 나같은 경우 쉽게 사용하기 위해 타입은 15자를 넘기면서 축약형을 쓰지 않는 편이다.

Tailwind CSS 컨벤션

나는 Next.JS 13.4 App Router 버전으로 개발을 하고 있다. 그러면서 CSS툴도 당연히 사용하는데 Next에서 표준으로 채택하고 있는 'Tailwind CSS'를 사용하고 있다.

그런데 이 툴의 문제점이 className에 CSS 코드를 작성하면서 엄청나게 고봉밥이 되어버리는 불상사가 발생할 수 있다.

<div className='flex items-center justify-start gap-[40px] border-b border-emerald-gray py-[22px] pl-[45px] text-sm'>
  <div className='animate-pulse-custom h-[140px] w-[140px] rounded ' />
  <div className='flex w-[964px] flex-wrap'>
    <div className='mr-3 flex'>
      <div className='mr-8 flex flex-col items-start gap-2'>
        <div>담당자명</div>
        <div className='animate-pulse-custom mb-3 block h-[40px] w-[300px] rounded border border-emerald-gray-2 bg-gray-100 p-2' />
      </div>
      <div className='flex flex-col items-start gap-2'>
        <div>이메일(아이디)</div>
        <div className='animate-pulse-custom mb-3 block h-[40px] w-[300px] rounded border border-emerald-gray-2 bg-gray-100 p-2' />
      </div>
    </div>
    <div className='mr-8 flex flex-col items-start gap-2'>
      <div>비밀번호</div>
      <div className='flex gap-3'>
        <div className='animate-pulse-custom mb-3 block h-[40px] w-[228px] rounded border border-emerald-gray-2 bg-gray-100 p-2' />
        <div
          className='flex h-[40px] w-[60px] cursor-pointer items-center justify-center rounded-sm bg-emerald-3 text-white'
          onClick={() => setEditPassword(true)}
        >
          변경
        </div>
      </div>
    </div>
    ...

어질어질한 코드 길이다.
그래서 CSS 파일에 따로 @apply로 작성해보기도 하고, 다양하게 사용해보는데 그렇게 된다면 툴을 사용하는 의미가 퇴색되어져버린다. 그리고 저렇게 길어져 버리면 가독성도 매우매우 떨어져버린다.

그렇다면 가독성을 올리기 위해 어떤 노력을 해야할까? 다양한 방법이 있겠지만 나는 바로 떠오른 것이 '각 속성마다 순서 지키기'다. 각 속성이 자기 자리에 맞게 순서를 유지한다면 어떤 것이 나오는 게 예상되기 때문에 가독성을 올릴 수 있지 않을까?

하지만! 아쉽게도 위 방법은 매우매우 어려운 방법이다. 왜냐하면 className에 쓸 수 있는 클래스 종류만 수백가지가 된다. 그 순서를 다 외워서 각각 맞는 순서에 배치할 수 있을까? 있다 해도 다른 개발자와 똑같이 맞출 수 있을까? 불가능하다.

그런데 한줄기 빛이 있자니 그것이 바로 prettier다.

prettier-plugin-tailwindcss

Prettier는 기본적으로 컨벤션을 지키게 자동 포맷팅, 에러 감지 등을 사용할 수 있는 라이브러린데 Tailwind CSS도 그렇게 해줄 수 있다.

공식 페이지에서도 거즘 4년 간 이러한 테일윈드 CSS의 고질병을 고치려고 노력했단다. 그래서 나온 결론이 위 방법이다.

기본적인 메카니즘

  • 기본 레이어에 있는 클래스(container 등)가 먼저 정렬되고, 그 다음으로 컴포넌트 레이어에 있는 클래스가 정렬되며, 마지막으로 유틸리티 레이어에 있는 클래스가 정렬
  • 비슷한 재정의 코드가 뒤로 정렬
    <div class="pt-2 p-4">
    =>
    <div class="p-4 pt-2">
  • 박스 모델을 기준으로 레이아웃에 큰 영향 주는 속성은 보다 앞으로, 꾸며만 주는 디자인 속성은 보다 뒤로 배치되게 설정
    <div class="text-gray-700 shadow-md p-3 border-gray-300 ml-4 h-24 flex border-2">
    =>
    <div class="ml-4 flex h-24 border-2 border-gray-300 p-3 text-gray-700 shadow-md">
  • focus:, hover:같은 수정자(Modifier)는 맨 뒤로 감
    <div class="hover:opacity-75 opacity-50 hover:scale-150 scale-125">
    =>
    <div class="scale-125 opacity-50 hover:scale-150 hover:opacity-75">
  • 반응형 수정자는 더 맨 뒤로, sm: 부터 큰 것으로 나열
    <div class="lg:grid-cols-4 grid sm:grid-cols-3 grid-cols-2">
    =>
    <div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4">
  • Tailwind 플러그인에서 제공되지 않는 타사 플러그인이나 커스텀 CSS 속성이면 맨 앞으로

이러한 메카니즘으로 자동 포맷팅을 도와준다. 얼마나 편하고 얼마나 가독성이 좋아질까??

궁금하시다면 https://tailwindcss.com/blog/automatic-class-sorting-with-prettier#how-classes-are-sorted 로 이동해 메카니즘을 살피고, 직접 설치하여 경험해보시길 바랍니다! 겁나 편해! 자동 최고!


그 외 나머지 코드 컨벤션들은 엄청 많은데 일단 일반적인 컨벤션만 작성해보았다.

문서화(주석) 컨벤션

여기에는 주석 및 README 컨벤션을 정하는 곳이다. 주로 주석을 정하며 어디에, 어떻게, 무엇을, 등 어떻게 작성할 지 정하면 된다.

보통 나는 모든 코드에 설명 주석을 달려고 노력하고 있다. 특히 핸들러나 상태 등 비즈니스 로직을 찾는 것이 힘들어 그 쪽에 더 힘을 쏟고 있다.
또한 API의 경우 계속 찾아가기 번거롭고 그래서 얼마 전 새로 만드는 API 함수에 Documentation 주석을 달고 있다.

아래 예시를 작성해보겠다.

1. 로직 영역을 분리

비즈니스 로직을 주석으로 분리해 어떤 코드인지 한눈에 들어오도록 만듦

  // Reset Button 핸들러
  const handleResetButton = () => {
    setCurrentPage(1);
    setSearchedText('');
  };

  // 실거래처 선택 정렬 드롭다운
  const [selectedStateMain, setSelectedStateMain] = useState('');
  const handleSelectStateMain = (selected: string) => {
    setSelectedStateMain(selected);
  };
  // 지부 선택 정렬 드롭다운
  const [selectedBranchMain, setSelectedBranchMain] = useState('');
  const handleSelectBranchMain = (selected: string) => {
    setSelectedBranchMain(selected);
  };

JSX 부분도 마찬가지

<article className='h-full overflow-hidden rounded border border-emerald-gray bg-white'>
  {/* 표 헤더 */}
  <div className='flex h-[3.125rem] w-full items-center justify-center bg-emerald-gray-3 text-center text-[14px] text-white'>
    <div className='w-[101px]'>거래처 코드</div>
    <div className='w-[82px]'>담당 지부</div>
    ...
    <div className='w-[118px]'>통합거래장부</div>
    <div className='h-[3.125rem] w-[41px]'> </div>
  </div>

  {/* 표 본문 */}
  <table className='w-full'>
    ...

기본적인 주석 스타일이다.

2. Documentation 주석

이 주석은 특이한 주석인데 이게 VSC에만 적용되는지는 모르겠지만 내가 직접 만든 함수에 설명을 부여할 수 있다. 심지어 매개변수까지! 이거로 조금 많이 편해졌다.

/**
 * 지정된 매개변수를 기반으로 '상품 목록'을 검색 후 데이터를 가져오는 API 함수입니다.
 *
 * @param {number} perPage - 페이지당 표시할 상품 수입니다.
 * @param {number} page - 검색할 페이지 번호입니다.
 * @param {string} vendorId - Optional, 제조사 ID 식별자를 지정하여 제조사별로 필터링할 수 있습니다.
 * @param {string} category - Optional, 카테고리 식별자를 지정하여 카테고리별로 필터링할 수 있습니다.
 * @param {string} sort - Optional, 상품 목록을 정렬하는 데 사용됩니다.
 *
 * @returns {Promise<ProductResponse>} - 상품 목록을 담은 ProductResponse를 반환하는 Promise입니다.
 */
export async function getProductList(
  perPage: number,
  page: number,
  vendorId?: string,
  category?: string,
  sort?: string,
): Promise<ProductResponse> {
  ...
  const response = await fetchWithAuth(
    `/customers/products?perPage=${perPage}&start=${page}${
      vendorId ? `&vendorId=${vendorId}` : ''
    }${categorize()}${sort ? `&sort=${sort}` : ''}`,
    requestOptions,
  );

  return response.json();
}

이런 식으로 함수 자체의 설명 뿐만 아니라 Parameter, Return에 어떻게 들어가고 나오는지도 설명할 수 있다.

사용하는 함수 위에 마우스 오버를 하면 저렇게 작성했던 설명이 떠 어떤 속성이었는지, 어떻게 사용하면 되는지, 어떤 것이 리턴되는지 알 수 있다. 되게 편하다! 매개변수가 많은 API 통신 함수에 특히 용이하다.

또한 정말 큰 팁이 있는데

Extend : Doxygen Documentation Generator

이라는 VSC 확장 프로그램이다. 설치하고 자기가 설명하고 싶은 함수 위에 /**만 입력하면 자동으로 함수와 함수 params까지 미리 작성해줘 정말 편하다.

이거로 좀 더 작성하기 편해질 것이다. 이제 작성해보고 그 함수로 왔다갔다 하지 말고 바로바로 개발해보자!!@!@!@

profile
코뿔소처럼 저돌적으로

5개의 댓글

comment-user-thumbnail
2023년 9월 17일

코드컨벤션이야말로 어쩌면 협업환경을 유지하는데 가장 중요한 부분중 하나가 아닐까 생각했는데 정리해두셔서 잘 보고갑니다! tailwind prettier와 JSDoc은 잘 사용하면 많이 도움이 될 것 같네요!

답글 달기
comment-user-thumbnail
2023년 9월 19일

코드가 길어질수록 주석의 중요성을 더욱 느끼고 있는 것 같아요
Documentation 주석 부분은 저도 한번 이용해봐야겠어요!

답글 달기
comment-user-thumbnail
2023년 9월 24일

모든 코드에 주석이 필요하다고 느끼고 있어요,,, 파악하는데 시간이 너무 걸리더라구요 ㅜ 고생하셨습니다 !

답글 달기
comment-user-thumbnail
2023년 9월 24일

주석도 정리할 수 있는 확장이 있다니 너무 좋습니다...

답글 달기
comment-user-thumbnail
2023년 9월 24일

tailwind prettier가 적용되는지 몰랐어요 Documentation 꿀팁 알아갑니당!

답글 달기