본문으로 건너뛰기

import()

정보

mdn 문서의 import()를 번역하였습니다.

원본 바로가기

흔히 동적 임포트라고 불리는 import() 구문은 ECMAScript 모듈을 잠재적으로 모듈이 아닌 환경에 비동기적이고 동적으로 사용할 수 있게 하는 함수와 유사한 표현입니다.

선언 스타일과는 다르게, 동적 임포트는 필요할 때만 평가되며, 더 큰 구문적인 유연함을 허용합니다.


문법

import(moduleName)

import() 실행은 함수의 실행과 매우 유사한 구문입니다. 하지만 import 자체는 키워드이지 함수가 아닙니다. 따라서 const myImport = import와 같은 별칭을 둘 수 없으며, 사용시 구문오류가 발생합니다.

Parameters

moduleName 임포트할 모듈의 명시자의 평가는 호스트 지정식 이지만, 정적 임포트와 항상 동일한 알고리즘을 따릅니다.

Return value

moduleName 내보내진 모든 것을 담고 있는 객체인 모듈 네임스페이스 객체를 이행하는 프로미스를 반환합니다.

import() 평가는 절대 동기적으로 오류를 발생시키지 않습니다. moduleNamestring으로 강제되며, 그 강제가 발생하면, 프로미스는 오류와 함께 거절됩니다.


상세설명

import 선언 문법 (importd something from "somewhere")은 정적이며 항상 로드타임에 평가된 모듈을 가져옵니다. 동적 임포트는 import 선언의 구문적 제한을 우회할 수 있게 해주며 조건부로 또는 필요에 따라 모듈을 불러올 수 있게 해줍니다. 동적 임포트가 필요한 이유는 다음과 같습니다.

  • 정적 임포트가 확연히 코드를 불러오는 것을 느리게 하거나 메모리 사용을 증가시킬때, 그리고 가져온 코드가 필요할 가능성이 낮거나, 당장은 필요하지 않을 때.
  • 가져오려는 모듈이 로드시점에 존재하지 않을 때
  • import 지시어 문자열이 동적으로 생성되어야 할 때 (정적 임포트는 정적 지시어만 지원합니다.)
  • import된 모듈이 부수효과가 있고, 특정 조건에만 그 부수효과를 원할 때. (모듈 안에서 어떠한 부수효과를 가지는것을 추천하지 않지만, 때로는 모듈 의존성을 제어할 수 없는 경우가 있습니다.)
  • 모듈이 아닌 환경에 있을 때 (예를 들어, eval 또는 스크립트 파일)

꼭 필요할 때만 다이나믹 임포트를 사용하세요. 초기 의존성 로드에는 정적 임포트가 더 선호되며, 정적 분석툴과 트리쉐이킹으로부터 즉각적인 이점을 취할 수 있습니다.

당신의 파일이 모듈로 동작하지 않는다면(HTML 파일 안에서 참조된다면, 스크립트 태그는 type="module"을 가져야합니다.), 정적 임포트 선언을 사용할 수 없습니다. 하지만 비동기적인 동적 임포트 문법은 언제나 사용할 수 있어 모듈이 아닌 환경에서도 모듈을 가져올 수 있게 합니다.

동적 모듈 임포트는 모든 실행 문맥에서 허용되지 않습니다. 예를 들어, import()는 메인 쓰레드, shared worker, dedicated worker에서 사용될 수 있지만, service worker 또는 worklet과 함께 사용된다면 오류가 발생할 것입니다.

모듈 네임스페이스 객체

모듈 네임스페이스 객체는 한 모듈에서 내보내진 모든 것을 표현하는 객체입니다. 이 정적 객체는 모듈이 평가될 때 생성됩니다. 어떤 모듈의 모듈 네임스페이스 객체에 접근하는 두가지 방법이 있습니다: 네임스페이스 import를 통하거나(import * as name from moduleName), 동적 import의 이행된 값을 통해서.

모듈 네임스페이스 객체는 null prototype으로 sealed된 객체입니다. 즉 객체의 모든 문자열 키가 그 모듈의 내보내진 것들과 일치하며 그 외의 키는 존재 하지 않는다는 의미입니다. 모든 키들은 사전 순서로(즉, Array.prototype.sort()의 기본동작입니다.) 나열(enumable)됩니다. 동시에 default export는 default라는 키로 사용가능합니다. 게다가, 모듈 네임스페이스 객체는 Object.prototype.toString()에서 사용되는 "Module"을 값으로 가진 @@toStringTag 속성을 가지고 있습니다.

문자열 속성들은 그 속성들의 기술자를 가져오려고 Object.getOwnPropertyDescriptors()을 사용할 때 설정불가하고 기록가능하지만 그들은 사실상 읽기전용입니다, 왜냐하면 새로운 값으로 속성을 재할당할 수 없기 때문입니다. 그 행동은 정적임포트가 "live bindings" 모듈이 exporting하여 재당할될 수 있지만 가져오는 모듈에서는 재할당 될 수 없는 값-을 생성할 수 있다는 사실을 반영합니다. 속성의 기록가능성은 값이 변화할 수 있다는 가능성을 반영합니다, 왜냐하면 조정할 수 없고 쓸 수 없는 속성은 상수여야하기 때문입니다. 예를 들어 당신은 내보내진 변수를 재할당할 수 있고, 새로운 값은 모듈 네임스페이스 객체에서 관찰될 수 있습니다.

각 모듈 지시자는 유일한 모듈 네임스페이스 객체와 일치하기 때문에 다음은 일반적으로 참입니다.:

import * as mod from "/my-module.js";

import("/my-module.js").then((mod2) => {
console.log(mod === mod2); // true
});

하나의 특이한 케이스를 제외합니다: 프로미스는 결코 thenable로 이행되지 않으므로 my-module.js 모듈이 then()이라는 함수를 내보낸 경우 해당 함수가 동적 임포트의 프로미스가 이행될 때 자동으로 호출됩니다. 이는 프로미스 처리 프로세스의 일부로서 발생합니다.

// my-module.js
export function then(resolve) {
console.log("then() called");
resolve(1);
}
// main.js
import * as mod from "/my-module.js";

import("/my-module.js").then((mod2) => {
// Logs "then() called"
console.log(mod === mod2); // false
});
warning

경고: then()이라는 함수를 모듈로부터 내보내지마세요. 정적 임포트와 동적 임포트에서 모듈이 다르게 동작하게 되는 원인이 됩니다.