Day.js 오류 해결 완벽 가이드 Cannot read properties of undefined (reading '$i') with ESM CommonJS

typescript로 개발을 할때 날짜를 가지고 이것저것 활요해서 개발을 해야할 때가 있습니다.

저는 그럴 때 day.js라는 모듈을 사용하고 있는데요.

이모듈을 사용하는 과정에서 발생한 오류를 기록해보고자 합니다.

1.오류발생

평소와 같이 개발을 한뒤에 빌드를 진행하고 메서드를 실행해 보았습니다.
그때, 위처럼 개발도중에 TypeError: Cannot read properties of undefined (reading '$i') 라는
오류문구가 뜨면서 에러가 발생을 하는걸 확인했습니다.

2.오류의 원인

TypeError: Cannot read properties of undefined (reading '$i') 오류는 말 Days.js를 사용할때 발생하는 문제인데요.

이것은 저의 경우엔 Days.js를 아래와 같이 ESM 방식의 사용을 하다가 발생한 오류입니다.

import * as dayjs from 'dayjs';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import customParseFormat from 'dayjs/plugin/customParseFormat'; // YYYYMM 파싱용
dayjs.extend(customParseFormat);
dayjs.extend(isSameOrBefore);

저는 날짜 비교를 위해서 위처럼 import를 해서 사용을 할 생각이었는데 해당 코드에서 위와 같은  
TypeError: Cannot read properties of undefined (reading '$i') 오류를 반환하는 것을 확인했습니다.

원인을 확인해보니 ESM 방식으로 import를 하면 실제 dayjs의 객체가 default 안에 있기 때문에
제가 위에서 dayjs.extend()를 호출하여도 extend() 자체가 없어서 오류를 반환 하는 상황이었습니다.

또 플러그인도 위와 동일한 이유로
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';를 사용하면 함수가 아니라 {defulat:f} 형태로 넘어오기 때문에
extend에서 $i 플래그를 읽는 과정에서daysjs 인스턴스가 제대로 있지 않아 오류를 발생시키게 되는겁니다.

한줄요약

  • dayjs import : import * as dayjs => dayjs.default 인스턴스에 함수가 있음
  • 플러그인 import : ESM 빌드에선 {default :fn} 형식으로 전달
  • extend 호출 : day.js 인스턴스가 아니기 때문에 오류 발생

오류 해결

위처럼 ESM 빌드로 import를 하게되면 default가 실제 인스턴스여서 오류가 발생하기 때문에 이를 CommonJS import 방식으로 변경해줘야 합니다.

   const dayjs = require('dayjs');
   const customParseFormat = require('dayjs/plugin/customParseFormat');
   const isSameOrBefore = require('dayjs/plugin/isSameOrBefore');

   dayjs.extend(customParseFormat);
   dayjs.extend(isSameOrBefore);

위와 같이 require()를 사용해서 impoort 하게 되면 dayjs 인스턴스 자체를 가져오기때문에 deafult를 찾아올 필요가 없게 됩니다.

이는 Node.js/Nest.js는 CommonJS 환경이 기본이기 때문에 require로 import하는 것이 좋기 때문입니다.

tsconfig.json

물론 최신버젼의 프레임워크와 tsconfig에서 module의 설정을 esnext로 변경하면 ESM이 가능하지만 왠만해서는 안정성과 호환성 때문에 CommonJS 사용을 권하고 있습니다.

결과

위처럼 CommonJS로 변경한 결과 아래와 같이 정상적으로 빌드가 되는 부분을 확인 할 수 있었습니다.

 

작은 설정 하나가 코드 실행에도 아주 중요한 영향을 끼칩니다. 이를 파악하기 위해선 해당 개발 환경과 구조 원리를 알아야지만 빠르게 오류를 수정할 수 있고 더 좋은 방식의 코드를 생산 할수 있는것 같습니다.

반응형