ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • NodeJS - 모듈(import, export default)
    개발언어/Node.js 2023. 2. 20. 11:52

    ECMAScript모듈

    ES모듈은 공식적인 자바스크립트 모듈형식이다. 노드에서 아직까지는 CommonJS모듈을 많이 쓰긴 하지만, ES모듈이 표준으로 정해지면서 점점 ES모듈을 사용하는 비중이 늘어나고 있습니다. 브라우저에서도 ES모듈을 사용할 수 있어 브라우저와 노드 모두에 같은 모듈형시을 사용할 수 있다는 것이 장점이다.

     

    CommonJS모듈은 공식 모듈이 아니라 표준 묘듈에 가까웠다. 사실 표준 모듈이라고 단언하기도 어려운 점이 JavaScrip자체이 표준이 없었기 때문에 노드생태계 에서는 CommonJS라는 자체적인 표준을 정해서 사용하고 있었던 것이다.

     

    하지만 브라우저 쪽에서 먼저 ES 모듈이 표준모듈로 정해지면서 노드에서도 ES모듈을 많이 사용하는 추세이다. 또한 장기적인 관점에서 모면 CommonJS 모듈이 ES모듈로 전환이 될 것이다.

     

     

    ES모듈을 배울때는 기본적으로 1:1 대응을 시키면 좋다.

     

    var.mjs

    export const odd = 'MJS 홀수입니다.';
    export const even = 'MJS 짝수입니다.';

    상수를 선언하면서 앞에 바로 export를 붙여서 내보낼 수 있다.

     

    func.mjs

    import { odd, evevn } from "./var.mjs";
    
    function checkOddOrEven(num) {
      if (num % 2) {
        // 홀수이면
        return odd;
      } else {
        return even;
      }
    }
    
    export default checkOddOrEven;

    export default는 module.exports와 동일하다고 생각하면 된다.

     

    index.mjs

    import { odd, even } from "./var.mjs";
    import checkNumber from "./func.mjs";
    
    function checkStringOddEven(str) {
      if (str.length % 2) {
        // 홀수이면
        return odd;
      } else {
        return even;
      }
    }
    
    console.log(checkNumber(10));
    console.log(checkStringOddEven("hello"));

    module.exports로 exports한 것들은 require()로 불러서 const 변수에 담을때 변수명이 꼭 똑같지 않아도 되고, ES모듈도 마찬가지 이다. import시 불러온 이름은 다르지만 func.mjs에서 export default한 함수를 가르키는것이다. 이것을 default export라고 부른다.

     

    반면 import { odd, even }의 경우는 export한 이름과 동일한 이름으로 import 해야되며 이름 named export라고 부른다.

     

    실행

    node index.mjs

    실행할 시에도 그냥 node index로 명령어를 사용할 경우 node index.js를 찾으므로 node index.mjs 라고 파일 확장자를 명시해주는 것이 좋다.

     

     

    CommonJS와 ES모듈의 차이점

    CommonJS와는 다른 부분이 CommonJS에서 require()는 함수이다. 그리고 module, exports 이런것 들은 객체이다. 그렇기 때문에 잘못사용하면 참조가 끊어지거나 module.exports가 덮어 씌어질 수 있다.

     

    반면에 ES모듈의 import나 export의 경우 고유한 문법 즉 예약어이다.

     

    파일도 js대신 mjs 확장자로 변경되었다. js 확장자에서 import를 사용하면 SyntacError:Cannot use import statement outside s module 에러가 발생한다. mjs 확장자 대신 js확장자를 사용하면서 ES모듈을 사용하려면 package.json에 type:'module'속성을 넣어주어야 한다.

     

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

     

    차이점 CommonJS 모듈 EXMAScript모듈
    문법 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
    확장자 생략 가능 불가능
    다이나믹 임포트   불가능
    인덱스(index)생략 가능(require('./folder')) 불가능(import './folder/index.mjs')
    top level await  불가능  가능(최상위 한정)
    __filename,
    __dirname,
    require, module.exports,
    exports
      사용불가능(__filename 대신 import.meta.url 사용)
    서로 간 호출 가능

     

    다이나믹 임포트

    앞의 표에서 CommonJS 모듈과 ES모듈을 비교할 때, CommonJS 모듈에서는 다이나믹 임포트(dynamic import)(동적 불러오기)가 되는데 ES 모듈에서는 다이나믹 임포트를 할 수 없다고 명시하였다 . 다이나믹 임포트가 무것이고 ES 모듈에서는 대안으로 어떤 방식을 사용하는지 알아본다.

     

    dynamic.js

    const a = false;
    if (a) {
      require("./func");
    }
    console.log("성공");

    dynamic.js에서 require('./func')는 실행되지 않는다. if문이 false라서 실행되지 않기때문이다. 이렇게 조건 부로 모듈을 불러오는 것을 다이나믹 임포트라고 한다.

     

    dynamic.mjs

    const a = false;
    if (a) {
      import "./func.mjs";
    }
    console.log("성공");

    ES모듈에서 import는 반드시  파일에 최상단에 위치하고 있어야 하기 때문에 if문 안에서 imort하는 것이 불가능하다.

     

    dynamic.mjs

    const a = true;
    // if (a) {
    //   import "./func.mjs";
    // }
    // console.log("성공");
    if (a) {
      const m1 = await import("./func.mjs");
      console.log(m1);
      const m2 = await import("./var.mjs");
      console.log(m2);
    }

    import라는 함수를 사용해서 모듈을 동적으로 불러올 수 있다. import는 Promise를 반환하기 때문에 await나 then을 붙여야 한다. 또 한 위 코드에서는  async 함수를 사용하지 않아았는데, ES 모듈의 최상위 Scope에서는 async 함수 없이도 await할 수 있다. 

     

    결과값도 눈여겨볼 필요가 있다. export default의 경우 import할 때 도 default라는 속성 이름으로 import된다.  참고로 CommonJS 모듈에서 module.exports한 것도 default라는 이름으로 import된다.

     

    출처 -

     

    https://www.inflearn.com/course/%EB%85%B8%EB%93%9C-js-%EA%B5%90%EA%B3%BC%EC%84%9C/dashboard

     

    [개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지 - 인프런 | 강의

    노드가 무엇인지부터, 자바스크립트 최신 문법, 노드의 API, npm, 모듈 시스템, 데이터베이스, 테스팅 등을 배우고 5가지 실전 예제로 프로젝트를 만들어 나갑니다. 클라우드에 서비스를 배포해보

    www.inflearn.com

     

    댓글

Designed by Tistory.