Javascript 从字符串变量导入模块
我需要从内存中的变量导入一个JavaScript模块。 我知道这可以通过SystemJS和Webpack实现 但是,我找不到一个好的工作示例,也找不到相关文档。这些文档主要讨论.js文件的动态导入 基本上我需要像下面这样导入模块Javascript 从字符串变量导入模块,javascript,angular,typescript,webpack,systemjs,Javascript,Angular,Typescript,Webpack,Systemjs,我需要从内存中的变量导入一个JavaScript模块。 我知道这可以通过SystemJS和Webpack实现 但是,我找不到一个好的工作示例,也找不到相关文档。这些文档主要讨论.js文件的动态导入 基本上我需要像下面这样导入模块 let moduleData = "export function doSomething(string) { return string + '-done'; };" //Need code to import that moduleData into memory
let moduleData = "export function doSomething(string) { return string + '-done'; };"
//Need code to import that moduleData into memory
如果任何人都能找到很棒的文档使用nodejs flag--实验模块来使用导入。。。来自代码>
节点——实验模块索引.mjs
索引.mjs:
从“fs”导入fs;
let fileContents=“导出函数doSomething(string){return string+'-done';};”
让tempFileName='./._temporaryFile.mjs';
fs.writeFileSync(临时文件名,文件内容);
log('创建了临时mjs文件!');
导入(临时文件名)
.then((loadedModule)=>loadedModule.doSomething('It Works!'))
.then(console.log)
进一步阅读
工作原理:
我首先使用fs.writeFileSync
然后我使用import方法的promise加载模块和
管道doSomething方法调用,并带有“It Works!”
然后记录剂量测量的结果
学分:,@Louis
从“./myModule.js”导入{myfun};
myfun();
/*myModule.js*/
导出函数myfun(){
log('这是我的模块函数');
}
您可以动态创建组件和模块。但不是从字符串。以下是一个例子:
name = "Dynamic Module on Fly";
const tmpCmp = Component({
template:
'<span (click)="doSomething()" >generated on the fly: {{name}}</span>'
})(
class {
doSomething(string) {
console.log("log from function call");
return string + "-done";
}
}
);
const tmpModule = NgModule({ declarations: [tmpCmp] })(class {});
this._compiler.compileModuleAndAllComponentsAsync(tmpModule).then(factories => {
const f = factories.componentFactories[0];
const cmpRef = this.container.createComponent(f);
cmpRef.instance.name = "dynamic";
});
name=“动态模块动态”;
常量tmpCmp=组件({
模板:
'动态生成:{{name}}'
})(
阶级{
doSomething(字符串){
log(“来自函数调用的日志”);
返回字符串+“-done”;
}
}
);
const tmpModule=NgModule({声明:[tmpCmp]})(类{});
此.u compiler.compileemoduleandallcomponentsasync(tmpModule).then(factories=>{
常数f=工厂。组件工厂[0];
const cmpRef=this.container.createComponent(f);
cmpRef.instance.name=“动态”;
});
以下是导入
语法中存在一些限制,如果不使用外部库,很难做到这一点
我能得到的最接近的方法是使用语法。例如:
<!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>
页面标题
var moduleData=“导出函数hello(){alert('hello');};”;
var b64moduleData=“数据:text/javascript;base64,”+btoa(moduleData);
异步函数doimport(){
常量模块=等待导入(b64moduleData);
module.hello();
}
doimport();
但是,您会注意到,这对导入代码的构造方式有一些限制,这可能与您需要的不完全匹配。
最简单的解决方案可能是在服务器上发送模块的代码,以便生成一个临时脚本,然后使用更传统的语法导入。
eval
是您的解决方案,但不建议使用它。阅读更多关于它的信息,这里eval=evil反对“eval=evil”在处理执行模块代码时不是一个好的反对意见。SystemJS、Webpack、RequireJS和我使用过的任何其他JS模块加载程序的默认操作模式是以与执行eval
完全相同的权限运行代码。换句话说,require(“foo”)
并不比获取模块的源代码foo
然后对其进行eval
更安全。一些模块加载程序甚至将eval(sourceOfModule)
作为模块加载过程的一部分。也就是说,eval
无法处理OP的export
语句,因此不足以满足OP的要求。编辑后,这个答案仍然没有达到目的。搜索“es6动态导入”。静态导入可以被提升,但动态导入不被提升。我认为动态导入的实现不允许传递到import()
调用模块的源代码,但可能有一个SystemJS插件或Webpack允许它。即使这样的插件目前不存在,我相信可以开发一个。我不会把OP想要做的事情称为“不可能”。@Louis是的,你是对的。我通过谷歌搜索这条消息得到了答案。我将包括来源以及。非常感谢。你的工具链中已经有巴贝尔了吗?如果是这样的话,我想你已经有了一些可以配置插件的地方。现在,我没有找到任何适合你需要的插件。但是使用babel generator来解析和生成代码(),你可以编写自己的插件。多年来,我一直在JavaScript中使用模块加载器和模块绑定器,并为相关项目做出了贡献,但从未遇到过需要将字符串作为模块导入解决方案的问题。有些情况下,我可以通过这样做来解决我的问题,但有更好的解决方案。但是,按照目前编写问题的方式,我们不知道XY问题的X部分。为什么必须从包含模块源的字符串导入模块?我同意@Louis。这是一个非常奇怪的问题,解释为什么你需要这样做肯定会帮助你找到一个解决方案。基本上,我们有一个Angular应用程序,让用户创建Angular组件,包括HTML模板、TS文件和CSS。一旦他们输入这些,我们就需要在同一个Angular应用程序中编译和加载它们。我们已经解决了如何将HTML TS和CSS合并并编译成JS模块,现在加载部分已经完成,如果您需要完全在浏览器中完成这项工作(正如您在回答中的评论所指出的),我认为这是不可能的。请记住,运行任意代码也是非常危险的。行不通我们让用户也在Fly上创建模块基本上我们有一个Angular应用程序,其中
<!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>