How to Get the Caller's Filename in Node.js

This article is a translated version of my original post on Qiita. Original (Japanese): https://qiita.com/segur/items/aba1e38d200d62fd551f

How to Get the Caller's Filename in Node.js

There are situations — such as logging — where you want to know the name of the JavaScript file that called a function.

The following code retrieves the filename of the JavaScript file that called hogehoge():

import path from 'path';

const hogehoge = () => {
  // Get the caller's filename
  const caller = path.basename(new Error().stack.split('at ')[2].trim()).split(':')[0];

  // Print to stdout
  console.log(caller);
}

Explanation

Here's the same code broken down step by step:

import path from 'path';  // Node.js Path Module

const hogehoge = () => {
  // Get the caller's filename
  const stack = new Error().stack;        // (1) Get the stack trace
  const lines = stack.split('at ');       // (2) Split by 'at' to get an array
  const line = lines[2];                  // (3) Take the 3rd element (index 2)
  const trimed = line.trim();             // (4) Remove leading/trailing whitespace and newlines
  const basename = path.basename(trimed); // (5) Strip the directory path
  const splited = basename.split(':');    // (6) Split by ':' to get an array
  const caller = splited[0];              // (7) Take the first element (index 0)

  // Print to stdout
  console.log(caller);
}

(1) Get the Stack Trace

The stack trace is a history of which functions called which. It looks like this:

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)

This tells us that hogehoge was called by foo, and foo was called by bar. Our goal is to extract the string foo.js.

new Error().stack retrieves this string.

Reference: How to print a stack trace in Node.js?

(2)(3)(4) Split by 'at' and Take the 3rd Element

Splitting by at gives:

We take index 2 and strip the surrounding whitespace and newlines.

Reference: Get name and line of calling function in node.js

(5) Strip the Directory Path

path.basename() extracts everything after the last /, so:

foo (file:///src/app/lib/foo.js:20:10)

becomes:

foo.js:20:10)

(6)(7) Split by : and Take the First Element

Splitting by : gives:

Index 0 is the caller's filename. Index 1 is the line number, and index 2 is the column number.

Closing

I was happy to accomplish this without relying on any third-party packages. Hope it's useful!