[TIL] 자바스크립트 - script 태그와 모듈

앗뇽… 넘나 오랜만인 TIL 포스팅.. 앞으로 자주 써줄게

vanillaJS를 사용해서 코딩을 하다가, import, export를 사용해서 html에서 바로 실행시키려니, 에러가 났다.

Screen Shot 2022-02-27 at 4 34 20 PM

vanillaJS로 뭔가를 코딩해본 경험이 거의 없어서..(심각)

이번에 vanillaJS로 개발을 하다보니 비록 간단한 거였는데도.. 많이 헤매서 너무 자괴감을 많이 느꼈다.

쨌든 위 에러는 내가 전에 한창 자바스크립트를 팔 때, (거의 2년전..?) 분명 공부했지만 다 잊어버린 그것이어따..

html에서 script 태그를 사용해서 자바스크립트 파일을 실행시키면, 원래는 해당 script의 스코프는 window지만, 이는 var와 같은 개발자가 의도치않은 오류를 일으킬 가능성이 있다.

그래서 let, const와 같이 모듈시스템이라는 것도 es2015+ 문법으로 추가가 되었는데,(그 전에는 AMD, CommonJS 등등으로 모듈시스템을 사용)

html5에서도 type이라는 props를 받을 수 있게 업데이트되면서 자바스크립트의 모듈시스템이라는 것을 반영할 수 있게 되었다.

모듈

모듈이라는 것은, 자신만의 스코프가 있는 것이다. 위에서도 말했다시피, script 태그에서 type=”module”을 작성해주지 않으면 그 script의 스코프는 window가 된다.

그렇다면 기본적인 이런 기능 말고도, script에 type으로 module을 주게되면 일반 script와 차이점은 뭐가 있을까?

모듈의 기능

use strict 모드로 실행된다.

모듈만의 스코프가 있다.

window를 사용해야하면 window.어쩌구로 사용

모듈로 선언된 스크립트가 여러번 다른 곳에 실행되더라도, 딱 한번만 실행된다.

모듈 내에서도 다른 모듈을 불러올 수 있다. 그런 와중에 같은 모듈을 여기저기서 불러오게 될텐데, 그러면 여러번 실행되는 것 같지만 처음 딱 한번만 실행된다.

import.meta 객체가 있다.

this가 undefined이다.

script 태그에 type=”module”을 선언한 모듈은 this가 undefined이고, script 태그만 선언하면 window 객체이다.

브라우저에서 type=”module”을 했을 때 특징

지연 실행

모듈 스크립트는 항상 지연 실행된다. 즉, html 코드가 다 실행된 이후에 실행된다. 그래서 모듈 스크립트는 항상 완전한 html 문서를 볼 수 있다. 그래서, 문서 내 요소도 접근이 가능하다.

<script type="module">
  alert(typeof button); // 모듈 스크립트는 지연 실행되기 때문에 페이지가 모두 로드되고 난 다음에 alert 함수가 실행되므로
  // 얼럿창에 object가 정상적으로 출력됩니다. 모듈 스크립트는 아래쪽의 button 요소를 '볼 수' 있죠.
</script>

하단의 일반 스크립트와 비교해 봅시다.

<script>
  alert(typeof button); // 일반 스크립트는 페이지가 완전히 구성되기 전이라도 바로 실행됩니다.
  // 버튼 요소가 페이지에 만들어지기 전에 접근하였기 때문에 undefined가 출력되는 것을 확인할 수 있습니다.
</script>

<button id="button">Button</button>

그래서 모듈 스크립트를 불러오는 동안의 시간이 좀 걸릴 수 있다. 이럴땐 로딩 인디케이터를 넣어주기!

  • 그래서 async 태그가 또 존재한다. html이 로딩될 때, 같이 스크립트도 로딩되었으면 한다면, async 태그를 넣어주자. (만약 async 태그가 있는 script가 실행되기 전에 모듈 script가 async 스크립트를 불러서 모듈 script가 먼저 실행되는 상황이라면, 모듈 스크립트가 다 로딩된 후 병렬적으로 처리된다.)

구식 브라우저는 type=”module”을 모름..

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

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

이런식으로 구식 브라우저와 최신 브라우저가 사용하는 script를 나누기~

실제 애플리케이션을 출시할 땐 성능 개선 등의 이점 때문에 웹팩과 같은 번들러를 사용한다는 점!

짧은 module 공부 끝! 역시 모던자스 자료가 보기 좋아…

Reference