웹개발 초기에 완벽한 폴더 구조를 설계할 필요는 없다

profile_image
작성자 프론트엔드 개발자 서이준
댓글 0건 조회 34회

새 프로젝트를 열자마자 폴더 이름부터 고민하느라 첫 기능을 하루 종일 시작하지 못한 적이 있나요? 웹개발 초기에 자주 벌어지는 실패는 구조를 대충 잡는 것이 아니라, 아직 존재하지 않는 복잡성까지 미리 설계하는 것입니다. 사용자가 원하는 기능은 하나인데 components, features, domains, services, repositories를 먼저 늘리면 코드는 그럴듯해 보여도 변경 비용은 오히려 커집니다.

프로그래밍의 기본 개념처럼 프로그램은 문제 해결을 위한 명령과 절차의 구성입니다. 폴더 구조도 문제를 해결하는 수단이어야지, 그 자체가 개발 목표가 되어서는 안 됩니다.

빈 폴더부터 늘리는 설계는 하지 마세요

미래 기능을 상상해 만든 계층의 실패

한 팀은 간단한 회원 정보 수정 화면을 만들면서 controller, use-case, domain, repository, adapter 계층을 모두 분리했습니다. 서버와 통신하는 함수는 하나뿐이었지만 파일은 열두 개가 생겼고, 이름을 바꿀 때마다 여러 경로를 함께 수정해야 했습니다. 두 달 뒤 실제 요구사항은 예상과 다르게 흘렀고 미리 만든 계층 절반이 사용되지 않았습니다.

추상화는 반복이 확인된 뒤에 도입해도 늦지 않습니다. 기능이 하나뿐인 단계에서는 관련 코드를 가까이 두어 흐름을 빠르게 파악할 수 있게 만드는 편이 낫습니다. 두 번째와 세 번째 사례가 생겼을 때 공통점을 추출하면 실제 코드에 근거한 구조를 만들 수 있습니다.

다음과 같은 행동은 설계를 잘하는 것처럼 보이지만 초기 개발 속도를 떨어뜨리는 대표적인 실수입니다. 여러분의 프로젝트에도 이름만 있고 내용은 없는 디렉터리가 쌓여 있지는 않은지 살펴보세요.

  • 언젠가 쓸 것이라는 이유로 utils, common, shared 폴더를 먼저 만드는 행동
  • 구현체가 하나인데도 interface와 implementation 파일을 무조건 나누는 행동
  • 화면 하나를 위해 전역 상태 관리 계층부터 추가하는 행동
  • 팀원이 설명을 들어야만 이해할 수 있는 약어로 폴더 이름을 정하는 행동
  • 예제 프로젝트의 구조를 서비스 규모와 무관하게 그대로 복사하는 행동
좋은 초기 구조는 확장을 예언하는 구조가 아니라, 현재 기능의 위치와 실행 흐름을 새 팀원이 빠르게 찾을 수 있는 구조입니다.

모든 코드를 공용으로 빼지 않아도 되는 이유

성급한 재사용이 결합도를 높이는 순간

버튼 두 개의 색상과 크기가 비슷하다는 이유만으로 범용 컴포넌트를 만들면 처음에는 중복이 줄어든 듯합니다. 하지만 결제 버튼에는 로딩 표시가 필요하고 검색 버튼에는 아이콘 정렬이 필요해지는 순간 props가 급격히 늘어납니다. 결국 하나의 수정이 무관한 여러 화면을 흔드는 공유 컴포넌트의 역설이 발생합니다.

코드가 두 번 나타났다는 사실만으로 공통화하지 마세요. 모양이 같더라도 변경되는 이유가 다르면 별도의 코드로 유지하는 편이 안전합니다. 반대로 서로 다른 화면에서 같은 정책 때문에 함께 변경된다면 그때는 재사용 후보가 됩니다. 코딩이라는 활동의 의미를 더 넓게 확인하려면 코딩 용어 설명도 참고할 수 있지만, 실무 품질은 문법보다 변경 이유를 구분하는 능력에서 크게 갈립니다.

실패를 줄이려면 공통화 전에 아래 질문을 순서대로 던져보세요. 세 항목 이상에 확신 있게 답하기 어렵다면 약간의 중복을 허용하고 사례를 더 관찰하는 편이 경제적입니다.

  1. 같은 이유로 변경되는 코드인가? 단순히 현재 모양만 같은 것은 아닌지 확인합니다.
  2. 세 곳 이상에서 실제로 반복되고 있는가? 아직 없는 세 번째 사용처를 상상해 만들지 않습니다.
  3. 공용 API를 짧은 문장으로 설명할 수 있는가? 옵션 설명이 구현보다 길다면 분리가 이릅니다.
  4. 한 사용처의 요구가 다른 사용처에 불필요한 조건문을 추가하지 않는가?
  5. 분리 후 테스트와 탐색이 더 쉬워지는가? 파일 이동만 늘어난다면 이점이 없습니다.

나쁜 공통화와 유효한 공통화 구별하기

날짜 문자열 변환처럼 입력과 출력이 명확한 순수 함수는 비교적 안전하게 공유할 수 있습니다. 반면 회원가입과 주문 화면이 우연히 같은 형태의 입력 상자를 쓴다는 이유로 거대한 Form 컴포넌트를 만들면 검증 규칙과 오류 표시 정책이 뒤엉킬 가능성이 큽니다. 시각적 유사성보다 변경의 방향을 기준으로 판단해야 합니다.

상황권장 판단피해야 할 실수
순수한 날짜 포맷 변환공용 함수 검토화면별 조건을 함수 안에 추가
서로 다른 업무의 입력 폼각 기능에 우선 배치수십 개 props로 하나에 통합
동일한 인증 정책정책 모듈로 분리페이지마다 권한 조건 복사

유행하는 아키텍처를 그대로 복사하지 마세요

규모가 다른 프로젝트의 옷을 입힌 사례

대규모 서비스의 저장소를 참고하는 일 자체는 유익합니다. 문제는 수백 명이 다루는 모노레포 구조를 두 명이 만드는 예약 페이지에 그대로 적용할 때 생깁니다. 패키지 경계, 코드 생성기, 내부 라이브러리 배포 절차가 추가되면서 실제 고객 기능보다 빌드 설정을 관리하는 시간이 길어질 수 있습니다.

아키텍처 이름은 품질 보증서가 아닙니다. Feature-Sliced Design, 클린 아키텍처, 헥사고날 아키텍처처럼 널리 알려진 접근도 해결하려는 문제가 분명할 때 가치가 있습니다. 팀의 배포 단위가 하나이고 도메인 규칙도 단순하다면 페이지 또는 기능 단위로 가까이 배치하는 구조가 탐색과 수정에 더 유리할 수 있습니다.

초보 개발자는 유명한 구조를 적용하지 않으면 뒤처지는 듯한 불안을 느끼기도 합니다. 그러나 실제 제품을 만든 학생 개발자의 성장 사례를 다룬 AI·서비스 개발 관련 기사에서도 읽을 수 있듯, 개발의 가치는 복잡한 형식을 갖추는 데만 있지 않습니다. 사용자의 문제를 발견하고 작동하는 결과를 빠르게 검증하는 능력도 중요합니다.

  • 팀 규모: 구조를 익히고 유지할 사람이 실제로 몇 명인지 봅니다.
  • 변경 빈도: 함께 자주 바뀌는 파일을 멀리 떨어뜨리지 않습니다.
  • 도메인 복잡도: 단순 조회 화면에 과도한 업무 계층을 만들지 않습니다.
  • 배포 단위: 독립 배포하지 않는 코드를 성급하게 패키지로 나누지 않습니다.
  • 도구 비용: 빌드, 린트, 테스트 시간이 구조 변경으로 얼마나 증가하는지 측정합니다.
아키텍처를 채택하기 전에는 “이 방식이 멋진가?”보다 “우리 팀이 지금 겪는 어떤 실패를 줄이는가?”를 먼저 물어야 합니다.

구조 변경은 작은 실험으로 검증하기

전체 저장소를 한 번에 재구성하면 기존 기능 개발이 멈추고 되돌리기도 어려워집니다. 변경이 잦은 기능 하나를 골라 새 구조를 적용한 뒤, 파일 탐색 시간과 코드 리뷰 질문 수가 줄었는지 확인하세요. 효과가 수치나 팀 경험으로 확인될 때 범위를 넓히면 유행이 아니라 근거에 따라 선택할 수 있습니다.

파일 위치보다 변경 비용을 먼저 판단하세요

리팩터링 시점을 정하는 우선순위

폴더 구조를 바꿔야 할 신호는 “파일이 많아 보여서”가 아닙니다. 같은 기능을 수정할 때 관련 파일을 반복해서 놓치거나, 순환 참조가 발생하거나, 코드 리뷰에서 위치를 찾는 질문이 계속 나올 때가 실제 신호입니다. 이런 문제를 기록하면 취향 논쟁을 줄이고 구체적인 실패 비용을 기준으로 대화할 수 있습니다.

리팩터링 전에는 현재 테스트가 변경 중 안전망 역할을 하는지 확인해야 합니다. 테스트가 부족하다면 핵심 사용자 흐름부터 얇게 보호하고, 이동과 로직 수정을 한 커밋에 섞지 않는 편이 좋습니다. 먼저 파일만 이동하고 동작이 같음을 확인한 다음 이름과 책임을 다듬으면 오류가 생긴 지점을 찾기 쉬워집니다.

프로젝트의 다음 구조를 결정할 때는 아래 우선순위를 그대로 적용해보세요. 첫 번째 기준을 충족하지 못했다면 뒤의 멋진 설계 원칙을 검토하느라 시간을 쓰지 않아도 됩니다.

  1. 현재 사용자 기능이 정상 작동하는가: 구조 개선 때문에 장애 수정이나 핵심 개발을 미루지 않습니다.
  2. 변경할 코드를 쉽게 찾을 수 있는가: 검색 없이도 기능의 시작점과 관련 파일을 예측할 수 있어야 합니다.
  3. 함께 바뀌는 코드가 가까이 있는가: 기술 종류보다 업무 기능의 변경 경계를 우선 관찰합니다.
  4. 의존 방향이 단순한가: 공용 영역이 개별 페이지를 역으로 참조하지 않게 관리합니다.
  5. 반복되는 불편이 측정되는가: 한 번의 불편이 아니라 리뷰 지연, 누락, 충돌이 반복될 때 구조를 바꿉니다.
  6. 팀이 같은 규칙을 설명할 수 있는가: 문서 한 장으로 합의되지 않는 복잡한 규칙은 축소합니다.

예를 들어 상품 검색 기능을 자주 수정한다면 검색 화면, 요청 함수, 상태 처리, 테스트를 하나의 기능 경계에서 찾을 수 있게 하는 것이 우선입니다. 그다음 여러 기능에서 동일하게 사용하는 인증 정책만 공용 영역으로 올리면 됩니다. 이렇게 작동 여부 → 탐색성 → 변경 응집도 → 의존성 → 반복 비용 → 팀 합의 순으로 판단하면, 완벽한 폴더 구조를 예측하지 않고도 프로젝트가 성장하는 속도에 맞춰 안전하게 구조를 발전시킬 수 있습니다.

웹개발 초기에 완벽한 폴더 구조를 설계할 필요는 없다

댓글목록

등록된 댓글이 없습니다.