Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

동적으로 모듈 불러오기 본문

💬 언어/Javascript

동적으로 모듈 불러오기

Chamming2 2021. 3. 9. 12:44
// utils.js
const sayHello = () => {
  console.log("안녕하세요!");
};

const sayNothing = () => {
  console.log("...");
};

export { sayHello, sayNothing };
import { sayHello, sayNothing } from "./utils.js"

자주 보셨을 import-export 구문입니다.

그런데 조건에 따라 모듈을 불러오는 것도 가능할까요?

// Error!!!

if(person === "friend") {
    import { sayHello } from "./utils.js";
    sayHello();
}
else if(person === "professor") {
    import { sayNothing } from "./utils.js";
    sayNothing();
}

물론 이렇게 사용하면 오류가 출력됩니다.

 

코드를 짜다 보면 버튼을 눌렀을 때만 외부 함수를 호출하는 경우 등 특정 조건에 따라서 불러와야 하는 모듈이 있을 수도 있을 수 있는데요, 오늘은 필요할 때만 동적으로 모듈을 불러오는 방법을 소개하도록 하겠습니다.

import 함수

import("./utils.js");

어딘가 낯선 모습입니다. import를 함수 형태로 사용하면 인자로 받은 모듈을 불러온 후 이행(resolve) 객체로 모듈을 갖는 프라미스를 리턴하는데요, 이행 객체를 콘솔에 찍어보면 확실히 모듈을 불러왔음을 알 수 있습니다.

import("./utils.js").then((res) => console.log(res));
Module {Symbol(Symbol.toStringTag): "Module"}
  sayHello: (...)
  sayNothing: (...)
  Symbol(Symbol.toStringTag): "Module"
  get sayHello: ƒ ()
  set sayHello: ƒ ()
  get sayNothing: ƒ ()
  set sayNothing: ƒ ()

따라서 아래처럼 외부 모듈의 함수를 호출할 수 있게 됩니다.

import("./utils.js").then((res) => res.sayHello()) // 안녕하세요!

기본값 내보내기(export default) 도 유사합니다. 다만, 내보내기 기본값은 이행 객체에서 default 라는 이름의 프로퍼티로 존재합니다.

// utils.js
const sayHello = () => {
  console.log("안녕하세요!");
};

const sayNothing = () => {
  console.log("...");
};

const defaultSay = () => {
  console.log("좋은 하루 보내세요!");
};

export { sayHello, sayNothing };
export default defaultSay;
Module {Symbol(Symbol.toStringTag): "Module"}
  default: (...) // export default로 내보낸 함수
  sayHello: (...)
  sayNothing: (...)
  Symbol(Symbol.toStringTag): "Module"
  get default: ƒ ()
  set default: ƒ ()
  get sayHello: ƒ ()
  set sayHello: ƒ ()
  get sayNothing: ƒ ()
  set sayNothing: ƒ ()
import("./utils.js").then((res) => res.default()) // 좋은 하루 보내세요!​

async-await과 함께 사용하기

프라미스 형태로 사용할 수 있다면 async-await을 사용하도록 고치는 것도 얼마든지 가능합니다.

const load = async () => {
    // 모듈 객체에 대해 분해 할당을 사용한 모습입니다.
    const { sayHello } = await import("./utils.js");
    sayHello();
}	

결론

지금까지 조건에 따라 동적으로 외부 모듈을 불러와 활용하는 방법을 알아보았습니다.

if(person === "friend") {
    import("./utils.js").then((res) => res.sayHello()) // 안녕하세요!
}
else if(person == "professor") {
    import("./utils.js").then((res) => res.default()) // 좋은 하루 보내세요!
}
else {
    // 이 분기에서는 utils.js 모듈을 로드하지 않습니다.
    console.log("누구지?")
}

이 방법은 리액트의 "코드 스플리팅" 이라는 기법의 원리인데요, 오늘 배운 내용을 어떻게 실제로 유용하게 사용할 수 있는지 소개하는 시간도 가져보도록 하겠습니다.

TL;DR

- 동적 불러오기를 활용하면 조건에 따라 필요할 때만 모듈을 불러올 수 있다. (네트워크 성능 이득)

- import 를 함수로 사용하면 인자로 받은 모듈을 이행 객체로 갖는 프라미스를 반환한다.

- export default 로 내보낸 요소는 default 프로퍼티로 접근할 수 있다.

 

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆