tsconfig.json esModuleInterop, allowSyntheticDefaultImports

정민교·2024년 5월 20일
0

목록 보기
3/3

📒tsconfig.json

tsconfig.json 파일은 TypeScript 프로젝트의 구성 파일로, 컴파일러 옵션 및 컴파일 할 파일 포함/제외 설정을 정의하는 데 사용됩니다.

이 파일을 통해 TypeScript 컴파일러(tsc)가 프로젝트를 어떻게 해석하고 변환해야 하는지를 지정할 수 있습니다.

tsconfig.json은 프로젝트 루트 디렉터리에 위치하며, TypeScript 컴파일러가 이 파일을 찾고 그 설정을 따라 프로젝트를 컴파일합니다.

📒esModuleInterop

CommonJS와 ES6 모듈 시스템 간의 상호 운용성을 향상시키기 위해 도입되었습니다.

이 옵션을 사용하면 CommonJS 스타일로 작성된 모듈을 ES6 모듈 시스템과 더 잘 호환되도록 만듭니다.

✔️CommonJS 모듈의 default 내보내기 지원

CommonJS 모듈은 module.exports를 통해 내보내기를 합니다.

esModuleInterop 옵션을 사용하면 TypeScript가 이러한 모듈을 ES6 모듈처럼 처리하여 default import 구문을 사용할 수 있게 합니다.

✔️__esModule 속성 추가

이 옵션을 활성화하면 TypeScript는 컴파일된 파일에 __esModule 속성을 추가합니다. 이 속성은 모듈이 ES 모듈로 간주되도록 도와줍니다

✔️예시

tsconfig.json에 esModuleInterop 옵션을 활성화합니다.

{
  "compilerOptions": {
    "esModuleInterop": true
  }
}

다음과 같이 commonJS 스타일로 export 구문(module.exports)를 사용하여 모듈 내보내기를 작성

module.exports = {
  foo: 'bar'
};

그럼 다음과 같이 import 문을 작성할 수 있습니다.

import example from './example';

console.log(example.foo); // 'bar'

esModuleInterop 옵션이 활성화 되어있지 않으면

import * as example from './example';

console.log(example.foo); // 'bar'

이렇게 작성해야 합니다.

📒CommonJS와 ESModule 시스템

기본적으로 (esModuleInterop가 false이거나 설정되지 않은 경우) TypeScript는 CommonJS/AMD/UMD 모듈을 ES6 모듈과 유사하게 처리합니다.

이 과정에서 특히 두 가지 잘못된 부분이 있습니다.

✔️두 모듈 시스템의 import와 export

  • CommonJS: Node.js에서 사용하는 모듈 시스템으로, module.exportsrequire()를 사용합니다.
  • ES6 모듈: 최신 JavaScript 표준에서 사용하는 모듈 시스템으로, exportimport를 사용합니다.

✔️문제

📌네임스페이스 import

import * as moment from "moment";

TypeScript는 위의 코드를 다음과 같이 처리합니다

const moment = require("moment");

그러나 ES6 모듈 사양에 따르면, import * as x는 항상 객체여야 합니다. 하지만 moment는 함수일 수 있어서, 이렇게 사용하면 사양에 맞지 않습니다.

📌기본(default) import

import moment from "moment";

TypeScript는 위의 코드를 다음과 같이 처리합니다:

const moment = require("moment").default;

그러나 대부분의 CommonJS 모듈은 default 속성을 가지지 않기 때문에, 이렇게 하면 오류가 발생할 수 있습니다.

✔️esModuleInterop 옵션

esModuleInterop 옵션을 true로 설정하면 Typescript가 이러한 차이를 자동으로 처리하여 모듈을 올바르게 가져올 수 있습니다.

따라서 이 옵션을 사용하면 ES6 모듈과 CommonJS 모듈간의 호환성이 높아집니다.

📌TypeScript의 export = 구문

TypeScript에서 export = 구문은 typescript 에서 CommonJS 스타일의 내보내기를 의미합니다.

export = winston;

이 구문은 module.exports = winston;와 동등합니다. TypeScript는 이를 CommonJS와 ES6 모듈 시스템 간의 상호 운용성을 위해 지원합니다.

따라서 다음과 같이 CommonJS 스타일의 import 구문을 사용합니다.

import winston = require('winston')

📌import * as winston from 'winston'

네임스페이스 import인 import * as winston from "winson"const winston = require("winston")와 동일하게 작동합니다.

하지만 앞에서 이야기했던 문제로 esModuleInterop 옵션을 true로 사용하여 호환성에 문제가 없도록 설정하고 사용하는 것이 좋습니다.

이 구문은 ES6 모듈의 namespace import를 사용하여 winston 모듈의 모든 내보내기된 항목을 하나의 객체로 가져오는 것입니다.

export =와 함께 사용하면, 모든 내보내기된 항목을 포함하는 네임스페이스 객체를 가져오게 됩니다.

import * as winston from 'winston';

// winston은 여기서 모듈의 모든 내보내기된 항목을 포함합니다.

이 경우, winston 객체는 모듈의 모든 기능과 속성을 포함한 전체 객체를 나타냅니다.

📌import winston from 'winston'

이 구문은 ES6 모듈의 default import를 사용하여 winston 모듈을 가져오는 것입니다.

TypeScript에서 export = 와 함께 default import를 사용할 때, TypeScript는 export =를 ES6의 default export로 간주하여 모듈의 기본 내보내기 값만 가져옵니다.

default import를 사용하기 위해서는 allowSyntheticDefaultImports 옵션을 활성화하여 기본 import를 사용할 수 있도록 해야합니다.

마찬가지로 esModuleInterop 옵션도 활성화하여 CommonJS 모듈과의 호환성을 확보하는 것이 좋습니다.

import winston from 'winston';

// winston은 여기서 기본 내보내기 값만 가져옵니다.

📒요약

tsconfig.json의 esModuleInterop 옵션은 ES 모듈과 CommonJS 모듈 간의 호환성을 제공합니다.

기본적으로 namespace import를 사용하는 것이 안전하지만, 호환성 문제가 있을 수 있으므로 esModuelInterop 옵션을 활성화 하는 것이 좋습니다.

default import 또한 사용하기 위해서는 allowSystheticImports 옵션 또한 활성화 해야합니다.

import winston from 'winston':
  • 기본 내보내기 값만 가져옵니다.
import * as winston from 'winston':
  • 모든 내보내기된 항목을 포함한 전체 객체를 가져옵니다.
profile
백엔드 개발자

0개의 댓글