Condicional
É possível ter instruções de importação condicionais como a seguir?
if (foo === bar) {
import Baz from './Baz';
}
Tentei o procedimento acima, mas recebo o seguinte erro (de Babel) ao compilar.
'import' and 'export' may only appear at the top level
Dinâmico
É possível ter instruções de importação dinâmicas como a seguir?
for (let foo in bar) {
if (bar.hasOwnProperty(foo)) {
import Baz from `./${foo}`;
}
}
O exemplo acima recebe o mesmo erro do Babel durante a compilação.
Isso é possível fazer ou há algo que estou perdendo?
Raciocínio
Estou tentando fazer isso porque tenho muitas importações de várias "páginas" e elas seguem um padrão semelhante. Eu gostaria de limpar minha base de código importando esses arquivos com um loop for dinâmico.
Se isso não for possível, existe uma maneira melhor de lidar com um grande número de importações no ES6?
javascript
ecmascript-6
Enijar
fonte
fonte
super
para chamar específico.Respostas:
Temos uma proposta de importação dinâmica agora com ECMA. Isso está no estágio 2. Isso também está disponível como predefinição de babel .
A seguir está uma maneira de fazer a renderização condicional de acordo com o seu caso.
if (foo === bar) { import('./Baz') .then((Baz) => { console.log(Baz.Baz); }); }
Isso basicamente retorna uma promessa. Espera-se que a resolução da promessa tenha o módulo. A proposta também tem coisas como várias importações dinâmicas, importações padrão, importação de arquivo js etc. Você pode encontrar mais informações sobre importações dinâmicas aqui .
fonte
Você não pode resolver dinamicamente suas dependências, pois
imports
são destinadas à análise estática. No entanto, você provavelmente pode usar algunsrequire
aqui, algo como:for (let foo in bar) { if (bar.hasOwnProperty(foo)) { const Baz = require(foo).Baz; } }
fonte
import
s são projetados para importação, não para análise.import
instruções devem ser adequadas para análise estática - porque nunca são condicionais, as ferramentas podem analisar as árvores de dependência mais facilmente.Como essa questão é bem avaliada pelo Google, vale ressaltar que as coisas mudaram desde que as respostas mais antigas foram postadas.
MDN tem esta entrada em Importações dinâmicas :
Um artigo útil sobre o assunto pode ser encontrado no Medium .
fonte
Desde 2016 muito se passou no mundo do JavaScript, então acredito que é hora de oferecer as informações mais atualizadas sobre esse assunto. Atualmente, as importações dinâmicas são uma realidade tanto no Node quanto nos navegadores (nativamente, se você não se importa com o IE, ou com @ babel / plugin-syntax-dynamic-import se você se importa).
Portanto, considere um módulo de amostra
something.js
com duas exportações nomeadas e uma exportação padrão:export const hi = (name) => console.log(`Hi, ${name}!`) export const bye = (name) => console.log(`Bye, ${name}!`) export default () => console.log('Hello World!')
Podemos usar a
import()
sintaxe para carregá-lo de forma fácil e limpa condicionalmente: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 }) }
Mas como o retorno é um
Promise
, o açúcar sintáticoasync
/await
também é possível:async imAsyncFunction () { if (somethingIsTrue) { const module = await import('./something.js') module.hi('Erick') } }
Agora pense nas possibilidades junto com a Atribuição de Destruturação de Objetos ! Por exemplo, podemos facilmente colocar apenas uma dessas exportações nomeadas na memória para uso posterior:
const { bye } = await import('./something.js') bye('Erick')
Ou talvez pegue uma das exportações nomeadas e renomeie para qualquer outra coisa que quisermos:
const { hi: hello } = await import('./something.js') hello('Erick')
Ou até mesmo renomeie a função exportada padrão para algo que faça mais sentido:
const { default: helloWorld } = await import('./something.js') helloWorld()
Apenas uma última (mas não menos importante) observação:
import()
pode parecer uma chamada de função, mas não é umFunction
. É uma sintaxe especial que usa parênteses (semelhante ao que acontece comsuper()
). Portanto, não é possível atribuirimport
a uma variável ou usar coisas doFunction
protótipo, comocall
/apply
.fonte
Require não resolverá seu problema, pois é uma chamada síncrona. Existem várias opções e todas envolvem
No script ECMA, há suporte para módulos de carregamento lento usando SystemJS. É claro que isso não é compatível com todos os navegadores, portanto, enquanto isso, você pode usar JSPM ou um shim SystemJS.
https://github.com/ModuleLoader/es6-module-loader
fonte