2016-04-01 13 views
74

muszę zrobić coś takiego:Jak mogę warunkowo zaimportować moduł ES6?

if (condition) { 
    import something from 'something'; 
} 
// ... 
if (something) { 
    something.doStuff(); 
} 

Powyższy kod nie kompiluje; rzuca SyntaxError: ... 'import' and 'export' may only appear at the top level.

Próbowałem użyć System.import jak pokazano here, ale nie wiem skąd pochodzi System. Czy to propozycja ES6, która ostatecznie nie została zaakceptowana? Link do "programistycznego API" z tego artykułu rzuca mnie na numer deprecated docs page.

+0

Wystarczy zaimportować go normalnie. Twój moduł potrzebuje tego niezależnie. – Andy

+0

Nie widzę żadnego powodu, dla którego nie importowałbyś go bez względu na stan. To nie tak, że jest jakiś nadmiar. W niektórych scenariuszach potrzebujesz pliku, więc nie jest tak, że kiedykolwiek można go całkowicie pominąć. W takim przypadku wystarczy zaimportować go bezwarunkowo. – naomik

+3

Mój przypadek użycia: chcę, aby było łatwo mieć opcjonalną zależność. Jeśli dep nie jest potrzebny, użytkownik usuwa go z 'pakiet.json'; mój 'gulpfile' sprawdza, czy ta zależność istnieje przed wykonaniem niektórych kroków kompilacji. – ericsoco

Odpowiedz

32

Mamy teraz propozycję importu dynamicznego z ECMA. To jest na etapie 3. Jest to również dostępne pod numerem babel-preset.

Poniżej przedstawiono sposób renderowania warunkowego zgodnie ze swoim przypadkiem.

if (condition) { 
    import('something') 
    .then((something) => { 
     console.log(something.something); 
    }); 
} 

To zasadniczo zwraca obietnicę. Rozstrzygnięcie obietnicy ma mieć moduł. Wniosek ma również inne funkcje, takie jak wiele importów dynamicznych, import domyślny, import plików js itd. Więcej informacji na temat dynamic imports here można znaleźć.

+4

Wreszcie prawdziwa odpowiedź ES6! Dzięki @thecodejack. Właściwie na etapie 3 od tego pisania, zgodnie z tym artykułem teraz. – ericsoco

+0

yep..updated odpowiedź – thecodejack

9

Wygląda na to, że odpowiedź brzmi, że od tej chwili nie można.

http://exploringjs.com/es6/ch_modules.html#sec_module-loader-api

Myślę, że intencją jest umożliwienie analizy statycznej jak najwięcej, a warunkowo importowane moduły złamać to. Warto również wspomnieć - używam Babel i domyślam się, że System nie jest wspierany przez Babel, ponieważ API modułu ładującego moduły nie stał się standardem ES6.

+1

Chyba szukasz https://github.com/ModuleLoader/es6-module-loader. –

+0

@FelixKling to własna odpowiedź, a ja z przyjemnością ją zaakceptuję! – ericsoco

52

Jeśli chcesz, możesz użyć wymagania. Jest to sposób na warunkowe żądanie wymagające.

if (condition) { 
    const something = require('something'); 
    const other = require('something').other; 
} 
if (something && other) { 
    something.doStuff(); 
    other.doOtherStuff(); 
} 
18

Nie można zaimportować warunkowo, ale można zrobić odwrotnie: wyeksportować coś warunkowo. To zależy od twojego przypadku użycia, więc ta praca może nie być dla ciebie.

można zrobić:

api.js

import mockAPI from './mockAPI' 
import realAPI from './realAPI' 

const exportedAPI = shouldUseMock ? mockAPI : realAPI 
export default exportedAPI 

apiConsumer.js

import API from './api' 
... 

używam tego drwić analityki libs jak mixpanel itp ... bo mogę” • Mamy obecnie wiele buildów lub naszą frontend. Nie jest to najbardziej elegancki, ale działa. Mam tylko kilka "jeśli" tu i tam w zależności od środowiska, ponieważ w przypadku miksera wymaga on inicjalizacji.

+5

To rozwiązanie powoduje ładowanie niechcianych modułów, więc nie jest to optymalne rozwiązanie. – ismailarilik

+1

Jak stwierdzono w odpowiedzi, jest to obejście. W tamtym czasie nie było po prostu rozwiązania. Import ES6 nie jest dynamiczny, jest to zgodne z projektem. Propozycja funkcji dynamicznego importu ES6, opisana w obecnie akceptowanej odpowiedzi, może to zrobić. JS ewoluuje :) – Amida

0

zasłaniając go w eval pracował dla mnie, ukrywając go z analizatora statyczne ...

if (typeof __CLI__ !== 'undefined') { eval("require('fs');") }

Powiązane problemy