ts-node로 실행 시 Cannot find module... 오류 해결

윤학·2024년 10월 2일
0

Typescript

목록 보기
1/1
post-thumbnail

NestJS에서 작업 중 간단한 스크립트를 작성할 일이 있어 ts파일로 작성했다.

스크립트 실행은 npm script를 통해서 아래와 같이 작성하였고, 실행을 시키니 Cannot find module... 에러가 났다.

"script:start": "ts-node main.ts"

스크립트 파일에서 프로젝트 내에 있는 모듈을 가져오는 부분이 있었다.

근데 다른 모듈의 경로를 상대경로가 아닌, 비 상대 경로로 가져오고 있었고, 이는 tsconfig.json 파일에서 path 옵션을 통해 alias로 지정해놓은 상태였다.

단순하게 예를 들어보자.

프로젝트가 아래와 같이 되어있다고 가정해보자.

packages/user/src
├── config
│   ├── app-config.schema.ts
│   ├── app-config.value.ts
│   └── index.ts
├── email
│   ├── email.constant.ts
│   └── index.ts
├── main-app.controller.ts
├── main-app.module.ts
├── main-app.service.ts
├── main.ts
├── phone
│   └── phone.service.ts
└── validation-array.dto.ts

tsconfig.json

"module": "commonjs",
"paths": {
      "@packages/user": [
        "packages/user/src"
      ],
      "@packages/user/*": [
        "packages/user/src/*"
      ],
}

packages/user/email/email.constant.ts에 값을 하나 입력해둔다.

packages/user/email/email.constant.ts

export const EMAIL = 'MODULE FOUND!!!';

이제 프로젝트 루트 위치(packages 폴더 위치)에 EMAIL 값을 출력하는 스크립트 하나를 작성해보자.

main.ts

import { EMAIL } from "@packages/user/email";

function main() {
	console.log(EMAIL);
}

main();

그리고 실행시켜보면

에러가 나버린다.

왜일까?

Typescript에서 모듈을 해석할 때의 전략은 ClassicNode 2가지가 있다.

tsconfig.json에 작성된 compilerOptions 옵션 중 module의 값이 AMD | System | ES2015인 경우 Classic, 나머지는 모두 Node로 된다.

나의 경우 commonjs로 설정했기 때문에 Node 전략으로 해석되는데,
Node 전략에서의 비 상대적 경로를 해석하는 방법은 루트까지 올라가면서 node_modules 안에서 파일을 첫 번째로, 폴더를 다음으로 찾는다고 한다.

자세한 과정은 이곳에서 확인하실 수 있습니다.

위에서 내가 작성한 기준으로 살펴보면
main.ts에서 @packages/user/email를 import 하고 있으므로

node_modules/packages/user/email.ts
.
.
.
node_modules/packages/user/email/index.ts

만약 스크립트 파일을 packages/main.ts에서 작성했다고 한다면

packages/node_modules/packages/user/email.ts
.
.
packages/node_modules/packages/user/email/index.ts
.
.
node_modules/packages/user/email.ts
.
.
node_modules/packages/user/email/index.ts

이런식으로 찾아 나갈거다.

결국 찾지 못하게 되므로 node_modules 폴더가 아닌 tsconfig.jsonpath 경로를 읽어 불러올 수 있도록 tsconfig-paths/register 모듈을 사용하여 해결해보자.

package.json

"script:start": "ts-node -r tsconfig-paths/register main.ts"

정상적으로 동작하는 것을 확인할 수 있다.

참고

tsconfig-paths
Module Resolution
NodeJS

0개의 댓글