Importación dinámica y bajo demanda de Webpack 4

4

¿Es posible con webpack realizar una importación bajo demanda Y con un nombre dinámico? Por ejemplo, si tengo un fragmento de código

./src/index.js

function start() {
  const files = ['./foo.js'];
  const s = import(files[0]);
  console.log(new s());
}

document.getElementById('button').onclick = start;

./src/foo.js

export class Foo {}

index.html

<body>
  <button id="button">Click</button>
  <script type="text/javascript" src="index.js"></script>
  <script type="text/javascript" src="foo.js"></script>
</body>

webpack.config.js

module.exports = {
  entry: {
    index: './src/index.js',
    foo: './src/foo.js'
  }
}

Cuando ejecuto este código, después de hacer clic en mi botón, aparece el siguiente error

Uncaught (in promise) Error: Cannot find module './foo.js' at eval (eval at ./src lazy recursive (index.js:96), :5:11) (anonymous) @ src lazy namespace object?4252:5 Promise.then (async) start @ index.js?b635:4

También probé con const files = ['./src/foo.js'];pero lo mismo.

La pregunta es, ¿es posible lograr esta importación dinámica bajo demanda con webpack 4?

0

Se llama "División de código con contexto dinámico" . La forma en que la importación va a funcionar con el paquete web es que, estos fragmentos requeridos a pedido se "cargarán automáticamente" mediante el paquete web a pedido, solo cuando sea necesario.

El punto es, como @Batista ha señalado, esta importación tiene como resultado una promesa, que está envuelta en una propiedad predeterminada, por lo que podría:

async function start() {
  const files = ['./foo.js'];
  const s = await import(files[0]);
  console.log(new s.default());
}

Al hacer esto, no necesita agregar esto a los puntos de entrada, la única advertencia es que no genera un paquete con un nombre "fijo", para generar nombres, puede agregar:

...
import(/* webpackChunkName: "mychunk" */ files[0])
...

No es necesario que los agregue manualmente a su paquete web, estos se cargarán mediante el paquete web.

1
  • Tampoco funciona, el mismo error que el anterior. Sin embargo, encontré la solución, puedes consultar mi respuesta a continuación @ matheus-silva 18 de julio de 2018 a las 8:53
0

La solución fue usar import(`${files[0}`)con el signo inverso (sintaxis literal de plantilla). El uso import(files[0])no funciona, aunque files[0]sea ​​una cadena.

Sin embargo, no estoy seguro de por qué, si alguien es la respuesta.

0
-1

¿Ha intentado utilizar la promesa en su lugar?

import("module/foo").then(foo => console.log(foo.default))
1
  • el nombre dentro de importproviene de una variable import(files[0]). Por supuesto que si lo hago import('./foo'), funciona, pero aquí esto no es lo que quiero. 17 de julio de 2018 a las 16:02