상세 컨텐츠

본문 제목

javascript.info - 모듈

개발공부/개발공부

by Dal_pang 2023. 1. 2. 17:58

본문

모듈 소개

애플리케이션의 크기가 커져 파일을 여러 개로 분리해야 할 때, 분리된 파일 각각을 '모듈'이라고 부른다.

모듈은 대개 클래스 하나 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"

  • <script type="module" src="...">를 다운로드할 때, HTML 처리가 멈추지 않는다. 브라우저는 외부 모듈 스크립트와 리소스를 병렬적으로 불러온다. (Defer속성을 붙인 것처럼 실행)
  • 모듈 스크립트는 HTML 문서가 파싱 된 후에 실행. (모듈이 HTML보다 빨리 불러와져 있는 상태에서도)
  • 스크립트의 상대적 순서가 유지된다. (위쪽 스크립트부터 차례로 실행됨)

그러므로, 모듈 스크립트는 항상 완전한 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

  • 클래스, 함수 등의 선언부 앞에 export 붙여서 내보내기:
    • export [default] class/function/variable ...
  • 이름 없는 개체 내보내기:
    • export {x [as y], ...}.
  • 다시 내보내기:
    • export {x [as y], ...} from "module"
    • export * from "module" (default export는 다시 내보내 지지 않음)
    • export {default [as y]} from "module" (default export를 다시 내보냄)

 

import type

  • named export 가져오기:
    • import {x [as y], ...} from "mod"
  • default export 가져오기:
    • import x from "mod"
    • import {default as x} from "mod"
  • 한 번에 가져오기:
    • import * as obj from "mod"
  • 모듈을 가져오긴 하지만(코드는 실행됨), 변수에 할당하지 않기:
    • import "mod"

동적으로 모듈 가져오기

let modulePath = prompt("어떤 모듈을 불러오고 싶으세요?");

import(modulePath)
  .then(obj => <모듈 객체>)
  .catch(err => <로딩 에러, e.g. 해당하는 모듈이 없는 경우>)

https://ko.javascript.info/modules-dynamic-imports

 

동적으로 모듈 가져오기

 

ko.javascript.info

 

728x90

관련글 더보기