Node.jsで関数の呼び出し元のファイル名を取得する
ログ出力とかで、呼び出し元のJavaScriptファイルのファイル名を取得したいという場面があります。
以下のコードで、関数 hogehoge()
を呼び出したJavaScriptファイルのファイル名が取得できます。
import path from 'path';
const hogehoge = () => {
// 呼び出し元のファイル名を取得
const caller = path.basename(new Error().stack.split('at ')[2].trim()).split(':')[0];
// 標準出力
console.log(caller);
}
解説
細かく分割して書くとこんな感じです。
import path from 'path'; // Node.js Path Module
const hogehoge = () => {
// 呼び出し元のファイル名を取得
const stack = new Error().stack; // (1) スタックトレースを取得
const lines = stack.split('at '); // (2) atで分割し、配列を取得
const line = lines[2]; // (3) 配列の2番目を取得
const trimed = line.trim(); // (4) 前後の空白・改行を削除
const basename = path.basename(trimed); // (5) ディレクトリパスを削除
const splited = basename.split(':'); // (6) :で分割し、配列を取得
const caller = splited[0]; // (7) 配列の0番目を取得
// 標準出力
console.log(caller);
}
(1) スタックトレースを取得
スタックトレースというのは、どの関数から呼ばれてきたかの履歴です。
以下のような文字列になっています。
Error
at hogehoge (file:///src/app/lib/hogehoge.js:10:15)
at foo (file:///src/app/lib/foo.js:20:10)
at bar (file:///src/app/lib/bar.js:30:20)
この場合、 hogehoge
を呼んだのは、 foo
で、 foo
を呼んだのは bar
ということがわかります。
今回はこの foo.js
という文字列を抽出するのが目的です。
new Error().stack
でこの文字列を取得できます。
以下を参考にしました。
How to print a stack trace in Node.js?
(2)(3)(4) atで分割し2番目を取得
atで分割すると、
- 0番目:
Error
- 1番目:
hogehoge (file:///src/app/lib/hogehoge.js:10:15)
- 2番目:
foo (file:///src/app/lib/foo.js:20:10)
となります。この2番目を取得し、余計な改行や空白を削除します。
以下を参考にしました。
Get name and line of calling function in node.js
(5) ディレクトリパスを削除
path.basename()
を利用すると、一番最後に登場する /
より右側の文字列を抽出できます。これにより、
foo (file:///src/app/lib/foo.js:20:10)
が
foo.js:20:10)
になります。
(6)(7) :
で分割し0番目を取得
:
で分割すると、
- 0番目:
foo.js
- 1番目:
20
- 2番目:
10)
となります。この0番目を取得すれば、これが呼び出し元のファイル名です。
ちなみに、1番目は行数で、2番目は列数です。
さいごに
サードパーティーのパッケージに依存せずに書けたのが嬉しかったです。参考になりましたら幸いです。