일단 대부분의 경우 Node.js와 타입스크립트를 같이 쓸 때 , 그리고 ESM 모듈을 불러올 때 해당 에러가 발생할 겁니다.
TS2307: Cannot find module 패키지명 or its corresponding type declarations.
설마 타입 정의가 없는 패키지를 받으신 건 아니죠..? 그러면 @types를 설치하거나 직접 declare module로 타이핑을 하면 됩니다.
이 글은 CommonJS에서 ESM을 import할 때 발생하는 TS2307 에러에 대해 다룹니다.
먼저 모듈을 Node16으로 맞춰줍니다. Node16이면 현재 프로젝트가 CommonJS면 CommonJS로 결과를 내놓고, ESM이면 ESM으로 결과를 내놓습니다.
"module": "Node16",
그리고 import 대신에 dynamic import문을 사용해야 합니다. import('모듈명')을 해서 Promise로 모듈 결괏값을 받으면 됩니다. 이 게시글 참조 이러면 모든 에러가 사라집니다.
여기서 문제가 type만 import하고 싶을 때입니다. import type을 하는 경우는 ESM이든 CommonJS이든 상관 없지 않느냐 할 수 있는데(실제로 저도 왜 에러가 나는지 이해가 안 됩니다) 여전히 다음과 같은 에러가 남아 있습니다.
import type { ShowPropertyProps } from 'adminjs'; // adminjs에서 에러
TS1479: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("adminjs")' call instead.
typescript 5.2까지는 다음과 같이 할 수밖에 없습니다.
// @ts-expect-error
import type { ShowPropertyProps } from 'adminjs';
@ts-expect-error를 붙여주면 해결됩니다. 그런데 @ts-expect-error를 쓰는 것에서 에러가 난다면 .eslintrc에서 rules로 ban-ts-comment를 off 해줍시다.
rules: {
...
'@typescript-eslint/ban-ts-comment': 'off',
...
}
typescript 5.3부터는 다음과 같이 할 수 있게 되었습니다. import attributes 문법입니다.
import type { ShowPropertyProps } from 'adminjs' with { 'resolution-mode': 'import' };