我正在制作一个动态系统,需要在浏览器应用程序(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; }
}
当我运行doIt()函数没有第二行import语句时,它运行良好,直到它试图调用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();
由于它在全局范围内运行,因此需要将结果存储在某个全局对象中。它可以通过在对象实例上实现回调函数来改进,但我将其作为练习留给读者。: -)