[TIL] HTML 모듈 스크립트가 해결하는 문제

cheo·2021년 8월 6일
1

TIL

목록 보기
2/5

질문

  • Q1. HTML의 모듈 스크립트는 어떤 문제를 해결하는가?
  • Q2. 모듈 스크립트를 사용할 일이 많은가?

답변

TL;DR

  • HTML 모듈 스크립트는 일반 스크립트와 달리 전역 스코프 오염을 해결한다.
  • 모듈 스크립트 대신에 유사한 동작 원리를 가진 웹팩 같은 번들링 도구를 사용한다.

일반 스크립트 vs 모듈 스크립트

일반 스크립트를 사용하면 전역 스코프가 오염되지만 모듈 스크립트는 그것을 방지한다. 모듈 스크립트(<script type="module">)를 사용하면 일반 스크립트와 다른 특징을 가진다:

  1. 항상 엄격 모드(use strict)로 실행되므로 글로벌 스코프를 허용하지 않는다.
  2. 모듈 스코프 레벨을 사용하므로 모듈 간에 변수를 공유할 수 없다.
  3. 한 번만 평가되므로 동일한 스크립트를 여러 번 import해도 한 번만 실행된다.
  4. 지연 실행이 된다. 그래서 defer 옵션이 없어도 DOM 생성이 모두 완료된 이후에 스크립트가 실행된다.

모듈 스크립트 vs 웹팩

모듈 스크립트를 사용할 일이 많은가? 그렇지 않다. 왜냐하면 웹팩(webpack) 같은 도구로 번들링(bundling)한 스크립트를 한 번만 로딩하면 모두 해결되기 때문에. 그러나 모듈 스크립트의 동작 원리는 웹팩의 동작 원리와 유사하므로 알고 있는 것이 좋다.

어디에 써먹을까

Q. example.jsdiv#app을 참조하는 코드가 있다면 다음 HTML 파일은 에러가 발생한다. 왜 에러가 발생하며, 어떻게 해결할 수 있을까?

<body>
  <script src="example.js"></script>
  <div id="app"></div>
</body>

브라우저에서 HTML을 파싱(parsing)할 때 스크립트 태그를 만나면 파싱을 일시중단한다. 즉 div#app이라는 DOM을 파싱하기 전에 example.js를 로딩하게 된다. 그런데 이렇게 되면 내부적으로 div#app을 참조하는 example.js가 아직 파싱이 완료되지 않은 DOM을 참조하는 것이 되기 때문에 에러가 발생한다.

해결 방법은 DOM이 모두 완료된 이후에 스크립트를 불러오면 되므로 두 가지 방법이 있다:

  • defer 옵션을 사용한다: <script defer src="example.js">
  • 모듈 스크립트로 사용한다: <script type="module" src="example.js">

See also

0개의 댓글