Eu preciso fazer algo como:
if (condition) {
import something from 'something';
}
// ...
if (something) {
something.doStuff();
}
O código acima não compila; joga SyntaxError: ... 'import' and 'export' may only appear at the top level
.
Tentei usar System.import
como mostrado aqui , mas não sei de onde System
vem. É uma proposta do ES6 que não acabou sendo aceita? O link para "API programática" desse artigo me leva a uma página de documentos obsoleta .
javascript
module
ecmascript-6
ericsoco
fonte
fonte
package.json
; o meugulpfile
verifica se essa dependência existe antes de executar algumas etapas de compilação.webpack
ebabel
para transpilar es6 para es5. Projetos comowebpack-rewire
e similares não devem ajudar aqui - github.com/jhnns/rewire-webpack/issues/12 . Uma maneira de definir o dobro de teste OU para remover dependências problemáticas pode ser a importação condicional.webpack
é usado para converter folhas de estilo em módulos que inserem os estilos relevantes no DOM quando são importados), mas o módulo também precisa ser executado fora do navegador (por exemplo, para teste de unidade).Respostas:
Agora temos uma proposta de importação dinâmica com a ECMA. Isso está no estágio 3. Também está disponível como predefinição de babel .
A seguir, é apresentado um modo de renderização condicional conforme seu caso.
Isso basicamente retorna uma promessa. Espera-se que a resolução da promessa tenha o módulo. A proposta também possui outros recursos, 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 .
fonte
if (condition) { import('something') .then(({ somethingExported }) => { console.log(somethingExported); }); }
npm run build
, ainda recebo o erro:SyntaxError: ... 'import' and 'export' may only appear at the top level
Se desejar, você pode usar o exigir. Esta é uma maneira de ter uma instrução de requisição condicional.
fonte
require()
não faz parte do JavaScript padrão - é uma função interna do Node.js. Portanto, é útil apenas nesse ambiente. O OP não dá indicação de trabalho com Node.js.Você não pode importar condicionalmente, mas pode fazer o oposto: exportar algo condicionalmente. Depende do seu caso de uso, portanto, essa solução alternativa pode não ser para você.
Você pode fazer:
api.js
apiConsumer.js
Eu uso isso para simular bibliotecas de análise como mixpanel, etc ... porque não posso ter várias compilações ou nosso front-end atualmente. Não é o mais elegante, mas funciona. Eu só tenho alguns 'se' aqui e ali, dependendo do ambiente, porque no caso do mixpanel, ele precisa de inicialização.
fonte
Parece que a resposta é que, a partir de agora, você não pode.
http://exploringjs.com/es6/ch_modules.html#sec_module-loader-api
Penso que a intenção é permitir a análise estática, tanto quanto possível, e os módulos importados condicionalmente quebram isso. Também vale a pena mencionar - estou usando o Babel e acho que isso
System
não é suportado pelo Babel porque a API do carregador de módulos não se tornou um padrão ES6.fonte
require()
é uma maneira de importar algum módulo no tempo de execução e se qualifica igualmente para análise estática, comoimport
se usado com caminhos literais de cadeia de caracteres. Isso é requerido pelo bundler para escolher dependências para o bundle.Para resolução dinâmica de módulos com suporte completo à análise estática, primeiro indexe os módulos em um indexador (index.js) e importe o indexador no módulo host.
fonte
require()
não faz parte do JavaScript padrão - é uma função interna do Node.js. Portanto, é útil apenas nesse ambiente. O OP não dá indicação de trabalho com Node.js.Diferença importante se você usar o modo Webpack de importação dinâmica
eager
:fonte
import
retorna uma promessa.obscurecê-lo em uma avaliação funcionou para mim, escondendo-o do analisador estático ...
fonte
eval
aqui, @TormodHaugene?eval
não deve ser usado . Em geral: se você achar necessário usareval
, provavelmente está fazendo algo errado e deve dar um passo atrás para considerar suas alternativas. Provavelmente, existem alguns cenários em que o usoeval
está correto, mas você provavelmente não encontrou uma dessas situações.require()
não faz parte do JavaScript padrão - é uma função interna do Node.js. Portanto, é útil apenas nesse ambiente. O OP não dá indicação de trabalho com Node.js.Consegui fazer isso usando uma função imediatamente invocada e exigir instrução.
fonte
require()
não faz parte do JavaScript padrão - é uma função interna do Node.js. Portanto, é útil apenas nesse ambiente. O OP não dá indicação de trabalho com Node.js.As importações condicionais também poderiam ser alcançadas com um ternário
require()
es:const logger = DEBUG ? require('dev-logger') : require('logger');
Este exemplo foi retirado dos documentos de solicitação global do ES Lint: https://eslint.org/docs/rules/global-require
fonte
require()
não faz parte do JavaScript padrão - é uma função interna do Node.js. Portanto, é útil apenas nesse ambiente. O OP não dá indicação de trabalho com Node.js.Veja este exemplo para entender claramente como a importação dinâmica funciona.
Exemplo de importação de módulo dinâmico
Para ter um entendimento básico de importação e exportação de módulos.
Módulos JavaScript Github
Módulos Javascript MDN
fonte
Não, você não pode!
No entanto, ter esbarrado nessa questão deve fazer você repensar sobre como você organiza seu código.
Eu acho que uma das razões pelas quais eles abandonaram o suporte no ES6 em diante é o fato de que compilá-lo seria muito difícil ou impossível.
fonte