일하면서 메모 차원에서 남기는 게시글입니다.
tsconfig.json에서 moduleResolution 옵션은 TypeScript가 모듈을 어떻게 해석할지를 정의하는 설정입니다. 이는 TypeScript가 import나 require로 모듈을 가져올 때, 해당 모듈을 어디서 찾고 어떤 방식으로 해석할지 결정하는 중요한 부분입니다.
1. 기본 설명
moduleResolution은 TypeScript 컴파일러가 모듈 경로를 찾는 방식(모듈 해석 전략)을 결정합니다. TypeScript는 두 가지 기본적인 모듈 해석 전략을 제공합니다:
- node: Node.js의 모듈 해석 방식과 동일한 방식입니다. node_modules 디렉토리를 탐색하며, .js, .jsx, .ts, .tsx, .json 확장자를 가진 파일을 찾습니다.
- classic: TypeScript 1.6 이전에 사용되던 모듈 해석 방식입니다. ECMAScript 모듈 시스템을 따르며, 주로 전통적인 브라우저 환경에서 사용됩니다.
2. moduleResolution 값
- node: Node.js의 모듈 시스템을 기반으로 모듈을 해석합니다. 대부분의 프로젝트에서 이 옵션을 사용합니다. Node.js에서 모듈을 찾는 방식과 유사하며, node_modules에서 모듈을 찾습니다.이 방식에서는 import나 require로 모듈을 가져올 때, 해당 모듈이 로컬 디렉토리 또는 node_modules 디렉토리에서 찾을 수 있습니다. 해당 모듈이 패키지에 없으면 상위 디렉토리로 올라가면서 탐색합니다.
{
"compilerOptions": {
"moduleResolution": "node"
}
}
- classic: TypeScript의 초기 버전에서 사용하던 방식으로, 모듈을 현재 디렉토리와 그 상위 디렉토리에서만 찾습니다. node_modules 디렉토리를 탐색하지 않으며, 브라우저 환경에서의 전통적인 파일 참조 방식과 유사합니다.이 방식은 주로 레거시 코드를 위해 사용되며, import된 모듈을 현재 디렉토리와 그 상위 디렉토리에서만 찾습니다.
{
"compilerOptions": {
"moduleResolution": "classic"
}
}
3. 기타 관련 설정
moduleResolution은 모듈을 찾는 과정에서 다른 설정들과도 밀접한 관련이 있습니다:
- baseUrl: 모듈 해석의 기본 경로를 설정합니다. baseUrl을 설정하면 import 시 상대 경로뿐만 아니라, baseUrl로부터의 경로도 사용할 수 있습니다.
- paths: 모듈 해석 경로에 대한 별칭을 설정할 수 있습니다. paths 옵션은 모듈을 특정 경로로 매핑하는 데 유용합니다.
- rootDirs: TypeScript에서 여러 디렉토리를 논리적으로 결합하여 하나의 디렉토리인 것처럼 취급할 때 사용됩니다.
- module: TypeScript의 출력 모듈 시스템을 설정합니다. 이 값에 따라 moduleResolution의 기본값이 달라질 수 있습니다. 예를 들어, module: esnext일 때는 기본적으로 moduleResolution: node가 사용됩니다.
4. Node.js 방식 vs Classic 방식
- Node 방식: 파일 확장자를 자동으로 추가하거나, 패키지 내의 index 파일을 자동으로 불러오는 기능을 제공합니다. 예를 들어, import { x } from './module'에서 module.js나 module/index.js 파일을 자동으로 찾습니다.
- Classic 방식: 브라우저에서 스크립트를 로드할 때처럼, 파일 경로를 엄격하게 따릅니다. 즉, ./module을 import할 때 해당 파일이 정확히 존재해야 하며, 확장자를 자동으로 추론하지 않습니다.
예시
Node 방식 모듈 해석 (기본)
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node"
}
}
Classic 방식 모듈 해석
{
"compilerOptions": {
"module": "es2015",
"moduleResolution": "classic"
}
}
moduleResolution: "bundler"는 TypeScript 5.0에서 도입된 새로운 모듈 해석 전략으로, 번들러(예: Vite, Webpack, esbuild)가 모듈을 처리하는 방식을 더 잘 반영하기 위해 만들어졌습니다. 이 옵션은 번들러가 처리하는 방식과 유사한 방식으로 모듈을 해석하도록 TypeScript를 설정합니다. 번들러들이 자체적으로 모듈을 처리할 때 TypeScript와 충돌이 일어나지 않도록 최적화된 방식입니다.
주요 특징 및 동작 방식
- Ecosystem Alignment: 번들러들이 모듈을 처리하는 방식과 더 유사하게 작동합니다. 번들러는 Node.js의 해석 방식을 따르지만, 때때로 TypeScript의 node 모듈 해석 방식과 다르게 동작할 수 있습니다. bundler 옵션은 이러한 차이를 조정하여 TypeScript가 번들러와 동일하게 모듈을 처리하도록 돕습니다.
- 최적화된 동작:
- 파일 확장자 처리: 번들러들이 일반적으로 .js, .ts, .jsx, .tsx 등의 확장자를 자동으로 해석하고 처리하는 것처럼, bundler 해석 모드도 확장자를 명시하지 않아도 자동으로 처리합니다.
- 패키지 처리: Node.js 스타일로 패키지 내 package.json의 main 또는 exports 필드를 읽어서, 번들러가 처리하는 방식과 유사하게 모듈을 찾습니다. 이는 TypeScript가 번들러 환경에서 패키지를 처리하는 방식과 더 일치하게 만듭니다.
- Alias 및 Paths 매핑: 번들러에서 alias 설정을 사용하거나, TypeScript에서 paths 옵션을 설정하여 경로 별칭을 사용하는 경우, bundler 모듈 해석 방식은 이러한 별칭을 더 일관성 있게 처리합니다.
- ESM과의 호환성: 번들러들이 ESM(ES Modules)을 처리하는 방식과 호환되도록 최적화되어 있습니다. TypeScript가 ESM 모듈을 해석할 때, 번들러와 같은 방식으로 파일과 모듈을 찾습니다.
moduleResolution: "bundler"가 필요한 경우
이 옵션은 특히 다음과 같은 상황에서 유용합니다:
- 번들러 기반 프로젝트: Vite, esbuild, Webpack 등 최신 번들러를 사용하여 프로젝트를 빌드하는 경우, 번들러의 모듈 해석 방식과 TypeScript의 해석 방식이 충돌하지 않도록 도와줍니다.
- ESM 및 CommonJS 모듈이 혼재된 프로젝트: 번들러들이 혼합된 ESM 및 CommonJS 모듈을 처리하는 방식에 맞춰, TypeScript도 적절히 모듈을 해석합니다.
- 경로 Alias 사용: 번들러의 경로 별칭(예: Webpack의 resolve.alias 또는 Vite의 alias 설정)과 TypeScript의 paths 설정을 함께 사용할 때, bundler 옵션은 모듈 해석의 일관성을 유지하는 데 도움을 줍니다.
예시
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler",
"paths": {
"@components/*": ["src/components/*"]
}
}
}
이 설정에서 TypeScript는 번들러가 파일을 찾는 방식과 동일하게 모듈을 해석하며, @components/*와 같은 경로 별칭도 번들러 방식으로 처리합니다.
주의사항
- moduleResolution: "bundler"는 TypeScript가 모듈을 해석하는 방식만을 변경할 뿐, 실제 번들링 과정은 번들러가 수행합니다. 즉, 번들링 자체는 여전히 Webpack, Vite, esbuild와 같은 도구가 처리하게 됩니다.
- 최신 번들러와의 호환성에 초점을 맞추고 있기 때문에, 번들러가 모듈을 처리하는 방식에 따라 달라질 수 있는 일부 모호한 모듈 해석 문제를 해결하는 데 도움을 줍니다.
정리
moduleResolution: "bundler"는 번들러 환경에서 TypeScript가 모듈을 보다 일관성 있게 처리하도록 돕는 설정입니다. 번들러가 모듈을 해석하는 방식과 동일한 흐름을 따르므로, 최신 프론트엔드 도구와의 호환성을 강화하며, 특히 경로 별칭이나 ESM/UMD 모듈 처리에서 발생할 수 있는 문제들을 해결하는 데 매우 유용합니다.
'프론트엔드 개발' 카테고리의 다른 글
react-native 에서 tailwind 문법으로 스타일 적용하기 (twrnc 라이브러리) (0) | 2024.11.13 |
---|---|
Next.js 서버사이드/클라이언트 사이드 분산추적/모니터링 툴 elastic-node-apm, elastic-rum 설치 이슈와 해결방법 (0) | 2023.12.02 |
HTML 정리 (0) | 2021.04.08 |
2022년 03월 까지 웹 개발 정복하기 (21.05.26 up) (0) | 2021.04.07 |