Typescript의 moduleResolution 옵션

May 1, 2023 ˑ 4min read

thumbnail

개요#

신규 SPA 프로젝트를 세팅하기 위해 create-vite를 실행했더니 전에는 보지 못했던 설정이 눈에 들어왔습니다. 일단 런타임 환경별로 tsconfig이 분리된 부분과 moduleResolution 옵션으로 bundler라는 값이 설정되어있네요. Typescript팀은 이전에도 React 개발팀과 협업하여 jsx문법에 대한 개선 작업을 진행하고 있다고 들었는데, 이번에는 번들러에 대한 지원도 이뤄지는 듯 하여 궁금증이 생겼습니다. 기존에는 어떤 설정이 있었는지 알아보고 새로 생긴 bundler 옵션은 어떤 이유로 등장했는지 알아보았습니다.

moduleResolution 설정#

Typescript의 moduleResolution은 Typescript 컴파일러(tsc)가 모듈을 해석하는 방법에 대한 설정인데요. Typescript 프로젝트의 모듈 시스템 방식을 결정하는 module 설정에 영향을 받으며 module 설정에 따라 기본 설정값이 달라집니다.

modulemoduleResolution
AMD, UMD, System, ES6, ES2015, …, ESNextclassic
node16node16
nodenextnodenext
그 밖에 다른 설정node
Note

moduleResolution을 한국어로 어떻게 부를지 고민하다가 적당한 의미로 “모듈 해석”을 선택하였습니다. 모듈을 해석한다고 함은, 모듈의 경로를 탐색하여 실제 존재하는 파일로 일치시키는 과정을 의미합니다.

그럼 각 설정에 대해 더 자세하게 알아보겠습니다.

1. node16, nodenext#

Node.js 12버전 이상부터 ECMAScript import와 CommonJS의 require를 모두 지원하며, 이 두가지 방식은 서로 다른 알고리즘을 사용하여 모듈을 해결합니다. 동일한 값의 module 설정과 함께 설정되면 이러한 모듈 해결 방식에 따라 Node.js가 컴파일된 Javascript 코드에서 import 또는 require를 볼지 결정하는 것을 기반으로 올바른 알고리즘을 선택하게 됩니다.

2. node10 (node)#

CommonJS require만을 지원하던 Node.js 10버전 이전의 레거시를 위한 방식으로, 최신 코드에서는 사용할 필요가 없습니다.

3. bundler#

bundler 설정은 Typescript 5.0 버전부터 추가된 옵션으로, 최신 JavaScript 번들러(Vite, Webpack, esbuild 등)와의 통합을 위해 새로 추가되었습니다. 이 설정에서 TypeScript는 번들러가 모듈을 처리하는 방식에 맞춰 모듈 경로를 해석합니다.

node16/nodenext설정과 비교해보면 공통점과 차이점이 있습니다.

[공통점] package.json의 imports와 exports 지원#

bundler 모드는 Node.js의 최신 모듈 해석 방식(node16, nodenext)과 마찬가지로, package.jsonimportsexports 필드를 지원합니다.

Note

package.json의 importsexports 필드

  • imports — 모듈 간 상대 경로를 줄이거나 특정 경로에 별칭을 부여할 때 사용.
  • exports — 패키지의 외부 API를 제어해, 어떤 파일이 노출되는지 정의.

[차이점] 파일 확장자 처리#

bundler 모드는 상대 경로에서 파일 확장자를 강제하지 않습니다. 이러한 특징은 번들러가 파일 확장자를 자동으로 처리하는 방법과 일치합니다.

node16/nodenext 설정에서는 파일 확장자를 명시해야 합니다.

예를 들어, 다음과 같은 TypeScript 코드가 있을때,

Typescript
// example.ts import { foo } from "./utils"; // 상대 경로

node16/nodenext 설정의 경우, TypeScript는 ./utils를 찾을 때 확장자를 명시하지 않으면 경고를 표시합니다.

bash
TS2691: Relative import paths need explicit file extensions in ECMAScript imports. Did you mean './utils.js'?

반면에 bundler 설정은 올바른 파일을 찾아주는 번들러의 방식을 따라 동작하기 때문에 파일 확장자를 따로 명시하지 않아도 됩니다.

요약#

  • bundlernode16/nodenext처럼 package.jsonimportsexports을 지원합니다.
  • 하지만 bundler 모드는 번들러 동작에 맞춰 상대 경로에서 파일 확장자를 요구하지 않습니다.
  • 결론적으로, 번들러와 함께 사용하는 경우라면 moduleResolution: "bundler"가 더 간편하게 동작합니다.

TSConfig Reference - Docs on every TSConfig optionFrom allowJs to useDefineForClassFields the TSConfig reference includes information about all of the active compiler flags setting up a TypeScript project.Link Previewhttps://www.typescriptlang.org/tsconfig/#moduleResolution TSConfig Reference - Docs on every TSConfig optionFrom allowJs to useDefineForClassFields the TSConfig reference includes information about all of the active compiler flags setting up a TypeScript project.Link Previewhttps://www.typescriptlang.org/tsconfig/#module

Related Articles

Github

Linkedin

Instagram