본문 바로가기
Woowa Techcourse/Missions

Javascript 모듈(Module)

by mingule 2021. 3. 10.

모듈이란?

개발하는 웹의 크기가 커지면 언젠가 파일을 여러개로 분리해야하는데, 이때 분리된 파일 각각을 "Module"이라고 부른다.

모듈에 export, import를 적용하면 다른 모듈을 불러와 함수를 호출할 수 있게 해준다.

 

// hi.js
export function sayHi(user) {
  alert(`hello, ${user}!`)
}
// main.js
import { sayHi } from "./hi.js"

alert(sayHi('John')) //alert가 뜸

이렇게 모듈을 사용하려면, HTML에서 Script를 불러올 때에 <script type="module">과 같은 속성을 설정해 해당 스크립트가 모듈이라는 것을 브라우저가 알 수 있게 해줘야 한다. 이렇게 모듈을 사용하려면 local에서는 사용하기 힘들고, live-server등을 사용해 서버를 켜야한다.

 

모듈의 Scope

모듈은 자신만의 scope가 있다. 그래서 모듈에서 정의한 내부의 변수, 함수는 다른 스크립트에서 접근할 수 없다. 만약 모듈에서 외부로 공개하려면 export를 사용해 내보내야하고, 이런 모듈들을 가져와 사용하려면 import를 통해 가져와야한다.

 

모듈은 단 한번만 평가된다.

동일한 모듈이 여러 곳에서 사용되더라도 모듈은 처음 호출시 한번만 실행된다. import를 몇번씩 해도 최초 import만 발생한다.

 

모듈은 단 한번만 실행되고, 실행된 모듈은 필요한 곳에 공유된다.

// admin.js
export let admin = {
  name: "John"
};
// 1.js
import {admin} from './admin.js';
admin.name = "Pete";
// 2.js
import {admin} from './admin.js';
alert(admin.name); // Pete

 

1.js에서 변경한 내용을 2.js에서도 확인할 수 있다는 것을 알 수 있다!

 

최상위 레벨의 this는 undefined

모듈이 아닌 스크립트의 this는 전역 객체인데, 모듈은 undefined이다. 

<script>
  alert(this); // window
</script>

<script type="module">
  alert(this); // undefined
</script>

 

type="module"와 일반 스크립트의 다른 점

항상 지연 실행된다.

모듈 스크립트는 HTML 문서가 완전히 준비될 때까지 대기 상태에 있다가 HTML이 다 만들어진 후에 실행된다. 

그래서 모듈 스크립트는 항상 완전한 HTML 페이지를 볼 수 있고, 문서 내 요소에도 접근할 수 있다.

그런데, 이렇게 모듈이 HTML이 모두 로딩된 후에 실행되기 때문에, 모듈 스크립트를 불러오는 동안 Loading Indicator이나 투명 오버레이 등을 넣어주어 사용자의 혼란을 예방해주어야한다.

 

인라인 스크립트의 비동기 처리

일반 스크립트에서 async 속성은 외부 스크립트를 불러올 때에만 유효한데, 모듈에서는 인라인 스크립트에도 적용할 수 있다.

광고나 카운터 등과 같이 어디에도 종속되지 않는 기능을 구현할 때에 사용할 수 있다.

<!-- 필요한 모듈(analytics.js)의 로드가 끝나면 -->
<!-- 문서나 다른 <script>가 로드되길 기다리지 않고 바로 실행됩니다.-->
<script async type="module">
  import {counter} from './analytics.js';

  counter.count();
</script>

구식 브라우저 대응

구식 브라우저는 type="module"을 해석하지 못해서 만약 저게 붙어있으면 무시하고 넘어가는데.. 그래서 nomodule을 붙여주면 대신 그걸 실행한다. 아래 예시에 잘 나와있다.

<script type="module">
  alert("모던 브라우저를 사용하고 계시군요.");
</script>

<script nomodule>
  alert("type=module을 해석할 수 있는 브라우저는 nomodule 타입의 스크립트는 넘어갑니다. 따라서 이 alert 문은 실행되지 않습니다.")
  alert("오래된 브라우저를 사용하고 있다면, type=module이 붙은 스크립트는 무시합니다. 대신 이 alert 문이 실행됩니다.");
</script>

 

참고 링크

ko.javascript.info/modules-intro

 

모듈 소개

 

ko.javascript.info

실제 웹을 출시할 때에는 성능 개선 등의 이점 때문에 웹팩과 같은 번들러를 사용한다.

댓글