Node.js는 전통적으로 CommonJS 라는 자기네 방식의 독특한 모듈 시스템을 사용했습니다. require과 module.exports로 대표되는 방식이었죠. 하지만 브라우저에서는 import, export로 대표되는 모듈 시스템 을 채택했습니다. 자바스크립트 정식 스펙이기도 하고요. 타입스크립트도 자바스크립트를 따라가니까 import export를 채택했습니다.
Node.js도 이 흐름을 거스를 수는 없었습니다. 따라서 import, export를 도입했는데요.
과거에는 mjs라는 확장자를 썼어야 했습니다. app.js 대신에 app.mjs를 하는 식이죠. 그래야만 import, export를 인식했습니다. 이 때 export하는 파일이나 import 하는 파일 모두 mjs 확장자를 갖고 있어야 합니다. 참고로 타입스크립트에서는 mts 확장자를 사용하고 있습니다.
하지만 이제는 package.json을 통해서도 설정할 수 있어서 확장자를 바꾸지 않아도 import, export를 쓸 수 있습니다.
package.json
{
...
type: "module",
...
}
이렇게 하면 해당 package.json이 있는 프로젝트에서는 모두 import와 export를 사용할 수 있게 됩니다. 반대로 이제부터는 CommonJS를 사용하려면 cjs 확장자를 명시적으로 사용해야 합니다.
import x from 'package';
export const hello = 'world';
export default function() {
return '이제 됩니다!';
}
브라우저와 노드에서 import, export를 지원함에 따라 점점 CommonJS도 과거의 유산이 되어갈 것 같다는 생각이 드네요. 참고로 노드 버전이 많이 올라감에 따라 --experimental-modules 를 붙여서 실행하던 방식은 사라졌다고 보시면 됩니다.
내 프로젝트에 사용하는 라이브러리에서 CommonJS와 ESM을 동시에 지원하는 경우도 있습니다. 그런 경우 각 모듈에 따라 어떤 파일을 불러오는지는 라이브러리 package.json의 exports 필드에 들어 있습니다. 해당 속성에 대한 설명은 여기 에 있습니다.