requireexports, module.exports가 각각 import, export, export default로 바뀌었습니다. 상당한 부분에서 차이가 있으므로 단순히 글자만 바꿔서는 제대로 동작하지 않을 수 있습니다. ES 모듈의 importexport defaultrequiremodule처럼 함수나 객체가 아니라 문법 그 자체입니다.

    파일도 js 대신 mjs 확장자로 변경되었습니다. js 확장자에서 import를 사용하면 SyntaxError: Cannot use import statement outside a module 에러가 발생합니다. mjs 확장자 대신 js 확장자를 사용하면서 ES 모듈을 사용하려면 5장에서 배울 package.json에 type: "module" 속성을 넣으면 됩니다.

    CommonJS 모듈과는 다르게 import 시 파일 경로에서 js, mjs 같은 확장자는 생략할 수 없습니다. 또한, 폴더 내부에서 index.js도 생략할 수 없습니다.

    표로 두 모듈 형식의 차이를 정리해봤습니다.

    ▼ 표 3-1 CommonJS 모듈과 ECMAScript 모듈의 차이

    차이점

    CommonJS 모듈

    ECMAScript 모듈

    문법

    require('./a');

    module.exports = A;

    const A = require('./a');

    exports.C = D;

    const E = F; exports.E = E;

    const { C, E } = require ('./b');

    import './a.mjs';

    export default A;

    import A from './a.mjs';

    export const C = D;

    const E = F; export { E };

    import { C, E } from './b.mjs';

    확장자

    js

    cjs

    js(package.json에 type: "module" 필요)

    mjs

    확장자 생략

    가능

    불가능

    다이내믹 임포트

    가능(3.3.3절 참고)

    불가능

    인덱스(index) 생략

    가능(require('./folder'))

    불가능(import './folder/index.mjs')

    top level await

    불가능

    가능

    __filename, __dirname, require, module.exports, exports

    사용 가능(3.3.4절 참고)

    사용 불가능(__filename 대신 import.meta.url 사용)

    서로 간 호출

    가능

    지금까지 CommonJS 모듈과 ES 모듈을 알아봤습니다. 서로 간에 잘 호환되지 않는 케이스가 많으므로 웬만하면 한 가지 형식만 사용하는 것을 권장합니다.

    신간 소식 구독하기
    뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.