javascript - 在浏览器中执行(导入)带有 JavaScript 代码的字符串,该字符串导入 ES6 模块
问题描述
我正在制作一个动态系统,该系统需要执行在浏览器应用程序(Edge 或 Chrome 最新版本)中动态生成的 JS 代码。从另一个例子来看,我已经做到了这一点:
async function doIt()
{
let code = "";
code += "import { MyClass } from './MyClass.js' ;\n";
code += 'export default function hello() { console.log( "Hello World" ); console.log( MyClass.test() ); }';
const dataUri = 'data:text/javascript;charset=utf-8,' + encodeURIComponent(code);
let module = await import(dataUri);
console.log(module); // property default contains function hello now
const myHello = module.default;
myHello(); // puts "Hello World" to console
}
MyClass.js 有一个简单的 ES6 模块类:
export class MyClass {
static test() { return 42; }
}
当我在没有第二行的情况下使用 import 语句运行 doIt() 函数时,它运行良好,直到它尝试调用 MyClass.test() ,这当然是未知的。启用第二个导入行后,Edge 或 Chrome 会出现错误:
"Uncaught TypeError: Failed to resolve module specifier './MyClass.js'.
Invalid relative url or base scheme isn't hierarchical."
我试图制作模块引用的绝对路径,但错误仍然相同。. 那么,如何使这项工作?或者也许是替代解决方案?但是使用 ES6 模块是一个硬性要求。
解决方案
回答我自己的问题: import() 似乎有些残缺,但一种解决方法是将所需的动态 JavaScript 放在当前 HTML 页面中新的临时脚本节点的 innerHTML 中。从那里,ES6 import 语句就可以正常执行了:
var script = document.createElement( "script" );
script.setAttribute( 'type', 'module' );
script.innerHTML = 'import { MyClass } from "/App/MyClass.js"; \
someGlobalVar = MyClass.test();
由于它在全局范围内运行,因此您需要将结果存储在某个全局对象中。它可以通过在对象实例上实现回调函数来改进,但我把它留给读者作为练习。:-)
推荐阅读
- spring - Bean 验证 - 验证可选字段
- r - R:如何在方法中设置成员变量?
- java - 在 JavaFX 中将节点的形状和大小绑定到剪贴蒙版
- python - 在函数中使用全局变量而不将其显式传递给函数时是否可能会收到警告?
- c++ - 模块 (DLL) 的类大小不同。如何以及为什么?
- mysql - 相同的 ID 不同的值变成一行
- c# - 为什么我在mysql中的count命令返回错误的值-1?
- kubernetes - 在 Kubernetes 中实现 WebSocket 时出错
- javascript - 错误未知类型“webform__webform”使用 gatsby-drupal-webform & GraphQL
- spring-boot - Primefaces+SpringBoot大文件上传失败