Trouble Shooting
2026년 03월 24일

FSD 아키텍처 파일구조 관련 트러블슈팅

📝 FSD 아키텍처 가이드: 위젯 그룹화와 배럴 파일(Barrel File) 패턴의 이해

💡 Q1. 여러 위젯을 특정 폴더(예: home)로 묶어 관리할 때, 상위에 home/index.ts를 두어 하위 위젯들을 한꺼번에 export 해도 되나요?

A. 권장하지 않습니다! (FSD 안티패턴)

각각의 개별 위젯 폴더(슬라이스) 내부에 위치한 index.ts를 핵심 진입점(Public API)으로 유지하시고, 이것들을 다시 하나로 묶어 내보내는 최상단의 home/index.ts는 만들지 않는 것이 FSD의 표준 프랙티스입니다.

🚫 안티패턴 (배럴 파일 방식)

widgets/ home/ index.ts <-- (X) 하위 위젯들을 모아서 내보내는 파일 (생성 금지) trending-posts/ TrendingPosts.tsx <-- (X) 자체 index.ts 없음 job-opportunities/ JobOpportunities.tsx <-- (X) 자체 index.ts 없음

✅ FSD 표준 (개별 슬라이스 독립)

widgets/ home/ <-- 단순히 디렉토리를 묶기 위한 논리적 폴더 (index.ts 없음) trending-posts/ index.ts <-- (O) 외부로 내보내는 독립된 진입점 TrendingPosts.tsx job-opportunities/ index.ts <-- (O) 외부로 내보내는 독립된 진입점 JobOpportunities.tsx

💡 Q2. 상위에서 한꺼번에 export 하면 import { A, B } from "@widgets/home처럼 쓸 수 있어 훨씬 편한데, 왜 이 방식을 금지하나요?

A. 타이핑의 편리함보다 '아키텍처의 안정성과 투명한 의존성 관리'가 훨씬 더 중요하기 때문입니다.

이렇게 특정 폴더의 index.ts 한 곳에서 모든 하위 모듈을 내보내는 방식을 배럴 파일(Barrel File) 패턴이라고 부릅니다. 이를 사용하면 슬라이스 간의 격리가 무너지고 내부적으로 순환 참조(Circular Dependency) 위험이 커집니다.

🚫 안티패턴: 의존성이 얽히기 쉬운 방식

// 📄 widgets/home/index.ts (배럴 파일 - 만들면 안 됨) export { TrendingPosts } from './trending-posts/TrendingPosts'; export { JobOpportunities } from './job-opportunities/JobOpportunities'; // 📄 pages/home/HomePage.tsx // ❌ 타이핑은 편리하지만, 의존성 트리에 JobOpportunities 코드까지 통째로 연결됨 import { TrendingPosts, JobOpportunities } from '@/widgets/home';

✅ FSD 표준: 명시적이고 독립적인 의존성

// 📄 pages/home/HomePage.tsx // ⭕ 각각의 슬라이스 진입점에서 필요한 것만 직접 가져옴 import { TrendingPosts } from '@/widgets/home/trending-posts'; import { JobOpportunities } from '@/widgets/home/job-opportunities';
임포트 구문이 다소 길어지는 불편함은 감수하더라도, 앱의 규모가 커졌을 때 엉뚱한 코드가 딸려오거나 스파게티처럼 얽히는 것을 근본적으로 차단하는 것이 FSD의 핵심 철학입니다.

💡 Q3. 한 번에 묶어서 import 하더라도, 최신 모던 번들러가 알아서 안 쓰는 코드는 트리셰이킹(Tree-shaking) 해주지 않나요?

A. 가장 흔한 오해 중 하나입니다. 실제 모던 생태계(Vite, Webpack, Next.js 등)에서는 배럴 파일 패턴이 오히려 트리셰이킹과 로딩 속도에 심각한 악영향을 미칩니다.

🐌 배럴 파일 사용 시 (트리셰이킹이 방해받는 과정)

// 오직 단 한 개의 위젯만 필요해서 임포트했지만... import { TrendingPosts } from '@/widgets/home';

☝️ 위처럼 코드를 작성하면, 번들러는 일단 @/widgets/home/index.ts 전체를 읽어야 합니다. 이때 그 안에 묶여있는 JobOpportunities사용하지 않는 다른 모듈들의 파일까지 전부 찾아가서 메모리에 올리고 해석(Evaluate)하게 됩니다. 이로 인해 개발 서버(Dev Server) 최초 로딩 속도가 심각하게 느려지고, 예상치 못한 사이드 이펙트로 인해 빌드 용량이 뚱뚱해질 수 있습니다.

🚀 직접 임포트 시 (완벽한 트리셰이킹 달성)

// 무조건 단일 슬라이스 경로를 직접 지칭 import { TrendingPosts } from '@/widgets/home/trending-posts';

☝️ 번들러는 오직 trending-posts 폴더 하나만 정확히 찔러서 참조합니다. 불필요한 다른 폴더(job-opportunities)의 코드는 원천적으로 쳐다보지도 않게 되므로 가장 가볍고 완벽한 트리셰이킹과 쾌적한 개발 환경 로딩 속도를 보장 받습니다.


🎯 결론 및 베스트 프랙티스

FSD에서는 import 구문의 **'편리함'**을 조금 포기하는 대신, 압도적인 **'빌드 및 로딩 성능(완벽한 트리셰이킹)'**과 꼬이지 않는 **'안정적인 의존성 구조'**를 얻습니다.