gpt4 book ai didi

javascript - 如何动态执行/评估包含 ES6 模块/需要某些依赖项的 JavaScript 代码?

转载 作者:数据小太阳 更新时间:2023-10-29 05:28:23 25 4
gpt4 key购买 nike

我希望我的用户能够在我的 JavaScript 应用程序中使用 JavaScript 作为脚本语言。为此,我需要动态执行源代码。

动态执行 JavaScript 似乎有两个主要选项:

a) 使用 eval(...)方法(或 var func = new Function(...);)。

b) 添加 <script>节点到 DOM(例如使用 $('body').append(...) )。

只要我不使用任何 import,这两种方法都可以正常工作动态执行的源代码中的语句。如果我包括 import语句我收到错误消息 Unexpected identifier .

要执行的示例用户源代码:

import Atom from './src/core.atom.js':

window.createTreeModel = function(){
var root = new Atom('root');
root.createChildAtom('child');
return root;
}

示例应用程序代码来说明该动态代码的可能用法:

a) 使用评估

var sourceCode =  editor.getText(); 
window.createTreeModel = undefined;
eval(sourceCode);
var model = window.createTreeModel();
treeView.setModel(model);

b) 使用 DOM 修改:

var sourceCode =  editor.getText(); 
window.createTreeModel = undefined;

var script = "<script >\n"+
sourceCode + "\n" +
"</script>";

$('body').append(script);

var model = window.createTreeModel();
treeView.setModel(model);

如果我没有指定脚本类型或使用 type="application/javascript"对于选项 b),我得到 Unexpected identifier错误。如果我使用 type="module"我没有错误。脚本标签成功添加到DOM,但是模块代码没有执行。

我首先想到这可能是由于异步加载造成的。然而,等到脚本标签加载完成对 type='module' 不起作用。 .加载机制与 type="application/javascript" 一起工作但是然后……又……import不起作用。

加载脚本标签后异步执行的示例代码:

function loadScript(sourceCode, callback){
// Adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'application/javascript';
script.innerHTML = sourceCode;
//script.async=false;

// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;

// Fire the loading
head.appendChild(script);
}

--

loadScript(sourceCode, function(){
var model = window.createModel();
console.log('model:' + model);
});

如果我使用 <source type="module"> 在我的 index.html 中硬编码用户源代码,模块代码被执行。动态加载模块代码似乎不起作用。我使用 Chrome 版本 63.0.3239.108。

=> I. 如何强制执行 <script type="module">动态添加到 DOM 后的标签?或

=> 二。我如何评估包含 import 的脚本(也许还有导出)声明?或

=> 三。允许用户源代码定义可以动态解析的依赖项的好方法是什么?

相关问题和文章:

补充说明:

我知道示例的工作流程,使用 window.createTreeModel不理想。我在这里使用它是因为代码很容易理解。在我以某种方式设法运行用户源代码(包括其依赖项)之后,我将改进我的所有工作流程并考虑诸如安全问题之类的事情。

最佳答案

使用数据 uris 或 objectUrls 和动态导入:

数据URI:

const code = 'export default function hello() { console.log("Hello World"); }';
const dataUri = 'data:text/javascript;charset=utf-8,' + encodeURIComponent(code);
const module = await import(dataUri);
console.log(module); // property default contains function hello now
const myHello = module.default;
myHello(); // puts "Hello World" to console

对象网址:

const code = 'export default function hello() { console.log("Hello World"); }';
const objectURL = URL.createObjectURL(new Blob([code], { type: 'text/javascript' }));
const module = await import(objectURL);
console.log(module); // property default contains function hello now
const myHello = module.default;
myHello(); // puts "Hello World" to console

导入在我的测试中有效,如果你使用相对路径,你可能必须更改目录更改前缀(如 ./或 ../),但由于你必须首先编码为文本,你可以替换它在模拟之前使用正则表达式。

关于javascript - 如何动态执行/评估包含 ES6 模块/需要某些依赖项的 JavaScript 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47978809/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com