Javascript 如何在Duktape中使用多个js文件?

Javascript 如何在Duktape中使用多个js文件?,javascript,embedded,duktape,Javascript,Embedded,Duktape,我在嵌入式MCU中使用Duktape。对于测试用例,我有: main.js文件: (function(){ test(); })(); test.js文件: (function test(){ print("func"); }) 编译为全局默认代码和main.js都使用duk_调用(ctx,0)执行 问题是它在调用test()函数时抛出错误 我也试过使用just function test() { print("test"); } 在test.js代码中,但它也不起作

我在嵌入式MCU中使用Duktape。对于测试用例,我有: main.js文件:

(function(){
    test();
})();
test.js文件:

(function test(){
    print("func");
})
编译为全局默认代码和main.js都使用duk_调用(ctx,0)执行


问题是它在调用test()函数时抛出错误

我也试过使用just

function test() {
   print("test");
}
在test.js代码中,但它也不起作用

据我所知,这两个文件都有单独的执行上下文。这就是函数无法访问的原因

但是,对于Duktape,将代码拆分为多个文件的正确方法是什么

另外,我的目标是避免使用全局上下文,因为在文档中,这样访问变量很慢,这就是main.js看起来如此的原因

p.p.S.我确信test()函数是不可访问的,但我不知道如何编写js代码,以便一切正常


p.p.p.S print()是一个C函数,它输出到esp32的串行端口并工作。甚至main.js也可以在没有test()函数调用的情况下工作。

基本上,您需要的是文件导入功能。您可以通过两种方式实现这一点:

  • 在后端提供一个函数并将其导出到JS,以允许在运行时动态加载文件
  • 实现与Node.js类似的模块处理(本质上也可以归结为导入函数)
  • 第二个想法是最常用的方法,它实现了一种定义良好的方法来在JS应用程序中包含其他文件。Duktape附带了一个额外的文件,它实现了
    require
    命令,就像Node.js中一样。您只需要提供自己的函数来解析模块并从磁盘加载它(因为duktape不支持文件I/O)

    我在中实现了这种方法。用于实现节点模块处理的duktape文件是。解析模块的函数(包括处理嵌套的
    node_模块
    文件夹等)在类中实现。其相关部分如下:

    /**
    *模块装载机械的一部分。JS接口由duk_模块_节点代码完成。
    *但是我们必须在这里做文件工作。在堆栈上,我们将值作为“模块ID”传递给'require()',然后
    *调用脚本的ID(主脚本为空)。
    */
    duk_ret_t ScriptingContext::resolveModule(duk_context*ctx){
    //堆栈:[请求的\u id父\u id]
    std::string requestedID=duk_get_字符串(ctx,0);
    std::string callingID=duk_get_string(ctx,1);
    std::string parentPath=FS::isDir(callingID)?callingID:Path::dirname(callingID);
    //Node.js样式的模块解析策略:https://nodejs.org/api/modules.html#modules_all_together
    自动模块=getInternalModules();
    if(modules.find(requestedID)!=modules.end()){
    duk_push_字符串(ctx,requestedID.c_str());
    返回1;
    }
    ScriptingContext*context=ScriptingContext::fromDuktapeContext(ctx);
    std::字符串解析;
    std::string cwd=Process::cwd();
    试一试{
    if(路径::isAbsolute(requestedID)| |实用程序::hasPrefix(requestedID,“.”){
    std::字符串温度;
    if(路径::isAbsolute(requestedID)){
    temp=Path::relative(cwd,requestedID);
    }否则
    temp=Path::join({parentPath,requestedID});
    resolvedID=resolveFile(临时);
    if(resolvedID.empty())
    resolvedID=resolveFolder(上下文,临时);
    }
    }捕获(标准::运行时错误&e){
    //已为package.json中的分析错误触发。
    context->throwScriptingError(ScriptingError::Syntax,例如what());
    返回0;
    }
    //到目前为止未找到任何文件。请检查节点模块。
    if(resolvedID.empty()){
    用于(自动文件夹:模块文件夹(父路径)(&F)){
    std::string path=path::join({folder,requestedID});
    std::string temp=resolveFile(路径);
    如果(!temp.empty()){
    resolvedID=温度;
    打破
    }
    temp=resolveFolder(上下文、路径);
    如果(!temp.empty()){
    resolvedID=温度;
    打破
    }
    }
    }
    if(resolvedID.empty()){
    context->throwScriptingError(ScriptingError::Error,Utilities::format(“无法解析模块%s”,requestedID.c_str());
    返回0;
    }
    duk_push_字符串(ctx,resolvedID.c_str());
    返回1;//在堆栈上使用结果。
    }
    
    “调用test()函数时会抛出错误。”很高兴听到这个消息,但它会给出什么错误?您甚至想通过调用
    print
    来实现什么?它是一个嵌入式设备,因此没有终端,除非你把它放进去。我有c函数的打印功能,它可以工作。我不知道它会产生什么错误,我还不能很流利地调试duktape。但这是运行时错误,在函数调用完成时会发生,因为如果在函数调用之前再打印一次,它会在终端输出字符串。我确信这个函数是不可访问的,我想问的是如何正确地编写js代码,所以它是可访问的。现在最重要的问题是,您是否已经嵌入了duck?如果不这样说,您的问题会有很大变化。它是运行在esp32上的嵌入式duktape,并将函数输出打印到串行端口和wirks Fine。感谢您的详细解释。我在考虑模块,但希望它能更容易地完成。再次感谢!