인턴

Next.js 프로젝트의 효율적인 폴더 구조 개선하기 📂

choijming21 2025. 3. 26. 14:36

Next.js에서 특히 App Router를 사용할 때 폴더 구조는 코드 유지보수성과 개발 효율성에 큰 영향을 미칩니다. 이 글에서는 랜딩 페이지 중심의 Next.js 프로젝트에서 촐더 구조를 개선한 사례를 공유합니다!

 

 

📌 기존 폴더 구조의 문제점 📌

프로젝트 초기에는 다음과 같은 구조로 시작했습니다.

📦src
 ┣ 📂app
 ┃ ┣ 📂components
 ┃ ┃ ┣ 📂landing
 ┃ ┃ ┃ ┣ 📜Accomplishment.tsx
 ┃ ┃ ┃ ┣ 📜CaseCard.tsx
 ┃ ┃ ┃ ┣ 📜CaseSection.tsx
 ┃ ┃ ┃ ┣ 📜Closing.tsx
 ┃ ┃ ┃ ┣ 📜CurriculumCard.tsx
 ┃ ┃ ┃ ┗ ...
 ┃ ┃ ┣ 📂typography
 ┃ ┃ ┃ ┣ 📜H2.tsx
 ┃ ┃ ┃ ┗ 📜Text.tsx
 ┃ ┃ ┣ 📜CtaButton.tsx
 ┃ ┃ ┣ 📜DesktopViewContainer.tsx
 ┃ ┃ ┣ 📜Footer.tsx
 ┃ ┃ ┗ ...
 ┃ ┣ 📜page.tsx
 ┃ ┗ ...

 

이 구조의 주요 문제점:

  1. 관련 컴포넌트의 분산: 섹션별로 관련된 컴포넌트들이 분산되어 있어 코드 탐색이 어려움
  2. 책임 구분 불명확: 공통 컴포넌트와 특정 페이지 컴포넌트 구분이 모호함
  3. 재사용성 저하: 촐더 구조가 컴포넌트의 재사용성을 고려하지 않음
  4. 유지보수 어려움: 프로젝트 규모가 커질수록 관련 파일 찾기 어려움

 

 

 

 

 

📌 개선된 폴더 구조 📌

프로젝트 구조를 다음과 같이 개선했습니다.

📦src
 ┣ 📂app
 ┃ ┣ 📂_home
 ┃ ┃ ┗ 📂components
 ┃ ┃ ┃ ┣ 📂common
 ┃ ┃ ┃ ┃ ┗ 📜LeftTitle.tsx
 ┃ ┃ ┃ ┣ 📂accomplishment
 ┃ ┃ ┃ ┃ ┗ 📜Accomplishment.tsx
 ┃ ┃ ┃ ┣ 📂case
 ┃ ┃ ┃ ┃ ┣ 📜CaseCard.tsx
 ┃ ┃ ┃ ┃ ┗ 📜CaseSection.tsx
 ┃ ┃ ┃ ┣ 📂caseStudyRequest
 ┃ ┃ ┃ ┃ ┗ 📜Report.tsx
 ┃ ┃ ┃ ┣ 📂curriculum
 ┃ ┃ ┃ ┃ ┣ 📜CurriculumCard.tsx
 ┃ ┃ ┃ ┃ ┗ 📜CurriculumSection.tsx
 ┃ ┃ ┃ ┗ ...
 ┃ ┣ 📂components
 ┃ ┃ ┣ 📂typography
 ┃ ┃ ┃ ┣ 📜H2.tsx
 ┃ ┃ ┃ ┗ 📜Text.tsx
 ┃ ┃ ┣ 📜DesktopViewContainer.tsx
 ┃ ┃ ┗ ...
 ┣ 📂components
 ┃ ┣ 📂ui
 ┃ ┃ ┣ 📜button.tsx
 ┃ ┃ ┣ 📜input.tsx
 ┃ ┃ ┗ ...

 

 

 

 

 

 

📌 주요 개선 사항 📌

1. 페이지별 컴포넌트 분리

  • 홈페이지 관련 컴포넌트를 _home 폴더로 분리했습니다. App Router에서 언더스코어(_)로 시작하는 폴더는 라우팅에서 제외되므로, URL 구조에 영향을 주지 않으면서도 코드를 논리적으로 구성할 수 있습니다.

 

2. 섹션별 폴더 구조화

  • 기존에 평면적으로 나열되어 있던 컴포넌트들을 섹션별로 폴더화하여 구성했습니다. 예를 들어 기존의 CaseCard.tsx와 CaseSection는 이제 Case 폴더 내에 함께 위치합니다.

 

3. 의미 있는 폴더명 사용

  • 기존의 모호한 폴더명(ex: report)을 더 명확한 이름(ex: caseStudyRequest)으로 변경했습니다. 이렇게 하면 개발자가 코드베이스를 처음 접할 때도 각 폴더의 목적을 쉽게 이해할 수 있습니다.

 

4. 공통 컴포넌트 추출

  • 여러 섹션에서 반복되는 UI 패턴을 발견하고 공통 컴포넌트로 추출했습니다. 예를 들어, 여러 섹션에서 사용되는 제목 스타일을 LeftTitle 컴포넌트로 추출했습니다.
// _home/components/common/LeftTitle.tsx
interface LeftTitleProps {
  title: string;
  subTitle: string;
  description: React.ReactNode;
}

export const LeftTitle = ({ title, subTitle, description }: LeftTitleProps) => {
  return (
    <div className="flex flex-col w-full gap-2">
      <Text weight="bold" size="xl" className="...">
        {title}
      </Text>
      <Text weight="bold" size="3xl" className="...">
        {subTitle}
      </Text>
      <Text weight="medium" size="xl" className="...">
        {description}
      </Text>
    </div>
  );
};

 

 

이 컴포넌트는 다음과 같이 사용합니다.

// PointSection에서 사용
const POINT_TITLE = {
  title: "POINT",
  subTitle: "TeamSpartaの強み",
  description: (
    <>
      受講生一人ひとりの成長のために
      <br />
      スパルタならではのソリューションで密着管理します。
    </>
  )
};

const PointSection = () => {
  return (
    <section>
      <DesktopViewContainer>
        <LeftTitle
          title={POINT_TITLE.title}
          subTitle={POINT_TITLE.subTitle}
          description={POINT_TITLE.description}
        />
        {/* 나머지 컨텐츠 */}
      </DesktopViewContainer>
    </section>
  );
};

 

 

5. 전역 UI 컴포넌트 분리

  • 애플리케이션 전체에서 사용되는 UI 컴포넌트는 src/components/ui 폴더로 분리했습니다. 이는 각 페이지에 특화된 컴포넌트와 전역 UI 컴포넌트를 명확히 구분합니다.

 

 

 

 

 

📌 개선 효과 📌

  1. 개발 효율성 증가: 관련 파일을 더 빠르고 찾고 수정할 수 있게 됨
  2. 코드 재사용성 향상: 공통 컴포넌트 추출로 중복 코드 감소
  3. 협업 용이성: 다른 개발자가 코드베이스를 더 쉽게 이해하고 작업할 수 있음
  4. 유지보수성 개선: 폴더 구조가 명확해져 버그 수정과 기능 추가가 더 쉬워짐
  5. 확장성 증가: 새로운 페이지나 섹션을 추가할 때 기존 패턴을 따르기 쉬움

 

 

 

 

📌 컴포넌트 refactoring 사례 📌

폴더 구조 개선과 함께 컴포넌트 내부 코드도 refactoring 했습니다. 예를 들어 InrtoVideoSection 컴포넌트는 다음과 같이 개선되었습니다.

 

기존 코드:

const IntroVideoSection = () => {
  return (
    <section>
      <DesktopViewContainer>
        <div className="flex gap-6">
          <div className="h-full">
            <div className="max-w-[564px]">
              <video>
                <source src={`${CDN_BASE_URL}/video.mp4`} />
              </video>
            </div>
          </div>
          <div className="flex flex-col">
            <Text>「タイトル」</Text>
            <Text>
              説明テキスト<br />
              説明テキスト
            </Text>
          </div>
        </div>
      </DesktopViewContainer>
    </section>
  );
};

 

개선 코드:

// 비디오 컴포넌트 분리
const VideoComponent = () => {
  return (
    <div className="h-full">
      <div className="max-w-[564px]">
        <video>
          <source src={`${CDN_BASE_URL}/video.mp4`} />
        </video>
      </div>
    </div>
  );
};

const IntroVideoSection = () => {
  return (
    <section>
      <DesktopViewContainer>
        <div className="flex gap-6">
          <VideoComponent />
          <div className="flex flex-col">
            <Text>「タイトル」</Text>
            <Text>
              説明テキスト<br />
              説明テキスト
            </Text>
          </div>
        </div>
      </DesktopViewContainer>
    </section>
  );
};

 

 

 

 

 

📌 결론 📌

Next.js 프로젝트 폴더 구조를 개선하는 것은 단순한 파일 이동 이상의 가치가 있습니다. 이는 코드 품질, 개발, 경험, 그리고 궁극적으로 사용자 경험까지 향상시킬 수 있습니다.