Node.js 22 릴리즈 - require()로 ESM 불러오기 지원

배경

회사 프로젝트는 여전히 CommonJS 기반이다. package.json에 "type": "module"을 추가하지 않은 레거시 코드베이스다. 그런데 최근 설치하는 라이브러리들이 ESM only로 배포되는 경우가 늘어나면서 문제가 생겼다.

특히 chalk 5.x 업데이트 후 기존 require('chalk')가 동작하지 않아 4.x로 되돌린 적이 있다. 이런 식으로 의존성 버전을 고정하다 보니 보안 패치나 새 기능을 못 쓰는 상황이 반복됐다.

Node.js 22의 변화

4월 24일 릴리즈된 Node.js 22에서 --experimental-require-module 플래그가 추가됐다. 이제 require()로 ESM 모듈을 불러올 수 있다.

// 기존에는 에러 발생
const chalk = require('chalk');

// 이제는 플래그와 함께 실행 시 동작
// node --experimental-require-module index.js

물론 top-level await를 사용하는 모듈은 여전히 불가능하다. 동기적으로 로드할 수 없기 때문이다.

실험

간단한 테스트 코드를 작성했다.

// test.js
const chalk = require('chalk');
console.log(chalk.blue('Hello from ESM via require'));
node --experimental-require-module test.js
# 정상 출력됨

예상대로 작동했다. 하지만 프로덕션에 바로 적용하긴 어렵다. experimental 기능이고, CI/CD 파이프라인의 모든 node 실행 명령에 플래그를 추가해야 한다.

당장의 대응

  1. 새 프로젝트는 ESM으로 시작
  2. 기존 프로젝트는 점진적 마이그레이션 계획 수립
  3. Node.js 22가 LTS가 되는 10월까지 지켜보기

레거시 프로젝트의 경우 ts-node와 TypeScript의 esModuleInterop으로 어느 정도 우회했지만, 근본적인 해결은 아니다. 올해 안에 주요 프로젝트를 ESM으로 전환하는 작업을 시작해야 할 것 같다.