Thief of Wealth

모듈이란? feat. 일반스코프와 모듈의차이

모듈은 대개 클래스 하나, 또는 특정한 목적을 가진 여러개의 함수로 구성된 라이브러리로 구성된다.

자바스크립트가 만들어진지 얼마 안되었을 때에는 자바스크립트로 만든 스크립트의 크기도 작고, 기능도 단순했기 때문에 자바스크립트는 긴 세월 동안 모듈 관련 표준 문법이 필요없었다.

그런데 스크립트의 크기가 점차 커지고, 기능도 복잡해지자 자바스크립트 커뮤니티는 특별한 라이브러리를 만들어서 필요한 모듈을 언제든지 불러올 수 있게 해준다거나 코드를 모듈 단위로 구성해주는 방법을 만드는 등 다양한 시도를 하게된다.

  • AMD
    가장 오래된 모듈 시스템중 하나로, require.js 라는 라이브러를 통해 처음 개발되었다.
  • CommonJS
    Node.js 서버를 위해 만들어진 모듈 시스템이다.
  • UMD
    AMD와 CommonJS와 같은 다양한 모듈 시스템을 함께 사용하기 위해 만들어졌다.

모듈은 그냥 파일 하나에 불과하고, 스크립트 하나는 모듈 하나이다.

모듈에 특수한 지시자 export, import 으로 모듈을 내보내고 가져올 수 있다.

브라우저에서는 특수한 키워드나 기능과 함께 사용되므로 <script type="module"> 과 같은 속성을 설정해서 해당 스크립트가 모듈이라는 것을 브라우저가 알 수 있게 해야한다.

!주의!

모듈은 로컬 파일에서 동작하지 않고, http또는 https프로토콜을 사용해서만 동작한다.
즉, file://가 아닌 localhost같은 live server같은 것을 이용해서 동작시켜야 한다.

일반 스코프와 모듈의 차이

모듈은 항상 엄격모드로 실행된다. 즉 선언되지 않은 변수에 값을 할당하는 코드는 에러를 발생시킨다.

<script type="module">
  a = 5; //error
</script>

모듈은 자신만의 스코프를 가지고 있다.
브라우저 환경에서도 script type="module"하면 독립적인 스코프가 만들어진다.

<script type="module">
  // user는 해당 모듈 안에서만 접근 가능합니다.
  let user = "John";
</script>

<script type="module">
  alert(user); // Error: user is not defined
</script>

참고로, 브라우저 환경에서 window 레벨 전역변수가 필요하면 window객체를 명시적으로 사용하면된다.

script type="module" src="..." 는 defer를 붙인것과 똑같이 동작한다.

type="module"인데 src가 같으면 스크립트가 한번만 실행된다.

빌드툴 관점

브라우저 환경에서 모듈을 단독으로 사용하는 경우는 흔치않고, webpack이 번들링하여 적용합니다.

  1. HTML의 script type='module'에 넣을 진입점 모듈을 선택 index.js
  2. 진입점 모듈에 의존하는 모듈들을 가지고와서 의존성 트리를 그림
  3. 모듈을 한데 모아서 번들링
  4. 이때 트리셰이킹 등등의 변형 및 최적화 수행

번들링 과정이 끝나면 import, export가 사라져서 type="module"이 더이상 필요없게됨

즉, 웹팩이 번들링되면

<script src="bundle.js"></script> 만 써도됨.

즉, 모듈이 일반 스크립트가 됨!

import는 무조건 최상단에서 쓰여야함!
import()는 동적 import 문법으로 상관없고, type="module"가 아닌 일반스크립트에서도 사용가능!

참고

https://ko.javascript.info/modules-intro

profile on loading

Loading...