2016-04-01 52 views
74

ho bisogno di fare qualcosa di simile:Come posso importare condizionatamente un modulo ES6?

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

Il codice di cui sopra non può essere compilato; getta SyntaxError: ... 'import' and 'export' may only appear at the top level.

Ho provato a utilizzare System.import come illustrato here, ma non so da dove proviene lo System. È una proposta ES6 che non è stata accettata? Il collegamento a "API programmatiche" di quell'articolo mi invia a deprecated docs page.

+0

Basta importare normalmente. Il tuo modulo ne ha bisogno a prescindere. – Andy

+0

Non vedo alcun motivo per cui non si importerebbe solo indipendentemente dalla condizione. Non è che ci sia una sorta di sovraccarico. In alcuni scenari è necessario il file, quindi non è che ci sia mai un caso in cui può essere completamente ignorato. In tal caso, basta importarlo incondizionatamente. – naomik

+3

Il mio caso d'uso: voglio rendere semplice avere una dipendenza opzionale. Se il dep non è necessario, l'utente lo rimuove da 'package.json'; il mio 'gulpfile' quindi controlla se esiste questa dipendenza prima di eseguire alcuni passi di costruzione. – ericsoco

risposta

32

Abbiamo ora una proposta di importazioni dinamiche con ECMA. Questo è in fase 3. Questo è disponibile anche come babel-preset.

Di seguito è riportato un modo per eseguire il rendering condizionale secondo il caso.

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

Questo sostanzialmente restituisce una promessa. Si prevede che la risoluzione della promessa abbia il modulo. La proposta ha anche altre caratteristiche come le importazioni dinamiche multiple, le importazioni di default, l'importazione di file js ecc. Puoi trovare ulteriori informazioni su dynamic imports here.

+4

Infine, una vera risposta ES6! Grazie a @thecodejack. In realtà allo stadio 3 al momento in cui scrivo, secondo quell'articolo ora. – ericsoco

+0

sì .. aggiorna la risposta – thecodejack

9

Sembra che la risposta sia che, al momento, non è possibile.

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

ritengo l'intento è quello di consentire l'analisi statica, per quanto possibile, e moduli condizionatamente importati rompono questo. Vale anche la pena ricordare - sto usando Babel, e suppongo che System non sia supportato da Babel perché l'API del caricatore di moduli non è diventato uno standard ES6.

+1

Suppongo che stiate cercando https://github.com/ModuleLoader/es6-module-loader. –

+0

@FelixKling rende questa la sua risposta e lo accetterò felicemente! – ericsoco

52

Se desideri, puoi utilizzare require. Questo è un modo per avere una dichiarazione di obbligo condizionale.

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

Non è possibile importare in modo condizionale, ma è possibile fare il contrario: esportare qualcosa in modo condizionale. Dipende dal tuo caso d'uso, quindi questa soluzione potrebbe non essere adatta a te.

Si può fare:

api.js

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

const exportedAPI = shouldUseMock ? mockAPI : realAPI 
export default exportedAPI 

apiConsumer.js

import API from './api' 
... 

Io uso che per analisi finte librerie come MixPanel, ecc ... perché non posso' Ho più build o il nostro frontend al momento. Non il più elegante, ma funziona. Ho solo un po 'se' qua e là a seconda dell'ambiente perché nel caso di mixpanel, ha bisogno di inizializzazione.

+5

Questa soluzione causa il caricamento di moduli indesiderati, quindi non una soluzione ottimale, penso. – ismailarilik

+1

Come indicato nella risposta, questa è una soluzione. A quel tempo, non c'era semplicemente nessuna soluzione. Le importazioni ES6 non sono dinamiche, questo è dovuto alla progettazione. La proposta della funzione di importazione dinamica ES6, descritta nella risposta attualmente accettata, può farlo. JS si sta evolvendo :) – Amida

0

oscurando in un eval lavorato per me, nascondendolo dal analizzatore statico ...

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

Problemi correlati