ABOUT ME

Today
Yesterday
Total
  • [JS] .cjs, .mjs 차이가 무엇인가요?
    카테고리 없음 2024. 6. 11. 10:41
    728x90

    [JS] .cjs, .mjs 차이가 무엇인가요?

     

     

    프로젝트를 진행하다가 이런 확장자의 파일을 볼 수 있었을 것이다. .mjs.cjs 말이다. 그냥 js면 js지 mjs랑 cjs는 무엇인가? 오늘은 이 의문에 대한 답을 찾아볼 것이다.

     

    사실 이 문제는 모듈에 대해서 알아볼 필요가 있다.

     

    module

    자바스크립트는 초기에는 큰 파일을 필요로 하지 않았다. 자바스크립트의 역할은 웹 사이트에서 약간의 상호작용을 도와주는 정도였다. 하지만 웹의 규모가 커짐에 따라 자바스크립트의 양은 급속도로 늘어났다. 심지어 자바스크립트가 영향을 주는 범위는 브라우저를 벗어나 nodejs 등으로 확산되었다. 때문에 자바스크립트 파일을 필요에 따라 불러와 사용할 수 있는 니즈가 있었고, 현재는 모듈 기능을 사용하게 해주는 많은 프레임워크가 존재한다.

     

    최신 브라우저는 기본적으로 모듈 기능을 제공해준다고 한다.

     

    CommonJS, ES Modules

    일반적으로 자바스크립트에서 모듈을 내보낼 경우 두 가지 방식을 선택할 수 있다.

     

    그중 하나가 CommonJS, 다른 하나는 ES Modules이다.

     

    CommonJS는 모듈을 내보낼 경우 module.exports를 사용하고, 모듈을 불러올 경우 require()를 사용한다.

    ES Modules는 모듈을 내보낼 경우 export를 사용하고, 모듈을 불러올 경우 import를 사용한다.

     

    // CommonJS
    const test = require('./test.js');
    
    module.exports = example;
    
    // ES Modules
    import test from './test.js';
    
    export example;

     

    이 두 방식은 같은 기능을 한다. 그렇지만 같지만은 않다.

     

    CommonJS

    일반적으로 자바스크립트 모듈이 이용되기 전, node.js에서는 이미 모듈처럼 자바스크립트를 사용할 수 있는 능력을 갖고 있었다. 이 CJS 방식이 바로 오래전부터 node.js에서 모듈 시스템을 표준화하기 위해 이용되던 방식이다.

     

    require()로 모듈을 가져오는 CJS는 즉시 스크립트를 실행하는 구조를 갖고 있다. 동기적으로 모듈을 로드한다는 것이다. node.js 환경에서는 딱히 문제가 되지 않지만, 브라우저에서는 동기적으로 모듈을 로드하는 특성상 문제가 생길 수 있다.

     

    ES Modules

    node.js에서는 CJS가 표준으로 사용되었지만, 일반적인 자바스크립트에서는 아니다. ES6에서 도입된 MJS는 자바스크립트 언어 자체에서 공식적으로 모듈 시스템을 지원하기 위해 만들어졌다.

     

    import를 사용하여 모듈을 가져오는 MJS는 비동기적으로 모듈을 로드하기 때문에 브라우저에서 실행되는 특성을 띈 자바스크립트에서 성능적인 이점을 가져올 수 있다. 최신 브라우저 및 v12 이상의 node.js에서도 MJS를 지원한다.

     

     

    두 시스템을 정리하자면,

    CJS는 node.js의 표준 모듈 시스템이고, 동기적인 모듈 로딩 때문에 성능적인 이슈가 있을 수 있다. 하지만, 기존 Node.js 모듈과의 호환성은 결코 무시할 수 없다.

    MJS는 ECMAScript 표준이며, 성능적인 이점이 있고, 좀 더 현대적인 방식으로 모듈 시스템을 사용할 수 있다.

     

    NextJS 사용 시

    nextjs는 클라이언트, 서버 모두 운용 가능한 프레임워크이다. 따라서 모듈 시스템을 사용할 때 고려해야 할 부분이 존재한다.

     

    nextjs는 기본적으로 node.js 기반에서 SSR 기능이 동작하기 때문에 CJS를 지원한다. 기존 많은 node.js 모듈이 CJS 기반으로 작성되어 있기 때문에, 이러한 모듈들을 쉽게 사용할 수 있다.

     

    nextjs는 최신 자바스크립트 표준을 지원하기 때문에 MJS 사용 또한 가능하다. MJS는 트리쉐이킹도 지원하기 때문에 번들 용량 측면에서의 이점도 가져올 수 있다.

     

    nextjs에서는 next.config.js 파일을 이용하여 설정을 할 수 있다. 기존 next.js에서는 CJS로 이 파일이 작성되었다.

    /** @type {import('next').NextConfig} */
    const nextConfig = {};
    
    module.exports = nextConfig;

     

    하지만 최신 버전의 Create Next App을 사용하면 기본적으로 MJS 형식으로 next.config.js 파일이 작성된 것을 확인할 수 있었다.

    /** @type {import('next').NextConfig} */
    const nextConfig = {};
    
    export default nextConfig;

     

    nextjs에서는 CJS와 MJS를 하이브리드로 사용할 수 있는데, 이를 직접 구성하기 위해서는 package.json에서 타입을 설정하면 된다. 이렇게 설정한다면 node.js가 프로젝트에서 모듈을 해석하는 방식을 구성하게 된다. type 설정은 node.js 런타임 동작에 영향을 미치며, webpack 설정과는 별개로 동작한다.

     

    빌드타임에 파일 형식에 대한 처리 방식을 설정하기 위해서는 webpack 설정을 따로 해주어야 한다.

    module.exports = {
      webpack(config) {
        config.module.rules.push({
          test: /\.mjs$/,
          type: 'javascript/auto',
        });
    
        return config;
      },
    };

    이 설정으로 webpack이 파일을 자동으로 적절하게 처리하고, mjs 파일로 인식하게 한다. 이 방식은 빌드 과정에 직접적으로 영향을 미치며, nextjs 어플리케이션이 빌드될 때 mjs 파일을 명시적으로 처리할 수 있다.

    728x90
Designed by Frorong.