Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Node.jsで関数の呼び出し元のファイル名を取得する

More than 1 year has passed since last update.

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番目は列数です。

さいごに

サードパーティーのパッケージに依存せずに書けたのが嬉しかったです。参考になりましたら幸いです。

segur
Unity認定プログラマー。VR学会認定技術者。xRエンジニア。ガジェットが大好きなギーク。 色んなコンピュータ言語に触れるのが好き。
https://segurvita.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away