모듈

모듈

특정 기능별로 클래스나 함수를 묶은 것. 자바스크립트가 커짐에 따라 모듈로 분리할 필요가 생겼다.

모듈이란

스크립트 하나는 모듈 하나이다.

내보내기

1
2
3
4
// 📁 sayHi.js
export function sayHi(user) {
alert(`Hello, ${user}!`);
}

가져오기

1
2
3
4
5
// 📁 main.js
import { sayHi } from "./sayHi.js";

alert(sayHi); // 함수
sayHi("John"); // Hello, John!

모듈의 핵심 기능

엄격 모드로 실행

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

1
<script type="module">a = 5; // 에러</script>

모듈 레벨 스코프

모듈간에는 당연히 변수를 공유하지 않는다.

단 한번만 평가됨

동일한 모듈이 여러 곳에서 사용되더라도 최초 호출 시 단 한번만 실행된다. 실무에서는 최상위 레벨 모듈을 대게 초기화나 내부에서 쓰이는 데이터 구조를 만들고 이를 내보내 재사용하고 싶을 때 사용한다.

최초에 가져온 모듈에서 가한 조작이 다음에 가져오는 상황에서 확인할 수 있다.

1
2
3
4
// 📁 admin.js
export let admin = {
name: "John",
};

모듈 가져오고 조작하기

1
2
3
4
5
6
7
8
9
10
// 📁 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에서도 확인할 수 있습니다.

이런 특징을 이용하면 모듈 설정을 쉽게 할 수 있다.

예를 들어 특정 기능을 사용하는 모듈이 사용전에 인증 정보를 받아와야 하는 등의 작업이 필요하다고 생각하면 이 기능을 활용할 수 있다.

1
2
3
4
5
6
// 📁 admin.js
export let admin = {};

export function sayHi() {
alert(`${admin.name}님, 안녕하세요!`);
}
1
2
3
// 📁 init.js
import { admin } from "./admin.js";
admin.name = "보라";
1
2
3
4
5
6
// 📁 other.js
import { admin, sayHi } from "./admin.js";

alert(admin.name); // 보라

sayHi(); // 보라님, 안녕하세요!

import.meta

import.meta 객체는 현재 모듈에 대한 정보를 제공해 주는데 브라우저 환경에서는 스크립트의 url 정보를 얻을 수 있다.

this 는 undefine만

모듈이 아닌 일반 객체에서 this는 전역 객체 window 이지만 모듈 내에서는 undefined이다.

브라우저 특정 기능

브라우저 환경에서 type="module"로 사용할때의 특징. 간단하게만 알아본다.

지연실행

defer 속성이 붙은 것처럼 실행되서 html 을 전부 파싱한 후에 실행된다.

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

async 속성이 붙은 스크립트는 로딩이 끝나면 다른 스크립트나 HTML 문서가 처리되길 기다리지 않고 바로 실행된다.

외부 스크립트

  1. 최최 실행
  2. CORS 헤더가 필요함.

경로가 없는 모듈은 금지

Node.js 같은건 모듈 경로를 알고 있어서 가져올 수 있지만 브라우저는 상대 혹은 절대 경로가 무조건 있어야 함.

빌드 툴

브라우저 환경에서 모듈을 ‘단독’으로 사용하는 경우는 흔치 않다. 대게 웹팩(Webpack)과 같은 특별한 툴을 사용해 모듈을 한데 묶어 프로덕션 서버에 올리는 방식을 사용한다.

일반 스크립트로 변환되기 대문에 type=”module”를 사용할 필요가 없어진다.