TypeScript/ESM import 경로 정리: '@', '#', 상대 경로의 의미와 설정

개요 TypeScript와 ESM에서 자주 보이는 세 가지 import 패턴 import … from ‘@…’ import … from ‘…’ import … from ‘#…’ 표기만 비슷할 뿐, 해석 주체와 동작 범위가 다름 ‘@‘는 경로 별칭 또는 npm 스코프 패키지 의미 가능 ‘…‘는 상대·절대 경로로 파일 시스템 기준 해석 ‘#‘는 Node.js 패키지 imports 또는 브라우저 import maps에서의 별칭으로 사용 아래에서 각 패턴의 의미, 설정 지점, 주의사항을 정리함 ‘@…’ 경로의 두 가지 의미 1) 경로 별칭 path alias 의도: 길고 복잡한 상대 경로를 짧게 추상화 설정 지점: tsconfig.json 의 compilerOptions.paths와 baseUrl 예시 { "compilerOptions": { "baseUrl": "./", "paths": { "@models/*": ["src/models/*"], "@utils/*": ["src/utils/*"] } } }import { User } from '@models/User' import { calculate } from '@utils/math' 장점 상대 경로를 단순화, 가독성 및 리팩터링 내성 향상 주의 tsconfig paths는 타입 체크러와 에디터가 이해하는 별칭일 뿐, 런타임 해석자는 아님 Node.js 런타임은 tsconfig paths를 모름. 번들러 설정별 alias 또는 전용 로더를 함께 구성 필요 예: Vite, Webpack, ts-node, tsconfig-paths 등 도구별 설정 일치 필요 2) 스코프된 패키지 scoped package 의미: npm 조직·팀·프로젝트 네임스페이스로 묶인 패키지 집합 표기: @scope/package-name 형태 @nestjs/swagger, @angular/core 등 사용 이유 네임스페이스로 이름 충돌 회피 관련 패키지의 그룹화와 공개·비공개 관리 설치 npm install @nestjs/swagger 해석 이 경우 ‘@‘는 경로 별칭이 아닌 패키지 이름의 일부로 동작 tsconfig paths와 무관. Node/npm가 패키지 이름으로 직접 해석 ‘…’ 상대·절대 경로 import 상대 경로 ‘./’, ‘../’ 기준으로 현재 파일 위치에서 탐색 절대 경로 ‘/path’는 실행 환경마다 기준이 다름 브라우저 ESM에서는 오리진 기준 절대 URL 경로 해석 Node.js에서는 파일 시스템 루트 절대 경로로 해석되어 이식성 낮음 예시 import { User } from './models/User' import { calculate } from '../utils/math' 장점 추가 설정 없이 즉시 동작, 모든 환경 공통 동작 모델 모듈 간 물리적 의존 관계가 드러남 단점 디렉터리 깊어질수록 ../../../ 형태로 복잡도 상승 구조 변경 시 경로 대량 수정 발생 ‘#…’ 경로의 의미 ‘#{name}’ 표기는 두 가지 서로 다른 맥락에서 등장함. 혼동 주의 ...

January 23, 2026