프로그래밍/NodeJS

Node.js import, require 차이점은? ESM vs CommonJS 실전 예제

smartbay 2025. 6. 13. 07:59

Node.js import, require 차이점은? ESM vs CommonJS 실전 예제

Node.js 프로젝트를 하다 보면 import를 썼더니 오류가 나고, require를 쓰면 또 다른 문제가 생기는 경우가 많습니다.
Node.js에서 import와 require는 어떤 차이가 있고, 각각 언제 사용해야 할까요?
이 글에서는 CommonJS와 ES Modules(ECMAScript Modules)의 차이, 실제 사용 예제, 그리고 스마트베이 실무 경험 기반의 문제 해결 방법까지 함께 정리해드립니다.

 

1. Node.js에서 import와 require가 혼용되는 이유는?

const express = require('express'); // CommonJS

// 또는

import express from 'express'; // ES Modules

 

Node.js 공식 문서나 StackOverflow에서 두 문법이 섞여 있는 걸 자주 보게 됩니다.
왜 이렇게 혼용되는 걸까요? 그 이유는 Node.js가 두 가지 모듈 시스템을 모두 지원하기 때문입니다.

 

2. CommonJS와 ES Modules의 등장 배경

 

CommonJS: Node.js의 전통적인 모듈 시스템

Node.js 초창기에는 브라우저에서 사용되던 ES6 모듈 시스템이 존재하지 않았습니다.
그래서 자체적으로 만든 모듈 시스템이 바로 CommonJS입니다.


- 모듈 가져오기: require('모듈명')
- 모듈 내보내기: module.exports = ...

 

ES Modules: 브라우저와의 통합을 위한 새 표준

ES6(ES2015)에서 공식적으로 도입된 모듈 시스템이며, Node.js도 점차 이를 채택하게 됩니다.


- 모듈 가져오기: import ... from '모듈명'
- 모듈 내보내기: export default, export { ... }

브라우저와 Node.js를 모두 아우르는 통합된 모듈 방식이 필요해졌고, ES Modules는 이를 해결하기 위해 등장했습니다.

 

3. CommonJS vs ES Modules 차이점

항목 CommonJS (CJS) ES Modules (ESM)
구문 require() / module.exports import / export
실행 방식 동기(Synchronous) 비동기(Asynchronous)
기본 확장자 .js, .cjs .mjs, 또는 "type": "module"
__dirname 사용 지원됨 기본 미지원
동적 로딩 가능 import() 필요

 

요약: CommonJS는 동기식 실행, ES Modules는 비동기식 처리와 top-level await 사용 가능

 

4. 실전 예제로 이해하는 사용법

CommonJS 방식

// file: server.cjs
const http = require('http');

http.createServer((req, res) => {
  res.end('Hello from CommonJS!');
}).listen(3000);

ES Modules 방식

// file: server.mjs
import http from 'http';

const server = http.createServer((req, res) => {
  res.end('Hello from ES Modules!');
});

server.listen(3000);

.mjs 확장자 또는 package.json"type": "module" 설정이 필요합니다.

 

5. 실무에서 자주 발생하는 오류 및 해결 방법

 

오류 1: SyntaxError: Cannot use import statement outside a module

원인: .js 파일에서 import를 사용했지만, type: "module"이 설정되지 않은 경우

// package.json
{
  "type": "module"
}

 

오류 2: require is not defined

 

원인: ES Modules 환경에서는 require가 기본으로 제공되지 않음

import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const fs = require('fs');

 

실전 Q&A: StackOverflow 예시

 

Q. 기존 CommonJS 프로젝트를 ES Modules로 마이그레이션 중인데, __dirname이 안 돼요!

A. ES Modules에서는 __dirname이 제공되지 않기 때문에, 아래와 같이 구현해야 합니다:

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

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

 

스마트베이에서도 기존 CommonJS 기반 툴을 ESM으로 전환하는 과정에서 __dirname 문제를 겪었고, 위 방식으로 안정적으로 해결했습니다.

 

6. 정리 및 추천 가이드라인

 

  • 새 프로젝트라면 ES Modules 권장
  • 기존 CommonJS 프로젝트는 혼합 사용 최소화
  • 외부 라이브러리와의 호환성 주의
  • .cjs / .mjs 확장자 구분 필요

 

이 내용은 스마트베이 내부 코드베이스 개선 과정에서 얻은 실무 인사이트를 기반으로 작성되었습니다.
실제 운영 중인 Node.js 자동화 서비스에서 발생한 오류를 해결하며 축적한 경험을 정리한 것이므로, 유사한 상황에서도 유용하게 적용될 수 있습니다.

 

마무리: import와 require, 이제는 구분해서 써야 합니다

 

Node.js는 이제 두 개의 모듈 시스템을 공식 지원합니다.
중요한 건 혼합 사용은 최소화하고, 프로젝트 성격에 맞게 일관되게 사용하는 것입니다.
에러가 나더라도 당황하지 말고, 오늘 설명드린 방식으로 해결해보세요!

 

함께 읽으면 좋은 글

 


스마트베이 | IT 자동화 혁신 파트너
비즈니스 효율을 높이는 스마트한 IT 솔루션을 제공합니다.

웹사이트 : www.esmartbay.co.kr
E-mail : smartbay.svc@gmail.com
카카오톡 : 바로 상담하기