개인적으로 진행해보는 프로젝트에서 서버의 로그를 쌓기 위해 멘삼딱 강의를 따라하면서 사용했던 pino라는 라이브러리를 사용하였다. 그런데 강의를 따라할 때는 발생하지 않았던 ERR_REQUIRE_ESM 오류가 발생하였다.
해당 오류는 node v20.19.0 버전 미만 환경이 아니라면 발생하지 않았을 수도 있다.
해결만 빠르게 하고 싶은 사람들을 위해 원인과 해결책 부터 적어보았다.
pino-pretty 13.0.0 버전에서 13.1.0으로 업데이트 과정에서 strip-json-comments 의존성을 v3 -> v5로 변경되었는데 해당 버전은 pure ESM 으로 변경되었다. 그런데 13.1.0 버전에서 여전히 require('strip-json-comments')로 사용하고 있어 오류가 발생한다
yarn node v1.22.18
✨ Done in 0.26s.
(node:21997) ExperimentalWarning: `--experimental-loader` may be removed in th
e future; instead use `register()`:
--import 'data:text/javascript,import { register } from "node:module"; import
{ pathToFileURL } from "node:url"; register("extensionless", pathToFileURL("./
"));'
(Use `node --trace-warnings ...` to show where the warning was created)
yarn run v1.22.18
$ /Users/jeongjeongsu/cursor/game/course/apps/web/node_modules/.bin/pino-prett
y --singleLine
/Users/jeongjeongsu/cursor/game/course/node_modules/.pnpm/pino-pretty@13.1.1/n
ode_modules/pino-pretty/bin.js:14
const { default: stripJsonComments } = require('strip-json-comments')
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/jeongjeongsu/cursor/gam
e/course/node_modules/.pnpm/strip-json-comments@5.0.3/node_modules/strip-json-
comments/index.js from /Users/jeongjeongsu/cursor/game/course/node_modules/.pn
pm/pino-pretty@13.1.1/node_modules/pino-pretty/bin.js not supported.
Instead change the require of index.js in /Users/jeongjeongsu/cursor/game/cour
se/node_modules/.pnpm/pino-pretty@13.1.1/node_modules/pino-pretty/bin.js to a
dynamic import() which is available in all CommonJS modules.
at Object.<anonymous> (/Users/jeongjeongsu/cursor/game/course/node_modules
/.pnpm/pino-pretty@13.1.1/node_modules/pino-pretty/bin.js:14:40) {
code: 'ERR_REQUIRE_ESM'
}
Node.js v20.11.0
터미널의 문구를 보면 pino-pretty 파일에서 const { default: stripJsonComments } = require('strip-json-comments')에서 require() of ES Module 라는 문구를 보면 strip-json-comments이 문제일거라는 추측해볼 수 있었다.
이전에 발생하지 않던 오류가 왜 발생했는지 생각해보니, 신규 프로젝트를 진행하면서 pino-prettey 최신 버전을 설치와 yarn에서 pnpm 변경하였는데 이 부분에 문제가 있지 않을까 생각하고 원인을 찾아보기로 했다.
요즘 오류가 발생하면 구글링보다는 gpt를 통해 원인을 찾아보는데, 라이브러리의 최신 버전 사용한 경우 gpt 등과 같은 챗봇에서는 과거 버전의 해결책을 제안해주는 경우가 많아 직접 찾는것보다 더 오래 걸렸던적이 많았다.
그런데, 이번 원인이 라이브러리의 최신 버전의 문제일 수도 있어서 github에서 찾아보기로 했다.
나는 바로 문제가 있었보이는 pino-prettey github repo에서 이슈 탭으로가 단순하게 ERR_REQUIRE_ESM만 검색을 해보았다.
아니나 다를까 내가 겪었던 이슈가 바로 나왔다.


원인은 등록자의 이슈 내용을 쉽게 찾을 수 있었는데,
13.0에서 v13.1 로 버전업 내용중 #600-chore: upgrade strip-json-comments 에서 strip-json-comments 의존성 버전이 ^3.1.1 에서 ^5.0.2 변경되면서 발생하게 되었다는 것을 알 수 있었다.
왜 의존성 버전을 최신 버전으로 변경하였는지 PR 내용에 없었는데 Merge되었다는게 조금 의아하긴 했다.
strip-json-comments 버전이 변경되면서 발생한 것은 알겠는데 정확히 어떤 버전부터 어떤 부분이 변경되어 발생하는지가 궁금하여 패치 노트를 찾아봤고, sctrip-json-comments 4.0.0 버전부터 pure ESM으로 변경 되었다는 것을 알게 되었다.

pure ESM을 변경되었는데 pino-pretty에서 여전히 require 구문으로 사용하여 발생한 문제였다.
나에 노드 환경은 v20.11.0 버전이였다. 이 버전에서는 ESM 모듈을 require() 사용하면 require() of ES Module 이라는 오류가 발생하는게 당연하였다. 해결 방법은 단순하게 import 구문으로 바꾸거나, 코드 변경없이 실행 옵션에 --experimental-require-module 주면 해결이 가능하다.
그런데 strip-json-comments 버전업 과정에서 어떻게 이런 과정없이 해결할 수 있었을까?
어떻게 해결했을지 궁금하던 와중에 github 댓글 중에서 그 근거를 찾게 되었다.

v20.19.0 버전업되면서 해당 옵션이 기본으로 변경되어 더 이상 require(ESM) 문제가 발생하지 않았던 것이다.

그래서 환경에따라 발생할 수도 발생하지 않았을 수도 있었던 문제였기에 테스트를 안해본게 아니라 노드 환경이 달라 발생하지 않았던 것이다.
사실 문제 해결하는 방법만 보면 node 버전만 바꾸면 되기 때문에 간단해 보였다.
그런데 원인을 파고들다보니 개발 환경별로 발생할 수 있는 문제가 정말 많을 수 있다는 것을 알게되었다. 왜 .nvmrc 통해 노드버전을 고정시켜야 하는지 패키지 dependency를 고정시켜서 사용해야하는지 조금은 이해하게 되었다.