Como posso importar condicionalmente um módulo ES6?

Eu preciso fazer algo como:

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

O código acima não compila; Ele lança SyntaxError: ... 'import' and 'export' may only appear at the top level .

Eu tentei usar System.import como mostrado aqui , mas não sei de onde o System vem. É uma proposta do ES6 que não acabou sendo aceita? O link para “API programática” desse artigo me despeja em uma página de documentos obsoleta .

Nós temos a proposta de importações dinâmicas agora com o ECMA. Isso está no estágio 3. Isso também está disponível como predefinição de babel .

A seguir está a maneira de renderizar condicional conforme o seu caso.

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

Isso basicamente retorna uma promise. Espera-se que a resolução da promise tenha o módulo. A proposta também tem outros resources, como várias importações dinâmicas, importações padrão, importação de arquivos js etc. Você pode encontrar mais informações sobre importações dinâmicas aqui .

Se você quiser, você pode usar require. Esta é uma maneira de ter uma instrução de condicionalidade.

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

Você não pode importar condicionalmente, mas você pode fazer o oposto: exportar algo condicionalmente. Depende do seu caso de uso, então esse trabalho pode não ser para você.

Você pode fazer:

api.js

 import mockAPI from './mockAPI' import realAPI from './realAPI' const exportedAPI = shouldUseMock ? mockAPI : realAPI export default exportedAPI 

apiConsumer.js

 import API from './api' ... 

Eu uso isso para simular bibliotecas de analytics como mixpanel, etc … porque não posso ter várias compilações ou nosso frontend atualmente. Não é o mais elegante, mas funciona. Eu só tenho alguns ‘if’ aqui e ali, dependendo do ambiente, porque no caso do mixpanel, ele precisa de boot.

Parece que a resposta é que, a partir de agora, você não pode.

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

Eu acho que a intenção é permitir a análise estática, tanto quanto possível, e módulos importados condicionalmente quebram isso. Também vale a pena mencionar – Estou usando o Babel , e estou supondo que o System não é suportado pelo Babel porque a API do carregador de módulos não se tornou um padrão do ES6.

obscurecendo-o em um eval trabalhou para mim, escondendo-o do analisador estático …

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