NodeJS

자바스크립트 ESM (ES Module)에서 __dirname 사용하기

ESM 모듈 시스템을 사용하여 자바스크립트를 개발하는 도중 한가지 난관에 부딪힐 때가 있습니다. 그건 바로 기존의 commonjs 환경에서 사용되던 __dirname이 ESM 코드에서 undefined 값이 되는 문제입니다. 주요 에러는 다음과 같습니다.

ReferenceError: __dirname is not defined in ES module scope
    at file:///C://Users/test/Project/index.js:14:13
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)  
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:385:
24)
    at async loadESM (node:internal/process/esm_loader:88:5)        
    at async handleMainPromise (node:internal/modules/run_main:61:12
)

__dirnameNodeJS에서 기본으로 제공되는 환경 변수입니다. 유사한 변수는 __filename이 있는데 이 두가지 변수가 리턴하는 값은 다음과 같습니다.

  • __dirname: 현재 스크립트를 실행한 프로젝트의 디렉토리 경로
  • __filename: 현재 스크립트를 실행한 프로젝트의 전체 파일 경로

예를 들어 node 명령을 C:\Users\test\Desktop\Project에서 실행했다면, __dirname__filename의 값은 다음과 같습니다.

$ node index.js
__dirname is 'C:\Users\test\Desktop\Project'
__filename is 'C:\Users\test\Desktop\Project\index.js'

__dirname을 별도 선언 없이 사용했었지만 ESM에서는 이러한 변수가 NodeJS에서 기본 지원되지 않습니다. 따라서 위와 같은 에러 메시지가 출력되는 것입니다. 이는 __filename 변수도 마찬가지입니다.

ESM __dirname is not defined 해결 방법

이 문제는 아래와 같은 방법으로 ESM 모듈에서 __dirname을 직접 선언하여 해결할 수 있습니다.

import { dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));

여기서 pathurl 모듈을 사용하는데, pathdirname 메소드는 주어진 파일 경로에서 디렉토리 경로만 리턴하는 메소드이고, urlfileURLToPath 메소드는 올바른 파일 경로로 컨버팅하고 퍼센트 인코딩을 디코딩해주는 역할을 합니다.

import.meta의 경우 현재 실행 중인 스크립트의 정보를 표시하는데, 아래와 같이 JSON 데이터로 값을 반환합니다.

console.log(JSON.stringify(import.meta));

// Result: {"url":"file:///C:/Users/test/Desktop/Project/index.js"}

여기서 url 키 정보를 사용하기 위해 위 코드에서 import.meta.url을 사용하였습니다. 이렇게 조합하여 나온 리턴값은 기존에 사용하던 __dirname의 값과 같아집니다.

마찬가지로 __filename을 사용하고 싶은 경우 위 예시에서 dirname 메소드를 빼고 사용하시면 됩니다.

import { dirname } from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
JooTC

안녕하세요. 테크놀로지에 관심이 많은 블로거입니다.

Recent Posts

[iOS] Xcode ‘You do not have required contracts to perform an operation’ 해결

Xcode에서 iOS 애플리케이션을 빌드(Archive)하고 App Store Connect에 앱을 업로드하는 도중, 아래와 같은 에러가 발생하면서 더…

1개월 ago

[안드로이드] INSTALL_FAILED_INSUFFICIENT_STORAGE 해결

INSTALL_FAILED_INSUFFICIENT_STORAGE 문제 안드로이드 스튜디오에서 에뮬레이터를 실행하고 개발중인 애플리케이션을 실행하려 하면 로그 창에 아래와 같이 표시되면서…

7개월 ago

Zalgo 텍스트와 이를 방지하는 방법

인터넷 커뮤니티 사이트에서 게시글이나 댓글에 간혹 장난을 목적으로 작성된 특이한 글자를 볼 수 있습니다. 위…

9개월 ago

리눅스 kill, killall 명령어 – 특정 프로세스 종료하기

리눅스 명령어 - kill, killall 리눅스 kill 명령어는 특정 프로세스를 종료해주는 명령어입니다. 백그라운드에서 실행되고 있는…

9개월 ago

JavaScript typeof null이 ‘object’인 이유

JavaScript는 역사가 긴 스크립트 프로그래밍 언어입니다. 세월이 흐르면서 많은 자바스크립트 표준이 만들어졌고, 현재는 많은 문법적…

9개월 ago

Mocha Error: Resolution method is overspecified. 해결 방법

NodeJS 테스트 프레임워크인 Mocha는 비동기 테스트를 지원합니다. 간혹 특정 테스트 스크립트를 작성하고 실행하면 아래와 같이…

9개월 ago