CJS, ESM

CJS, ESM

CJS

CJSCommonJS 로 Node.js에서 모듈 시스템으로 사용된다.

동기적으로 모듈을 불러오며, module.exportsrequire 를 사용한다.

ServerJS 라는 이름에서 시작된 만큼 서버사이드를 목적으로 하고 있다.

require 는 어디에서든 호출 가능하여 유연한 모듈 로드를 지원한다.

ESM

ESMES Modules 로 자바스크립트가 ES6 부터 자체적으로 모듈을 지원하면서 추가되었다.

비동기적으로 모듈을 불러오며, exportimport 를 사용한다.

표준 JS 모듈로 기획되었고, 최신 브라우저 대부분이 지원한다.

CJS를 로드할 수 있다.

CJS와 다르게 트리쉐이킹 이 가능하다.

URL을 통한 모듈 로드를 지원한다.

노드에서의 cjs, mjs

CJS : CommonJS, MJS : ESModule

노드는 기본적으로 cjs 환경을 지원한다.

노드에서 cjs로 실행하는 경우는 다음과 같다.

  • .cjs 확장자인 경우
  • .js 확장자와 package.jsontypecommonjs 이거나 명시되지 않은 경우

노드에서 mjs로 실행되는 경우는 다음과 같다.

  • .mjs 확장자인 경우
  • .js 확장자와 package.jsontypemodule 인 경우

ESM 에서 CJS 로드하기

CJS 에서 ESM 을 로드하는 것은 불가능 하지만, ESM 에서 CJS 는 로드할 수 있다.

// text.cjs
exports.hello = 'world'

위의 cjs 파일은 아래 처럼 사용할 수 있다.

import { hello } from './text.cjs'
// hello : 'world'

import text from './text.cjs'
// text : { hello: 'world' }

import * as textModule from './text.cjs'
// textModule : {default: {hello: 'world'}, hello: 'world'}

CJS의 모듈 래퍼

CJS의 코드는 실행하기 전에 모듈 래퍼에 의해 아래 함수로 래핑 된다.

(function(exports, require, module, __filename, __dirname) {
	// module code...
});

ESM 에서 __filename, __dirname 사용하기

위의 CJS 모듈 래퍼를 보면 __filename__dirname 이 있는 것을 알 수 있다.

ESM 은 CJS 모듈 래퍼로 감싸지지 않으므로, __filename__dirname 에 접근할 수 없다.

대신 import.meta.url 을 사용하여 가져올 수 있다.

// /Users/workspace/modules/index.mjs
import {fileURLToPath} from 'url'
import {dirname} from 'path'

/*
  import.meta.url = "file:///Users/workspace/modules/index.mjs"
*/
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(metaUrl)
참고

https://www.knowledgehut.com/blog/web-development/commonjs-vs-es-modules

https://nodejs.org/api/modules.html

https://nodejs.org/api/esm.html


Written by@[esllo]
plain developer

GitHubTwitterLinkedIn