Búsqueda de sitios web

javascript - Importar un módulo desde una variable de cadena


Necesito importar un módulo de JavaScript desde una variable en memoria. Sé que esto se puede hacer usando SystemJS y Webpack.

Pero en ningún lugar puedo encontrar un buen ejemplo funcional ni documentación sobre lo mismo. Las documentaciones mayormente hablan de la importación dinámica de archivos .js.

Básicamente necesito importar el módulo como se muestra a continuación

let moduleData = "export function doSomething(string) { return string + '-done'; };"
//Need code to import that moduleData into memory

Si alguien puede señalar documentación, eso sería genial

Respuesta #1

Existen limitaciones en la sintaxis import que hacen que sea difícil o incluso imposible hacerlo sin usar bibliotecas externas.

Lo más cerca que pude llegar es usando la sintaxis de Importación Dinámica. Siguen dos ejemplos: el primero es el original que escribí mientras que el segundo es una edición de un usuario que quería modernizarlo.

El original:

<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<script>
    var moduleData = "export function hello() { alert('hello'); };";
    var b64moduleData = "data:text/javascript;base64," + btoa(moduleData);
    
</script>
<script type="module">

    async function doimport() {
      const module = await import(b64moduleData);
      module.hello();
    }
    
    doimport();

</script>

</body>
</html>

El modernizado:

function doimport (str) {
  if (globalThis.URL.createObjectURL) {
    const blob = new Blob([str], { type: 'text/javascript' })
    const url = URL.createObjectURL(blob)
    const module = import(url)
    URL.revokeObjectURL(url) // GC objectURLs
    return module
  }
  
  const url = "data:text/javascript;base64," + btoa(moduleData)
  return import(url)
}

var moduleData = "export function hello() { console.log('hello') }"
var blob = new Blob(["export function hello() { console.log('world') }"])

doimport(moduleData).then(mod => mod.hello())

// Works with ArrayBuffers, TypedArrays, DataViews, Blob/Files 
// and strings too, that If URL.createObjectURL is supported.
doimport(blob).then(mod => mod.hello())

Sin embargo, notarás que esto tiene algunas limitaciones en la forma en que se construye el código de importación, lo que puede no coincidir exactamente con lo que necesitas. La solución más simple probablemente sea enviar el código del módulo al servidor para que genere un script temporal que luego pueda ser importado utilizando una sintaxis más convencional.

Respuesta #2

let moduleData = await import("data:text/javascript,export function doSomething(str) { return str + '-done'; }");

y probarlo

moduleData.doSomething('test');

Artículos relacionados