Condicional
¿Es posible tener declaraciones de importación condicionales como a continuación?
if (foo === bar) {
import Baz from './Baz';
}
He intentado lo anterior pero obtengo el siguiente error (de Babel) al compilar.
'import' and 'export' may only appear at the top level
Dinámica
¿Es posible tener declaraciones de importación dinámicas como las siguientes?
for (let foo in bar) {
if (bar.hasOwnProperty(foo)) {
import Baz from `./${foo}`;
}
}
Lo anterior recibe el mismo error de Babel durante la compilación.
¿Es posible hacer esto o hay algo que me falta?
Razonamiento
La razón por la que intento hacer esto es que tengo muchas importaciones para varias "páginas" y siguen un patrón similar. Me gustaría limpiar mi base de código importando estos archivos con un bucle for dinámico.
Si esto no es posible, ¿existe una mejor manera de manejar una gran cantidad de importaciones en ES6?
javascript
ecmascript-6
Enijar
fuente
fuente
super
para llamar específico.Respuestas:
Tenemos propuesta de importaciones dinámicas ahora con ECMA. Esto se encuentra en la etapa 2. También está disponible como babel-preset .
La siguiente es una forma de hacer una representación condicional según su caso.
if (foo === bar) { import('./Baz') .then((Baz) => { console.log(Baz.Baz); }); }
Esto básicamente devuelve una promesa. Se espera que la resolución de la promesa tenga el módulo. La propuesta también tiene cosas como múltiples importaciones dinámicas, importaciones predeterminadas, importación de archivos js, etc. Puede encontrar más información sobre importaciones dinámicas aquí .
fuente
No puede resolver dinámicamente sus dependencias, ya que
imports
están diseñadas para el análisis estático. Sin embargo, probablemente pueda usar algunosrequire
aquí, algo como:for (let foo in bar) { if (bar.hasOwnProperty(foo)) { const Baz = require(foo).Baz; } }
fuente
import
Los s están diseñados para importar, no para análisis.import
declaraciones están destinadas a ser adecuadas para el análisis estático, porque nunca son condicionales, las herramientas pueden analizar los árboles de dependencia más fácilmente.Como esta pregunta tiene una alta calificación de Google, vale la pena señalar que las cosas han cambiado desde que se publicaron las respuestas anteriores.
MDN tiene esta entrada en Importaciones dinámicas :
Se puede encontrar un artículo útil sobre el tema en Medium .
fuente
Require no resolverá su problema, ya que es una llamada sincrónica. Hay varias opciones y todas involucran
En ECMA Script hay soporte para módulos de carga diferida usando SystemJS. Por supuesto, esto no es compatible con todos los navegadores, por lo que, mientras tanto, puede usar JSPM o un shim SystemJS.
https://github.com/ModuleLoader/es6-module-loader
fuente
Desde 2016 han pasado muchas cosas en el mundo de JavaScript, por lo que creo que es hora de ofrecer la información más actualizada sobre este tema. Actualmente, las importaciones dinámicas son una realidad tanto en Node como en los navegadores (de forma nativa si no le importa IE, o con @ babel / plugin-syntax-dynamic-import si le importa).
Por lo tanto, considere un módulo de muestra
something.js
con dos exportaciones con nombre y una exportación predeterminada:export const hi = (name) => console.log(`Hi, ${name}!`) export const bye = (name) => console.log(`Bye, ${name}!`) export default () => console.log('Hello World!')
Podemos usar la
import()
sintaxis para cargarlo condicionalmente de manera fácil y limpia: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 }) }
Pero como el retorno es a
Promise
, el azúcar sintácticoasync
/await
también es posible:async imAsyncFunction () { if (somethingIsTrue) { const module = await import('./something.js') module.hi('Erick') } }
¡Ahora piense en las posibilidades junto con la asignación de destrucción de objetos ! Por ejemplo, podemos poner fácilmente solo una de esas exportaciones nombradas en la memoria para uso posterior:
const { bye } = await import('./something.js') bye('Erick')
O tal vez tome una de esas exportaciones con nombre y cámbiele el nombre a cualquier otra cosa que deseemos:
const { hi: hello } = await import('./something.js') hello('Erick')
O incluso cambie el nombre de la función exportada predeterminada a algo que tenga más sentido:
const { default: helloWorld } = await import('./something.js') helloWorld()
Solo una última (pero no menos importante) nota:
import()
puede parecer una llamada de función, pero no es unaFunction
. Es una sintaxis especial que simplemente usa paréntesis (similar a lo que sucede consuper()
). Entonces no es posible asignarimport
a una variable o usar cosas delFunction
prototipo, comocall
/apply
.fuente