亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將多個js文件與Duktape一起使用?

如何將多個js文件與Duktape一起使用?

慕斯709654 2022-09-02 21:03:05
我在嵌入式MCU中使用Duktape。對于測試用例,我有:主.js文件:(function(){    test();})();測試.js文件:(function test(){    print("func");})編譯為全局默認代碼和主.js都使用duk_call(ctx, 0)執行;問題是它在調用 test() 函數時會引發錯誤。我也嘗試過使用function test() {   print("test");}在 test.js代碼,但它也不起作用。我的理解是,這兩個文件都有單獨的執行上下文。這就是為什么功能無法訪問的原因。但是,將Duktape的代碼拆分為多個文件的正確方法是什么?附言:我的目標是避免使用全局上下文,因為在文檔中,據說以這種方式訪問變量很慢,這就是為什么main.js看起來那樣的原因。附言我確信test()函數是無法訪問的,但我不知道如何編寫js代碼以便一切正常。P.P.P.S print() 是一個 C 函數,輸出到 esp32 的串行端口,它可以工作。甚至 main.js 在沒有 test() 函數調用的情況下工作。
查看完整描述

1 回答

?
德瑪西亞99

TA貢獻1770條經驗 獲得超3個贊

基本上,您想要的是文件導入功能。您可以通過兩種方式實現它:

  1. 在后端提供一個函數并將其導出到 JS,以允許在運行時動態加載文件。

  2. 實現像Node.js這樣的模塊處理(本質上也歸結為導入函數)。

第二個想法是最常用的方法,并實現了一種定義良好的方法,以在JS應用程序中包含其他文件。Duktape附帶了一個額外的文件來實現該命令,就像在Node.js中一樣。您只需要提供自己的函數來解析模塊并從磁盤加載它(因為 duktape 沒有文件 I/O 支持)。require

我在MySQL Workbench的MGA工具中實現了這種方法。用于實現節點模塊處理的 duktape 文件在這里。解析模塊的函數(包括處理嵌套文件夾等)在 ScriptingContext 類中實現。它的相關部分是這樣的:node_modules

/**

 * Part of the module loading machinery. JS interfacing is done by the duk_module_node code.

 * But we have to do the file work here. On the stack we get the value passed to `require()` as a "module ID" and

 * the ID of the calling script (which is empty for the main script).

 */

duk_ret_t ScriptingContext::resolveModule(duk_context *ctx) {

  // stack: [ requested_id parent_id ]

  std::string requestedID = duk_get_string(ctx, 0);

  std::string callingID = duk_get_string(ctx, 1);

  std::string parentPath = FS::isDir(callingID) ? callingID : Path::dirname(callingID);


  // Module resolution strategy in Node.js style: https://nodejs.org/api/modules.html#modules_all_together

  auto modules = getInternalModules();

  if (modules.find(requestedID) != modules.end()) {

    duk_push_string(ctx, requestedID.c_str());

    return 1;

  }


  ScriptingContext *context = ScriptingContext::fromDuktapeContext(ctx);

  std::string resolvedID;

  std::string cwd = Process::cwd();


  try {

    if (Path::isAbsolute(requestedID) || Utilities::hasPrefix(requestedID, ".")) {

      std::string temp;

      if (Path::isAbsolute(requestedID)) {

        temp = Path::relative(cwd, requestedID);

      } else

        temp = Path::join({ parentPath, requestedID });


      resolvedID = resolveFile(temp);

      if (resolvedID.empty())

        resolvedID = resolveFolder(context, temp);

    }

  } catch (std::runtime_error &e) {

    // Triggered for parse errors in package.json.

    context->throwScriptingError(ScriptingError::Syntax, e.what());

    return 0;

  }


  // No files found so far. Check node modules.

  if (resolvedID.empty()) {

    for (auto &folder : moduleFolders(parentPath)) {

      std::string path = Path::join({ folder, requestedID });

      std::string temp = resolveFile(path);

      if (!temp.empty()) {

        resolvedID = temp;

        break;

      }


      temp = resolveFolder(context, path);

      if (!temp.empty()) {

        resolvedID = temp;

        break;

      }

    }

  }


  if (resolvedID.empty()) {

    context->throwScriptingError(ScriptingError::Error, Utilities::format("Cannot resolve module %s", requestedID.c_str()));

    return 0;

  }


  duk_push_string(ctx, resolvedID.c_str());

  return 1;  // Use result on stack.

}


查看完整回答
反對 回復 2022-09-02
  • 1 回答
  • 0 關注
  • 177 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號