두개 다 Javascript에서 모듈을 어떻게 관리할 지 표준화한 모델이다.
모듈은 함수나 변수를 다른 파일에서 사용하기 위해 만든다.
이런 모듈을 어떻게 관리하느냐에 따라 CommonJS와 ESM으로 나뉜다.
CommonJS에서는 Require과 Exports를 사용한다.
Node.js 환경에서 자주 사용하며 브라우저상에서는 표준으로 사용하지 않는다.
// singleObject.js
const singleObject = {
name: 'John Doe',
age: 30,
greet() {
console.log('Hello, my name is ' + this.name);
},
};
module.exports = singleObject;
// main.js
const singleObject = require('./singleObject');
singleObject.greet(); // Hello, my name is John Doe
보통 객체 내보내기를 많이 하기에 위와 같은 방식으로 exports를 한다.
// multipleObjects.js
const objectOne = {
name: 'John Doe',
age: 30,
};
const objectTwo = {
name: 'Jane Smith',
age: 25,
};
module.exports = {
objectOne,
objectTwo,
};
// main.js
const { objectOne, objectTwo } = require('./multipleObjects');
console.log(objectOne.name); // John Doe
console.log(objectTwo.name); // Jane Smith
ESM에서 Import, Export를 사용한다.
브라우저상에서 표준으로 사용되며, node.js에서 사용하고 싶다면 v.12이상에서 .mjs 확장자명으로 사용해야한다.
// singleObject.mjs
const singleObject = {
name: 'John Doe',
age: 30,
greet() {
console.log('Hello, my name is ' + this.name);
},
};
export default singleObject;
// main.mjs
import singleObject from './singleObject.mjs';
singleObject.greet(); // Hello, my name is John Doe
// multipleObjects.mjs
const objectOne = {
name: 'John Doe',
age: 30,
};
const objectTwo = {
name: 'Jane Smith',
age: 25,
};
export { objectOne, objectTwo };
// main.mjs
import { objectOne, objectTwo } from './multipleObjects.mjs';
console.log(objectOne.name); // John Doe
console.log(objectTwo.name); // Jane Smith
두 가지 방식의 Require, Import의 시점의 차이가 있다.
require는 호출되는 시점에 모듈을 동적으로 로드한다.
즉, 코드 실행 중 require가 호출되면 해당 모듈을 즉시 로드하고 실행한다.
런타임 때 즉각적으로 결정되는 것이다.
import는 파일의 최상위 레벨에서 선언되며, 파일 로드와 평가 시점에 모듈을 정적으로 로드한다.
ESM은 모듈을 미리 로드하고, 의존성 그래프를 형성하여 코드 실행 전에 모든 모듈을 준비한다.
컴파일 타임 때 최초에 정적으로 결정되는 것이다.
즉, ESM의 방식은 최초에 정적으로 결정되기 때문에 중복된 모듈 선언 같은 것을 미리 제거할 수 있어 최적화가 CommonJS보다 좋은 부분이 있을 수 있다.(트리 쉐이킹이라고 한다.)