코딩항해기

[JS] 모듈 (import, export) 본문

HTML CSS JS

[JS] 모듈 (import, export)

miniBcake 2024. 9. 15. 15:01

 

 

자바스크립트 모듈 module

개발하는 프로젝트의 크기가 커지면 파일을 여러 개로 분리해야하는 때가 온다. 이 때 분리된 파일 각각을 모듈 이라고 하며, 모듈은 대개 클래스 하나 혹은 특정한 목적을 가진 복수의 함수로 구성된 라이브러리 하나로 구성된다.

모듈에 특수한 지시자 export를 이용해 내보내고, import를 이용해 다른 모듈을 불러와 불러운 모듈에 있는 함수를 호출하는 것과 같은 기능 공유가 가능하다.

 

 

모듈 명시

모듈은 특수한 키워드나 기능과 함께 사용되므로 모듈임을 명시해야한다.

<script type="module"></script>

 

 

모듈 특징

모듈은 로컬파일에서 동작하지 않고 http, https 프로토콜을 통해서만 동작하므로, 로컬에서 file:// 프로토콜을 사용해 웹페이지를 열면 import, export 지시자가 동작하지 않는다. 또한 모듈스크립트는 크기가 작아 html보다 빨리 불러온 경우에도 html문서가 완전히 만들어진 이후에 실행된다. 항상 지연 실행되는 셈이다.

 

다만 모듈은 비동기 처리도 가능한데 이 경우 비동기임을 명시하기 위해 async 속성을 표기한다. async 속성이 붙은 경우 html 파싱이 끝나지 않았거나 다른 스크립트가 대기 상태에 있더라도 바로 실행된다. 종속되지 않는 기능을 구현할 때 용이하다. (광고, 문서 레벨 이벤트 리스너, 카운터 등)

 

모듈은 단 한 번만 평가된다는 특징도 있다. 동일한 모듈이 여러 곳에서 사용되더라도 최초 호출 시 단 한 번만 실행되어 이 모듈을 import하는 모든 모듈에 보내진다. 예를 들어 alert창을 띄우는 모듈을 여러 번 호출하면 단 한 번만 창이 뜬다.

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

 

기본 순서 : <script> -> DOM(button) -> <script type="module">

 

 

 

 

 

 

export

named exports 여러 값을 export할 때 사용한다. export된 이름을 사용하여 import할 수 있다.
default exports 모듈 당 딱 한 개의 export만 가능하다. 메인이라고 할 수 있는 것을 export할 때 사용하는 것이 좋다.
re-exports 부모 모듈이 자식 모듈을 가져와 다시 export할 수 있다.

 

 

named exports 예시

여러 개의 함수, 변수를 내보낼 때 사용하는 방식이다.
여러 개의 export값이 있을 수 있으므로 import할 때는 반드시 중괄호로 묶어야한다.

export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
//함수 또는 변수를 여러 개 내보낼 수 있다.

 

 

default exports 예시

모듈 당 딱 한 개만 가능하다. 하나만 있다는 것을 명시할 때 사용한다.
단 하나의 export 값만 존재하므로 import할 때는 중괄호를 생략 할 수 있다. 

const logger = (message) => console.log(message);
export default logger;
//하나만 내보낼 수 있다.

 

 

re-exports 예시

여러 개의 모듈을 모아놓은 하나의 모듈을 만들 수도 있다.

이때 모듈을 불러오는 방식은 import와 동일한 방식으로 진행된다.

export { add, subtract } from './math.js';  
//받아온 math.js의 함수들을 다시 내보낸다.

 

 

 

import

정적 방식 모아보기

모듈 전체 가져오기 import * as 앞에붙을명칭 from "모듈파일명";       // 앞에붙을명칭.함수명()
하나의 멤버 가져오기 import {함수명} from "모듈파일명";
여러 개의 멤버 가져오기 import {함수명1, 함수명2} from "모듈파일명";
다른 이름으로 가져오기 import {함수명1 as 별칭1, 함수명2 as 별칭2} from "모듈파일명";
바인딩 없이 모듈만 실행하기 import "모듈파일명";
default export 값 가져오기 import 함수명 from "모듈파일명";
다른 이름으로 default 가져오기 import {default as 바꿔줄이름} from "모듈파일명";

 

 

동적으로 import하기

 

정적 방식의 import는 여러 제약이 있는데, 그 중 하나의 제약은 모듈 경로에 함수를 넣을 수 없다는 것이다. 원시 문자열만 들어갈 수 있기 때문에 동적인 경로를 불러오는 것이 불가했다. 그 외에도 런타임이나 조건부로 모듈을 불러올 수 없다는 점이 있었다. 정적 import는 if문(조건문)이나 블록 안에 위치할 수 없기 때문이다.

 

import(module)

모듈을 읽고 이 모듈이 내보내는 것을 모두 포함하는 객체를 담은 프라미스를 반환한다.

async 함수 안에서 사용하는 것도 가능하다. 

 

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

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

// let module = await import(modulePath)

 

 

예제 (출처 블로그 참고)

*동적 import는 일반 스크립트에서도 동작하고 script에 모듈 속성을 표기하지 않아도 된다.

 

 

 

 

 

출처: https://inpa.tistory.com/entry/JS-📚-모듈-사용하기-import-export-정리 [Inpa Dev 👨‍💻:티스토리]

참고: https://velog.io/@reasonz/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%AA%A8%EB%93%88-export-import