javascript

모듈의 의미

노엠디엔 2023. 8. 23. 14:19

모듈이란

애플리케이션을 구성하는 개별적 요소로서 재상용 가능한 코드조각을 말한다!

모듈은 단지 파일 하나에 불과하며. 스크립트 하나는 모듈 하나이다.

일반적으로 모듈은 기능을 기준으로 파일 단위로 분리하며 

모듈은 자신만의 파일 스코프(모듈 스코프)를 가질 수 있어야 한다.

 

자신만의 파일 스코프를 갖기 때문에 모듈에 있는 객체는 기본적으로 바공개 상태며

캡슐화되어 다른 모듈에서 접근할 수 없다. 즉, 모듈은 개별적 존재로서 애플리케이션과 분리되어 존재한다.

캡슐화:객체의 속성(data fields)과 행위(메서드, methods)를 하나로 묶고,
실제 구현 내용 일부를 외부에 감추어 은닉한다.

 

애플리케이션과 분리되어 개별적으로 존재만 한다면 모듈은 재사용이 불가능하므로 존재의 의미가 없어지는데

공개가 필요한 부분을 한정하여 공개하는 할 때 사용하는 것이 export 키워드이다.

 

공개된 모듈은 다른 모듈에서 재사용할 수 있는데 이때 공개된 모듈의 자산을 사용하는 모듈을 모듈 사용자라 부른다.

모듈 사용자는 모듈이 공개한 자산 일부 또는 전체를 선택해 자신의 스코프 내로 불러들여 재사용할 수 있다

이때 사용하는 것이 import 키워드다.

 

자바스크립트는 script 태그를 사용하여 외부의 자바스크립트 파일을 로드할 수 있지만 
파일마다 독립적인 파일 스코프를 갖지 않는다고 한다?

 

자바스크립트는 파일을 여러 개로 분리해도 script 태그로 분리된 자바스크립트 파일들은

결국 하나의 자바스크립트 파일내에 있는 것처럼 동작하기 때문이다.

 자바스크립트 파일들은 모두 하나의 전역 상태를 공유하게 되는데 이러한 클라이언트 사이드,

브라우저 환경에 국한하지 않고 범용적으로 사용하려는 움직임이 생기면서 제안된 것이

CommonJS와 AMD(Asynchronous Module Definition)이라고 한다!

 

자바스크립트 런타임 환경인 Node.js는 모듈 시스템의 표준인 CommonJS를 채택했고

Node.js는 ECMAScript 표준 사양은 아니지만 모듈 시스템을 지원한다. 

결론은 Node.js 환경에서는 파일별로 독립적인 파일 스코프(모듈 스코프)를 갖는다고 한다!

 

CommonJS와 AMD 참고:

https://d2.naver.com/helloworld/12864

 

ES6 에서부터는 모듈 기능이 추가되어 script태그에 type= 'module' 어트리뷰트를 추가하면 
모듈로서 동작하며 ESM라는 파일확장자를 붙여주는 것을 권장한다고 함!

 

스크립트와 모듈의 차이

모듈은 항상 엄격 모드(use strict)로 실행됩니다. 선언되지 않은 변수에 값을 할당하는 등의 코드는 에러를 발생시킨다.

 

모듈 레벨 스코프

모듈은 자신만의 스코프가 있습니다. 따라서 모듈 내부에서 정의한 변수나 함수는 다른 스크립트에서 접근할 수 없습니다.

(접근하려면 import와 import 사용해 파일 내에서 접근 )

 

단 한 번만 평가됨

동일한 모듈이 여러 곳에서 사용되더라도 모듈은 최초 호출 시 단 한 번만 실행됩니다.
실행 후 결과는 이 모듈을 가져가려는 모든 모듈에 내보내 진다?

모듈은 단 한 번만 실행되고 실행된 모듈은 필요한 곳에 공유되므로 어느 한 모듈에서
test
객체를 수정하면 다른 모듈에서도 변경사항을 확인할 수 있습니다.

참고사항으로 모듈의 this를 호출하면 undefined가 호출된다고 함!

지연 실행

모듈 스크립트는 항상 지연 실행된다. 외부 스크립트,인라인 스크립트와 관계없이
마치 
defer 속성을 붙인 것처럼 실행된다고 한다.

https://ko.javascript.info/script-async-defer

 

defer, async 스크립트

 

ko.javascript.info

  • 외부 모듈 스크립트 <script type="module" src="...">를 다운로드할 때 브라우저의 HTML 처리가 멈추지 않습니다.
    브라우저는 외부 모듈 스크립트와 기타 리소스를 병렬적으로 불러옵니다.
  • 모듈 스크립트는 HTML 문서가 완전히 준비될 때까지 대기 상태에 있다가
    HTML 문서가 완전히 만들어진 이후에 실행됩니다..
  • 스크립트의 상대적 순서가 유지됩니다. 문서상 위쪽의 스크립트부터 차례로 실행됩니다.

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

모듈이 아닌 일반 스크립트에서 async 속성은 외부 스크립트를 불러올 때만 유효합니다. 
async 속성이 붙은 스크립트는 로딩이 끝나면 다른 스크립트나 HTML 문서가 처리되길 기다리지 않고 바로 실행됨!

모듈 스크립트에선 async 속성을 인라인 스크립트에도 적용할 수 있습니다.

아래 인라인 스크립트엔 async 속성이 붙었기 때문에 다른 스크립트나 HTML이 처리되길 기다리지 않고 바로 실행된다.

가져오기(./analytics.js) 작업이 끝나면 HTML 파싱이 끝나지 않았거나
다른 스크립트가 대기 상태에 있더라도 모듈이 바로 실행되며 이런 특징은 광고나 문서 레벨 이벤트 리스너,
카운터 같이 어디에도 종속되지 않는 기능을 구현할 때 유용하게 사용할 수 있다고 한다.

외부 스크립트

type="module"가 붙은 외부 모듈 스크립트엔 두 가지 큰 특징이 있는데.

  1. src 속성값이 동일한 외부 스크립트는 한 번만 실행된다.
  2.  
  3. <!-- my.js는 한 번만 로드 및 실행됩니다. -->
    <script type="module" src="my.js"></script>
    <script type="module" src="my.js"></script>
  4. 외부 사이트같이 다른 오리진에서 모듈 스크립트를 불러오려면 CORS 헤더가 필요합니다.
    모듈이 저장되어있는 원격 서버가 Access-Control-Allow-Origin: *헤더를 제공해야만 외부 모듈을 불러올 수 있다.
    대신 페치(fetch)를 허용할 도메인을 명시할 수도 있습니다. 이 특징은 보안을 강화해 준다
    <!-- another-site.com이 Access-Control-Allow-Origin을 지원해야만 외부 모듈을 불러올 수 있습니다.-->
    <!-- 그렇지 않으면 스크립트는 실행되지 않습니다.-->
    <script type="module" src="http://another-site.com/their.js"></script>

 

요약!

  • 모듈은 자신만의 스코프를 갖습니다. 모듈 간 기능 공유는 import, export로 할 수 있습니다.
  • 항상 엄격 모드로 실행(use strict)됩니다.
  • 모듈 내 코드는 단 한 번만 실행됩니다. 모듈을 내보내면 이 모듈을 가져오기 하는 모듈 모두가
    내보내진 모듈을 공유합니다.
  • 지연 실행된다.
  • 인라인 모듈 스크립트도 비동기 처리할 수 있다.
  • 외부 오리진(도메인이나 프로토콜, 포트가 다른 오리진)에서 스크립트를 불러오려면 CORS 헤더가 있어야 한다.
  • 중복된 외부 스크립트는 무시됨.

모던 자바스크립트 Deep Dive 거의 마지막 장인 모듈 부분을 정리하면서 거의 5개월이라는 시간 동안

900장 불량의 책을 다 읽게 되었다 이렇게 책을 꾸준히 읽은 적은 처음이다.

정말 스터디 모임의 없더라면 읽지 않았을 것 같고 계속해서 공부에 자극이 될만한 일을 꾸준히 해야겠다.

 

책: 모던 자바스크립트 Deep Dive

참고 사이트: https://ko.javascript.info/modules-intro#ref-298