애플리케이션의 크기가 커져 파일을 여러 개로 분리해야 할 때, 분리된 파일 각각을 '모듈'이라고 부른다.
모듈은 대개 클래스 하나 or 특정한 목적을 가진 복수의 함수로 구성된 라이브러리 하나로 구성된다.
- export : 외부 모듈에서 export가 붙은 변수나 함수에 접근 가능(모듈 내보내기).
- import : 외부 모듈의 기능 가져오기 가능(모듈 가져오기).
http, https 프로토콜을 통해 모듈 import, export동작.
모듈은 항상 use strict(엄격모드)로 실행된다. 때문에, 변수에 값 할당 전에 꼭 선언 해야 코드 에러 발생 안 함!
모듈 레벨 스코프
: 모듈은 자신만의 스코프가 있다. 모듈 내부에서 정의한 변수나 함수는 다른 스크립트에서 접근 불가.
***외부에 공개하려는 모듈은 export 해야 하고, 내보내진 모듈을 가져와 사용하려면 import 해줘야 합니다.
전역 변수 대신 export, import를 통해 값만 가져와 사용가능.
동일한 모듈이 여러 곳에서 사용되는 경우.
최초 호출 시 단 한 번만 실행된 후, 이 결과가 모듈을 가져가려는 모든 모듈에 보내진다.
// 📁 alert.js
alert("모듈이 평가되었습니다!");
// 동일한 모듈을 여러 모듈에서 가져오기
// 📁 1.js
import `./alert.js`; // 얼럿창에 '모듈이 평가되었습니다!'가 출력됩니다.
// 📁 2.js
import `./alert.js`; // 아무 일도 발생하지 않습니다.
실무 사용 예) 초기화나 내부에서 쓰이는 데이터 구조를 만들고 내보내 재사용할 때 최상위 레벨 모듈 사용.
이해를 돕기 위한 예)
// 📁 admin.js
export let admin = {
name: "John"
};
//같은 객체 admin을 가져와 1.js, 2.js에 전달하게 됨.
// 📁 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 모두 같은 객체를 가져오므로
// 1.js에서 객체에 가한 조작을 2.js에서도 확인할 수 있습니다.
*** 이 점을 사용하면, 모듈 설정을 쉽게 할 수 있다.
import.meta
- 현재 모듈에 대한 정보를 제공.
브라우저 환경에서는 스크립트 URL 정보 반환.
this는 undefined
모듈 최상위 레벨의 this는 undefined. (일반 스크립트의 this는 전역 객체)
브라우저 특정 기능
모듈 스크립트 : type="module"
그러므로, 모듈 스크립트는 항상 완전한 HTML 페이지를 보고, 접근 가능.
인라인 스크립트의 비동기 처리
일반스크립트 : 외부 스크립트 불러올 때, 로딩이 끝나면 다른 스크립트나 HTML 문서 처리를 기다리지 않고 바로 실행.
모듈스크립트 : async 속성 인라인 스크립트에 사용 시. 다른 스크립트나 HTML 문서 처리를 기다리지 않고 바로 실행.
<!-- 필요한 모듈(analytics.js)의 로드가 끝나면 -->
<!-- 문서나 다른 <script>가 로드되길 기다리지 않고 바로 실행됩니다.-->
<script async type="module">
import {counter} from './analytics.js';
counter.count();
</script>
외부 스크립트
type="module"가 붙은 외부 모듈 스크립트 특징.
1) src 속성값이 동일한 외부 스크립트는 한 번만 실행된다.
<!-- my.js는 한 번만 로드 및 실행됩니다. -->
<script type="module" src="my.js"></script>
<script type="module" src="my.js"></script>
2) 외부 사이트 같은 다른 오리진에서 모듈 스크립트를 불러오려면 CORS헤더가 필요.
모듈이 저장되어 있는 원격 서버가 Access-Control-Allow-Origin: * 헤더 제공해야만 외부 모듈 가져오기 가능.
( '*' 대신 도메인 명시도 가능 )
<!-- another-site.com이 Access-Control-Allow-Origin을 지원해야만 외부 모듈을 불러올 수 있습니다.-->
<!-- 그렇지 않으면 스크립트는 실행되지 않습니다.-->
<script type="module" src="http://another-site.com/their.js"></script>
경로 없는 모듈 import 금지!
nomodule
=> 구식 브라우저는 type="module"을 해석하지 못함 => '<script nomodule>'을 사용해 대비 가능.
빌드 툴
브라우저 환경에서는 웹팩 같은 특별한 툴을 사용해 모듈을 번들링(한 데 묶음) 후 프로덕션 서버에 올린다.
빌트 툴 역할?
1. <script type="module">에 넣을 주요 모듈(진입점) 선택
2. 주요 모듈을 시작으로 모듈 간 의존 관계를 파악
3. 모든 모듈을 모아 하나의 큰 파일을 만든다(또는 여러 개로 만들 수도 있음) 이때, import문이 번들러 내 함수로 대체되어 기능 유지됨.
4. 변형 및 최적화가 위 과정 중 수행됨. (도달불가 코드 삭제, 사용 안 되는 모듈 삭제, 개발 관련 코드 console, debugger 등 삭제됨, 바벨을 사용해 동일 기능 낮은 버전의 스크립트로 변환, 공백제거, 변수이름 줄이기 등 실행.)
번들링 툴 사용 시 import, export 사라짐 => type="module"이 필요 없어 번들링 후의 스크립트는 일반 스크립트 취급 가능.
<!-- 웹팩과 같은 툴로 번들링 과정을 거친 스크립트인 bundle.js -->
<script src="bundle.js"></script>
export type
import type
let modulePath = prompt("어떤 모듈을 불러오고 싶으세요?");
import(modulePath)
.then(obj => <모듈 객체>)
.catch(err => <로딩 에러, e.g. 해당하는 모듈이 없는 경우>)
https://ko.javascript.info/modules-dynamic-imports
Javascript 암호화, 복호화 메서드 (0) | 2023.02.27 |
---|---|
SSO - Single Sign-On? (1) | 2023.02.17 |
javascript.info - 제너레이터와 비동기 이터레이션 (0) | 2023.01.02 |
javascript.info - 프라미스와 async, await(3) (0) | 2023.01.02 |
javascript.info - 프라미스와 async, await(2) (0) | 2023.01.02 |