ES6 : 조건부 및 동적 가져 오기 문


85

가정 어구

아래와 같은 조건부 import 문을 가질 수 있습니까?

if (foo === bar) {
    import Baz from './Baz';
}

위의 방법을 시도했지만 컴파일 할 때 Babel에서 다음과 같은 오류가 발생합니다.

'import' and 'export' may only appear at the top level

동적

아래와 같은 동적 import 문을 가질 수 있습니까?

for (let foo in bar) {
    if (bar.hasOwnProperty(foo)) {
        import Baz from `./${foo}`;
    }
}

위의 내용은 컴파일하는 동안 Babel에서 동일한 오류를 수신합니다.

이것이 가능합니까 아니면 내가 놓친 것이 있습니까?

추리

내가 이것을 시도하는 이유는 여러 "페이지"에 대해 많은 가져 오기를 가지고 있고 유사한 패턴을 따르기 때문입니다. 동적 for 루프를 사용하여 이러한 파일을 가져 와서 코드베이스를 정리하고 싶습니다.

이것이 가능하지 않다면 ES6에서 많은 수의 가져 오기를 처리하는 더 좋은 방법이 있습니까?


1
그런 경우 상속을 사용할 수 없습니까? super특정 전화에 사용 하십시오.
재이

이미 상속을 사용하고 있지만 이러한 "페이지"에는 "페이지"특정 논리가 포함되어 있습니다. 나는 모두 확장되는 기본 "페이지"클래스를 가지고 있지만 이것은 내가 가지고있는 많은 수입을 정리하기에 충분하지 않습니다.
Enijar

1
@zerkms : 블록 밖으로 들어오지 않고 구문 오류입니다.
Bergi

node.js에서 ES6 변수 가져 오기 이름의 중복 가능성이 있습니까?
Bergi

답변:


54

우리는 이제 ECMA와 함께 동적 수입 제안을 가지고 있습니다. 이것은 2 단계에 있습니다. 이것은 babel-preset 으로도 사용할 수 있습니다 .

다음은 귀하의 경우에 따라 조건부 렌더링을 수행하는 방법입니다.

if (foo === bar) {
    import('./Baz')
    .then((Baz) => {
       console.log(Baz.Baz);
    });
}

이것은 기본적으로 약속을 반환합니다. 약속의 해결에는 모듈이있을 것으로 예상됩니다. 제안에는 여러 동적 가져 오기, 기본 가져 오기, js 파일 가져 오기 등과 같은 항목도 있습니다 . 여기에서 동적 가져 오기 에 대한 자세한 정보를 찾을 수 있습니다 .


3
이. 동적 가져 오기가 그 길입니다. 모듈이 아닌 약속을 제공한다는 점을 제외하면 require ()와 똑같이 작동합니다.
superluminary

24

imports정적 분석을위한 것처럼 종속성을 동적으로 해결할 수 없습니다 . 그러나 require다음과 같이 여기에서 사용할 수 있습니다 .

for (let foo in bar) {
    if (bar.hasOwnProperty(foo)) {
        const Baz = require(foo).Baz;
    }
}

8
"수입은 정적 분석을위한 것이므로."---이 진술은 모호합니다. import는 분석 용이 아니라 가져 오기 위해 설계되었습니다.
zerkms

12
@zerkms- import문장이 정적 분석에 적합하다는 것을 의미한다고 생각합니다 . 조건이 없기 때문에 도구가 종속성 트리를 더 쉽게 분석 할 수 있습니다.
조 클레이

4
"foo" "baz"및 "bar"로 이해하기 어렵습니다. 실제 예는 어떻습니까?
TetraDev 2016 년

1
이것은 더 이상 사실이 아닙니다. 이제 동적 가져 오기가 중요합니다. 여기를 참조하십시오 : stackoverflow.com/a/46543949/687677
superluminary

7

이 질문은 Google에서 높은 순위를 차지하기 때문에 이전 답변이 게시 된 후 상황이 변경되었음을 지적 할 가치가 있습니다.

MDN은 동적 가져 오기 아래에 다음 항목이 있습니다 .

import 키워드는 모듈을 동적으로 가져 오는 함수로 호출 될 수 있습니다. 이런 식으로 사용하면 promise를 반환합니다.

import('/modules/my-module.js')
  .then((module) => {
    // Do something with the module.
  });

// This form also supports the await keyword.
let module = await import('/modules/my-module.js');

주제에 대한 유용한 기사는 Medium 에서 찾을 수 있습니다 .


1

Require는 동기 호출이므로 문제를 해결하지 못합니다. 몇 가지 옵션이 있으며 모두 포함됩니다.

  1. 필요한 모듈 요청
  2. 모듈 반환 약속을 기다리는 중

ECMA 스크립트에는 SystemJS를 사용하는 지연로드 모듈에 대한 지원이 있습니다. 물론 이것은 모든 브라우저에서 지원되는 것은 아니므로 그 동안 JSPM 또는 SystemJS shim을 사용할 수 있습니다.

https://github.com/ModuleLoader/es6-module-loader


1

2016 년 이후 자바 스크립트 세계에서 많은 것이 통과되었으므로이 주제에 대한 최신 정보를 제공 할 때라고 생각합니다. 현재 동적 가져 오기노드브라우저 모두 에서 현실입니다 (기본적으로 IE에 관심이 없다면 @ babel / plugin-syntax-dynamic-import를 사용하세요).

따라서 something.js두 개의 이름이 지정된 내보내기와 하나의 기본 내보내기가 있는 샘플 모듈 을 고려하십시오 .

export const hi = (name) => console.log(`Hi, ${name}!`)
export const bye = (name) => console.log(`Bye, ${name}!`)
export default () => console.log('Hello World!')

import()구문을 사용 하여 쉽고 깔끔하게 조건부로로드 할 수 있습니다.

if (somethingIsTrue) {
  import('./something.js').then((module) => {
    // Use the module the way you want, as:
    module.hi('Erick') // Named export
    module.bye('Erick') // Named export
    module.default() // Default export
  })
}

그러나 반환 값이 Promise이므로 async/ await구문 설탕도 가능합니다.

async imAsyncFunction () {
  if (somethingIsTrue) {
    const module = await import('./something.js')
    module.hi('Erick')
  }
}

이제 Object Destructuring Assignment 와 함께 가능성에 대해 생각해보십시오 ! 예를 들어, 사후 사용을 위해 이름이 지정된 내보내기 중 하나만 메모리에 쉽게 넣을 수 있습니다.

const { bye } = await import('./something.js')
bye('Erick')

또는 이름이 지정된 내보내기 중 하나를 잡고 원하는 다른 이름으로 이름을 바꿀 수도 있습니다.

const { hi: hello } = await import('./something.js')
hello('Erick')

또는 기본 내 보낸 함수의 이름을 더 이해하기 쉬운 이름으로 바꿉니다.

const { default: helloWorld } = await import('./something.js')
helloWorld()

마지막 (적어도) 참고 : import() 함수 호출처럼 보일 수 있지만 Function. 괄호를 사용하는 특수 구문입니다 (에서 발생하는 것과 유사 함 super()). 따라서 import변수 에 할당 하거나 / Function와 같은 프로토 타입을 사용할 수 없습니다 .callapply

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.