아래의 아키텍처가 정답이 아니라고 생각합니다. 너그러운 마음과 피드백을 주시면 감사하겠습니다.🙇🏻‍


✔️ 새로운 아키텍처를 도입해 얻은 장점

  1. 코드 응집성을 높여 관리 포인트를 줄였습니다.
  2. 코드 유지보수에 더 유연하게 대응할 수 있게 되었습니다.
  3. 다른 팀원의 코드를 이해하는 데 필요한 리소스를 줄였습니다.

✏️ 새로운 아키텍처를 도입한 이유

새로운 아키텍처를 도입한 가장 큰 이유는 협업을 통한 개발 환경과 코드 응집성을 개선하고, 이로 인해 관리 포인트를 줄이기 위함입니다.

협업 시, 각자 다른 생각으로 폴더명을 지정해 개발을 진행하게 됩니다.(물론 팀내 폴더 컨벤션이 있을 때에는 다릅니다.) 이로 인해 다른 사람이 개발한 코드뿐만 아니라 해당 폴더명에 코드를 추가한 이유까지 파악해야 하는 상황이 발생합니다. 이는 코드를 이해하고 개발하는 데 많은 리소스를 필요로 하게 만듭니다.

따라서 팀원들과 회의를 통해 이 문제를 해결하고자, 더 나은 코드 아키텍처를 만들기로 결정하였습니다. 이를 위해 기존 아키텍처를 수정하면서 배우고 느꼈던 경험을 공유하고 적용하였습니다.


✍️ 각 폴더 역할

기존 Modules 폴더 세분화

기존 modules 폴더 안에 있는 코드들 중에는 외부 라이브러리를 커스텀하여 서비스에 필요한 피쳐로 변경한 코드, 순수 서비스에 필요한 기능 등이 모여 있었습니다. 처음 이 폴더 안의 코드를 볼 때, modules 폴더가 다소 넓은 기능들을 포함하고 있다는 인상을 주었습니다.

그래서 modules 폴더를 제거하고, features와 plugins 폴더를 만들어 더 세분화된 구조로 변경하였습니다. features 폴더는 서비스 내 필요한 기능을 담당하는 코드들을 모아놓은 공간, plugins 폴더는 외부 라이브러리를 프로젝트 내부 어디서든 쉽게 사용하고 관리할 수 있도록 Wrapping한 코드들을 모아놓았습니다.(shared 폴더 하위에 존재)


Shared 설계한 이유

기존에는 폴더의 깊이를 동일하게 유지해서 폴더를 생성해 관리했습니다. 이 방법도 나쁘지 않았지만, 폴더의 개수가 많아짐에 따라 폴더를 명확히 구분이 필요했습니다. 그 중 일부 프로젝트 내부에 공용적으로 사용되는 폴더가 필요해서 Shared 폴더를 만들었습니다. Shared 폴더 안에는 constants, utils, types, plugins, uiComponents 등이 포함되어 있습니다.(uiComponents는 순수하게 UI만을 담당하는 독립적인 컴포넌트입니다.)


templates 설계한 이유

Next.js에서는 page 폴더가 라우터 기능, SSR 관련 함수 호출 등을 담당하는 역할을 수행하므로, 이러한 기능을 수행하는 page 컴포넌트와 별도로 단일 책임 원칙을 따르기 위해 templates 폴더를 만들어 page와 1:1 대응되는 templates 컴포넌트를 만들었습니다.


features를 설계한 이유

features를 폴더는 클라이언트 데이터(DTO)와 서버에서 내려주는 데이터(Entity)를 분리하기 위해 설계되었습니다. 이러한 설계는 백엔드와 프론트엔드가 병렬적으로 개발을 진행하면서 서버 데이터의 변경이 있더라도, 클라이언트 데이터(DTO)의 변경에만 신경쓰면 되는 장점이 있어 features 폴더를 설계했습니다.


폴더명 참조 방향 설정 및 eslint 설정

  • 아래와 같이 바로 앞에 있는 폴더만 참조가 가능하도록 설정해, 개발의 참조 일관성을 부여했습니다.
  • 참조 방향 : pages -> templates -> features -> shared/plugins -> shared/uiComponent -> shared/utils -> shared/constants -> shared/types
  • eslint 역참조 불가 설정

    rulse: {
    'import/no-restricted-paths': [
      'error',
      {
        basePath: './src'
        zones: [
          // templates 폴더가 pages 폴더를 역참조 할 수 없도록 설정
          { target: './templates', from: './pages' }
        ]
      }
    ]
    }

적용한 코드 아키텍쳐

디렉토리 정의
shared/types 글로벌 타입
shared/constants 글로벌 상수
shared/utils 글로벌 유틸
shared/uiComponents 두 페이지 이상에서 사용되는 순수 UI 및 UI 로직
shared/plugins 3rd-party 라이브러리 커스텀 로직
features 프로젝트 의존성이 있는 공통 로직
templates page와 1:1 대응되는 페이지 컴포넌트
pages NextJS의 라우팅 기능

💡 새로운 아키텍처를 적용하면서 느낀점

이번 프로젝트를 통해 코드 이해도와 프로젝트 아키텍처에 대한 시야를 높일 수 있는 좋은 경험을 할 수 있었습니다. 코드의 폴더 위치와 참조 관계 등에 대한 고민을 깊이 해볼 수 있었으며, 팀원들의 코드를 보면서 해당 코드의 폴더 위치가 적절한지, 또한 어떤 의도로 해당 폴더에 코드를 작성했는지 물어봄으로써 팀원들의 코드를 깊이 이해할 수 있었습니다. 이번 경험을 통해 프로젝트 아키텍처에 대한 지식이 부족하다는 것을 느꼈고, Clean Achitecture 책을 구입하여 공부할 계획입니다.


참고