39

3つのファイルのサンプルコードを次に示します。

// foo.js
var myFunc = require("./myFunc");
function foo(){
   myFunc("message");
}

// bar.js
var myFunc = require("./myFunc");
function bar(){
   myFunc("message");
}

// myFunc.js
module.exports = myFunc;
function myFunc(arg1){
   console.log(arg1);
   // Here I need the file path of the caller function
   // For example, "/path/to/foo.js" and "/path/to/bar.js"
}

の場合、追加の引数を渡さずに、呼び出し元関数のファイルパスを動的に取得する必要がありますmyFunc

4

6 に答える 6

45

の内部の仕組みをいじる必要がありv8ます。参照: JavaScript Stack Trace API に関する wiki エントリ

提案されたコミットのいくつかのコードに基づいて少しテストしましたが、うまくいくようです。絶対パスになってしまいます。

// omfg.js

module.exports = omfg

function omfg() {
  var caller = getCaller()
  console.log(caller.filename)
}

// private

function getCaller() {
  var stack = getStack()

  // Remove superfluous function calls on stack
  stack.shift() // getCaller --> getStack
  stack.shift() // omfg --> getCaller

  // Return caller's caller
  return stack[1].receiver
}

function getStack() {
  // Save original Error.prepareStackTrace
  var origPrepareStackTrace = Error.prepareStackTrace

  // Override with function that just returns `stack`
  Error.prepareStackTrace = function (_, stack) {
    return stack
  }

  // Create a new `Error`, which automatically gets `stack`
  var err = new Error()

  // Evaluate `err.stack`, which calls our new `Error.prepareStackTrace`
  var stack = err.stack

  // Restore original `Error.prepareStackTrace`
  Error.prepareStackTrace = origPrepareStackTrace

  // Remove superfluous function call on stack
  stack.shift() // getStack --> Error

  return stack
}

omfgモジュールを含むテスト:

#!/usr/bin/env node
// test.js

var omfg = require("./omfg")

omfg()

そして、コンソールに の絶対パスが表示されtest.jsます。


説明

これは「v8」の問題であるため、「node.js」の問題ではありません。

参照:カスタム例外のスタック トレース コレクション

Error.captureStackTrace(error, constructorOpt)errorパラメータにプロパティを追加しますstack。このプロパティは、デフォルトでString( を介してFormatStackTrace) に評価されます。Error.prepareStackTrace(error, structuredStackTrace)が の場合Function、 の代わりに呼び出されFormatStackTraceます。

Error.prepareStackTraceしたがって、必要なもの (この場合はパラメーターのみ) を返す独自の関数でオーバーライドできますstructuredStackTrace

次に、structuredStackTrace[1].receiver呼び出し元を表すオブジェクトです。

于 2012-11-05T07:32:44.893 に答える
40

または、V8 エンジンの内部動作をいじる代わりにmodule.parent.filename、モジュールを必要とするモジュールへの絶対パスを取得するために使用します。ここに示すように: https://gist.github.com/capaj/a9ba9d313b79f1dcd9a2

モジュールはキャッシュされることに注意してください。他のファイルがそれを必要として呼び出した場合、それは常に最初のインポーターへのパスになります。

于 2014-11-12T00:20:26.340 に答える