SHIN STORYSHIN STORY
홈포스트C#TypeScriptNext.jsNode.js시리즈
</>SHIN STORY

sdf

탐색

  • 홈
  • 모든 포스트
  • 시리즈
  • 검색

카테고리

  • C#
  • TypeScript
  • Next.js
  • Node.js
  • 알고리즘
  • 개발 도구

© 2025 Shin Blog. All rights reserved.

GitHubRSS
목록으로
Node.js#JavaScript#Node.js

Node.js CJS vs ESM 모듈 시스템 완전 정리

SHIN

2026년 4월 29일1분 읽기0
📚

Node.js 실전 팁 20선

20편
  1. 3Node.js Stream으로 대용량 파일 처리하기
  2. 4Worker Threads로 CPU 집약 작업 처리하기
  3. 5cluster 모듈로 멀티코어 CPU 100% 활용하기
  4. 6child_process로 외부 명령 실행하기
  5. 7fs/promises로 파일 시스템 다루기
  6. 20Node.js Event Loop 완전 정복
  7. 20Node.js path 모듈 완전 정복
  8. 20환경 변수 관리 — .env, dotenv, 그리고 검증
  9. 20EventEmitter 패턴으로 느슨한 결합 구현하기
  10. 20Node.js crypto 모듈로 해싱과 암호화 구현하기
  11. 20Node.js 메모리 누수 찾고 수정하기
  12. 20Express 미들웨어 패턴과 에러 처리
  13. Node.js CJS vs ESM 모듈 시스템 완전 정리현재
  14. 20Node.js Buffer와 인코딩 완전 가이드
  15. 20PM2로 Node.js 프로세스 관리하기
  16. 20Node.js HTTP 서버 직접 구현하기
  17. 20Node.js 성능 프로파일링 실전 가이드
  18. 20Node.js npm 스크립트 완전 활용하기
  19. 20Node.js 보안 체크리스트 10가지
  20. 20Node.js 테스팅 전략 — 단위, 통합, E2E 테스트

Node.js CJS vs ESM 모듈 시스템 완전 정리

Node.js는 두 가지 모듈 시스템을 지원합니다. 각 시스템의 특징을 이해하고 올바르게 선택해야 합니다.

핵심 차이점

구분CommonJS (CJS)ES Modules (ESM)
문법require/module.exportsimport/export
로딩동기, 런타임정적, 컴파일 타임
확장자.js, .cjs.mjs, 또는 package.json type:module
__dirname기본 제공별도 구현 필요
Tree-shaking어려움가능
Top-level await불가가능

package.json 설정

CODE
{
  "type": "module",
  "main": "./dist/index.cjs",
  "module": "./dist/index.js",
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    }
  }
}

ESM에서 __dirname, __filename

CODE
// ESM에서는 __dirname, __filename이 없음
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';

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

const configPath = join(__dirname, '../config/app.json');

동적 import

CODE
// ESM에서 동적 로드 (CJS require와 비슷)
const module = await import('./plugin.js');

// 조건부 로드
async function loadConfig() {
  if (process.env.NODE_ENV === 'test') {
    return (await import('./config.test.js')).default;
  }
  return (await import('./config.js')).default;
}

CJS에서 ESM 가져오기

CODE
// CJS에서 ESM 패키지를 동기적으로 require할 수 없음
// ❌ const esm = require('pure-esm-package'); // 에러!

// ✅ 동적 import 사용
async function main() {
  const { default: chalk } = await import('chalk');
  console.log(chalk.green('Hello!'));
}

TypeScript에서 ESM 설정

CODE
// tsconfig.json
{
  "compilerOptions": {
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "target": "ES2022"
  }
}
CODE
// TypeScript ESM에서 반드시 확장자 포함
import { helper } from './utils/helper.js'; // .ts가 아닌 .js

권장 전략

  • 새 프로젝트: ESM 사용 ("type": "module")
  • 기존 CJS 프로젝트: 마이그레이션 비용 고려, 점진적 전환
  • 라이브러리: CJS + ESM 듀얼 패키지 (tsup, unbuild 활용)
CODE
# tsup으로 CJS + ESM 동시 빌드
tsup src/index.ts --format cjs,esm --dts
공유
S

SHIN

.NET 개발자입니다

GitHub
Express 미들웨어 패턴과 에러 처리

이전 포스트

Express 미들웨어 패턴과 에러 처리

다음 포스트

Node.js Buffer와 인코딩 완전 가이드

Node.js Buffer와 인코딩 완전 가이드

같은 카테고리 포스트

Node.js 테스팅 전략 — 단위, 통합, E2E 테스트

Node.js 테스팅 전략 — 단위, 통합, E2E 테스트

2026년 5월 6일· 2분
Node.js 보안 체크리스트 10가지

Node.js 보안 체크리스트 10가지

2026년 5월 5일· 2분
Node.js npm 스크립트 완전 활용하기

Node.js npm 스크립트 완전 활용하기

2026년 5월 4일· 1분

댓글