[JavaScript] .mjs vs .cjs

Joowon Jang·2024년 7월 31일

JavaScript

목록 보기
9/17

esLint, Vite 등의 개발 도구를 사용해 본 사람이라면 확장자가 .mjs, .cjs인 파일을 본 적이 있을 것이다.
둘 다 JavaScript 코드로 되어있는데, 어떤 차이가 있는 것일까?

mjs, cjs 파일의 차이

우선 두 파일 확장자가 무엇을 뜻하는지 알 필요가 있다.

  • mjs : Module JS (ECMAScript Module)
  • cjs : Common JS (Common JS Module)

두 파일은 JavaScript 모듈을 불러올 때 어떤 방식을 사용하는지의 차이가 있다.

아래의 두 파일을 비교해보자.

Module JS

// server.mjs
import liveServer from 'live-server';

const params = {
  host: 'localhost',
  port: 3000,
  root: '.',
  open: false,
  mount: [['/', './public']],
};

liveServer.start(params);

Common JS

// server.cjs
const liveServer = require('live-server');

const params = {
  host: 'localhost',
  port: 3000,
  root: '.',
  open: false,
  mount: [['/', './public']],
};

liveServer.start(params);

두 파일은 모두 개발 도구인 live-server를 사용할 때, 개발 서버를 실행할 옵션을 설정해 둔 파일인데, 맨 윗줄을 제외하고는 같은 코드이다.

package.json 파일에 live-server가 devDependencies(개발 종속성 패키지)에 추가되어 있고, 설치된 live-server 패키지에서 liveServer라는 모듈을 불러오는 것이다.

package.json 설정

.mjs, .cjs가 아닌 .js 확장자를 사용하면, package.json 파일에 아래와 같이 type 속성에 따라 사용할 방식을 지정할 수 있다.

  • "type": "module"로 설정하면 해당 프로젝트의 모든 .js 파일이 ECMAScript Module 파일로 취급되어 .mjs의 형식만 사용할 수 있다.
  • "type": "commonjs"로 설정하거나 type 속성을 생략하면 해당 프로젝트의 모든 .js 파일이 CommonJS Module 파일로 취급되어 .cjs의 형식만 사용할 수 있다.

.cjs와 .mjs 두 가지 방식으로 나뉜 이유 (배경)

"한 가지로 통일하면 될텐데 왜 귀찮게 두 가지 방식으로 나눈 것일까?" 의문이 생길 수 있다.

배경을 요약하면 다음과 같다.

  1. JavaScript는 초기에 대부분의 스크립트가 독립적인 작업을 수행하였고, 큰 스크립트가 필요하지 않았다.

  2. 몇 년 뒤, JavaScript는 많은 브라우저에서 실행되고 있는 완전한 애플리케이션을 실행할 수 있을 뿐 아니라, 다른 컨텍스트에서 (예를들면 Node.js) JavaScript를 사용할 수 있게 되었다.

  3. JavaScript 파일을 필요에 따라 가져올 수 있는, 별도의 모듈로 분할할 필요성이 생겼고, 그런 기능을 제공하는 많은 라이브러리와 프레임워크가 생겨났다.

  4. RequireJS같은 CommonJSAMD 기반의 ModuleJS가 가장 많이 사용되었고, JavaScript 표준으로 ModuleJS 방식을 사용하게 되었다.

  5. 하지만, 이미 CommonJS 방식을 많은 곳에서 사용하고 있었기 때문에, 호환성 유지 차원에서 사용 가능하도록 남겨두었다.

참고 (MDN 문서)
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Modules#a_background_on_modules


요약

ECMAScript 모듈(ESM):

  • 공식 표준으로, ES6(ECMAScript 2015)부터 도입되었다.
  • importexport 문법을 사용한다.
  • 브라우저와 Node.js(버전 12 이상)에서 기본적으로 지원된다.

CommonJS 모듈:

  • 비표준이며, 역사적으로 Node.js에서 주로 사용되었다.
  • requiremodule.exports 문법을 사용한다.
  • Node.js 초기 버전부터 사용되었으며, 여전히 많은 기존 Node.js 코드베이스에서 사용된다.
profile
깊이 공부하는 웹개발자

2개의 댓글

comment-user-thumbnail
2024년 11월 9일

AMD가 뭔가요 선생님

1개의 답글