CJS는 CommonJS 로 Node.js에서 모듈 시스템으로 사용된다.
동기적으로 모듈을 불러오며, module.exports
와 require
를 사용한다.
ServerJS 라는 이름에서 시작된 만큼 서버사이드를 목적으로 하고 있다.
require
는 어디에서든 호출 가능하여 유연한 모듈 로드를 지원한다.
ESM 은 ES Modules 로 자바스크립트가 ES6 부터 자체적으로 모듈을 지원하면서 추가되었다.
비동기적으로 모듈을 불러오며, export
와 import
를 사용한다.
표준 JS 모듈로 기획되었고, 최신 브라우저 대부분이 지원한다.
CJS를 로드할 수 있다.
CJS와 다르게 트리쉐이킹 이 가능하다.
URL을 통한 모듈 로드를 지원한다.
CJS : CommonJS, MJS : ESModule
노드는 기본적으로 cjs 환경을 지원한다.
노드에서 cjs로 실행하는 경우는 다음과 같다.
.cjs
확장자인 경우.js
확장자와 package.json
의 type
이 commonjs
이거나 명시되지 않은 경우노드에서 mjs로 실행되는 경우는 다음과 같다.
.mjs
확장자인 경우.js
확장자와 package.json
의 type
이 module
인 경우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의 코드는 실행하기 전에 모듈 래퍼에 의해 아래 함수로 래핑 된다.
(function(exports, require, module, __filename, __dirname) {
// module code...
});
__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