코딘 폴더구조 정리 중에 Deep Import와 Barrel File이라는 개념에 대해 알게되었다.

좋은 폴더구조에 대한 의견은 사람마다 다른 것 같아서 혼란스럽다...
패키지나 모듈의 내부 경로를 직접 지정해서 가져오는 것이다.
// 일반 import (public API를 통한 접근)
import { DefaultBody } from '@/shared/ui';
// Deep import (내부 경로를 직접 접근)
import DefaultBody from '@/shared/ui/layout/Body/defaultBody';
패키지가 tree-shaking을 제대로 지원하지 않을 때 필요한 모듈만 직접 가져오면 번들의 크기를 줄일 수 있다.
큰 라이브러리에서 함수 하나만 필요한 경우, deep import로 불필요한 코드 로딩을 피할 수 있다.
라이브러리가 리팩토링으로 폴더 구조를 바꾸면 deep import 경로가 전부 깨지는 상황이 발생한다. 공식 진입점을 통했다면 내부 변경과 무관하게 동작한다.
내부 모듈은 public API가 아니라서 Semantic Versioning을 지켜줄 의무가 없기 때문에, patch 업데이트에도 시그니처가 바뀌거나 모듈 자체가 삭제될 수 있다.
같은 모듈을 공식 경로와 deep import 경로로 가져오면 번들러가 이를 다를 모듈로 인식해 코드가 두 번 포함될 수 있다.
deep import 경로는 길고 일관성이 없어지기 쉬워서 팀원마다 같은 컴포넌트를 다른 경로로 가져오는 상황이 생길 수 있다.
외부 패키지의 모듈을 가져오는 상황이 아니고 팀 프로젝트 안의 모듈을 가져오는 상황이기 때문에 나의 상황에서 deep import를 지양해야 할 이유는 딱히 찾지 못했다.
claude와 더 얘기하다가 지금 팀 프로젝트가 단일 앱이라면 deep import보다는 아까 얘기한 폴더 구조 규칙이나 barrel file(index.ts) 정도로 정리하는 게 더 실질적인 도움이 될 거야.
라고 해서 barrel file에 대해서도 더 찾아보았다.
폴더 안에 index.ts를 만들어, 외부에 공개할 것들만 모아서 re-export하는 파일이다.
폴더구조가 아래와 같을 때
components/Button/
├── Button.tsx ← 실제 컴포넌트
├── Button.styles.ts ← 스타일
├── useButton.ts ← 내부에서만 쓰는 훅
└── index.ts ← barrel file
이렇게 외부에서 쓸 파일들만 내보내는 index.ts를 Barrel File이라고 한다.
// components/Button/index.ts
export { Button } from './Button';
export type { ButtonProps } from './Button';
// useButton은 내보내지 않음 → 외부에서 쓸 필요 없으니까
내부 구조를 몰라도 폴더 이름만으로 import할 수 있어서, 코드 가독성이 올라가고 import 줄 수가 줄어든다.
//barrel file 없이 → 경로를 다 알아야 함
import { Button } from '@/components/Button/Button';
import { Modal } from '@/components/Modal/Modal';
import { Input } from '@/components/Input/Input';
// barrel file 있으면 → 한 줄로 가능
import { Button, Modal, Input } from '@/components';
파일명이나 폴더구조를 바꿔도 index.ts만 수정하면 된다.
외부에 공개할 것과 내부에서만 쓸 것을 명확히 구분 가능하다.
Button 하나만 필요해도 barrel file을 통하면 그 안에 export된 모든 모듈을 번들러가 불러올 수 있다. tree-shaking이 완벽하지 않은 환경에서는 불필요한 코드가 포함될 수 있다.
프로젝트가 커질수록 barrel file끼리 서로 참조하는 문제가 나타날 수 있다.
파일 하나 수정했는데 barrel file을 통해 연결된 모듈 전체를 다시 로드해야 할 수 있어서, HMR(Hot Module Replacement) 속도가 느려질 수 있다.
IDE에서 "정의로 이동"을 하면 실제 컴포넌트가 아니라 index.ts로 먼저 가게 돼서, 한 번 더 따라가야 하는 불편함이 있다.
Barrel File을 쓸지 말지 애매해서 인터넷에 검색한 결과 여기서도 의견이 분분했다.
작은 프로젝트에서는 유용하겠지만 프로젝트 규모가 커질수록 성능 부분에서 쓰기가 애매한것같았다.
다음 글에서는 실제로 CodIN 프로젝트에서 Barrel File을 쓰는것이 좋을 지 테스트해보도록 하겠다!