172

How to get current file name, function name and line number?

I want to use it for logging/debugging purpose, equivalent to __FILE__, __LINE__ in c

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
Raxit Sheth
  • 2,491
  • 5
  • 17
  • 20

9 Answers9

305

Node.js provides a standard API to do so: Path.

Getting the name of the current script is then easy:

var path = require('path');
var scriptName = path.basename(__filename);
herve
  • 3,825
  • 2
  • 18
  • 27
  • Doesn't this get the basename rather than the actual filename? – Phil May 11 '17 at 07:30
  • 16
    for a script named `script.js`, you'll get `script.js`. If you want to have the name only without extension, as we are speaking here of a `js` script you can use `var scriptName = path.basename(__filename, '.js');` or `var scriptName = path.basename(__filename, path.extname(__filename))` – herve May 12 '17 at 08:15
  • 11
    another way to drop the extension: `path.parse(__filename).name` – RH Becker Feb 05 '18 at 20:59
  • 11
    `__filename` is not defined in an ES6 Module. – Cullub Jun 24 '20 at 19:15
  • 6
    @Cullub, extract from the nodejs [documentation](https://nodejs.org/api/esm.html#esm_no_require_exports_module_exports_filename_dirname): These `CommonJS` variables are not available in ES modules. Equivalents of `__filename` and `__dirname` can be created inside of each file via `import.meta.url`. – herve Jun 27 '20 at 12:50
  • You can remove the extension by regex string replace too. and it can handle upper case letter in filename `var scriptName = path.basename(__filename).replace(/\.js$/i, '' ); ` – fedmich Sep 03 '21 at 02:45
  • @Cullub `module.filename` seems to work for me. – Asaf Jul 27 '22 at 16:15
58

within a module you can do any of the following to get the full path with filename

this.filename;
module.filename;
__filename;

If you just want the actual name with no path or extension you can do something like this.

module.filename.slice(__filename.lastIndexOf(path.sep)+1, module.filename.length -3);
Anthony McCormick
  • 2,724
  • 3
  • 25
  • 27
  • 4
    You probably want to use path.sep to make it cross platform. Here's what I did __filename.slice(__filename.lastIndexOf(path.sep)+1); – Ryan Mar 29 '14 at 21:28
  • 2
    For those who just want to copy and paste this super handy one-liner, don't forget to either `var path = require('path');` beforehand or change it to `module.filename.slice(__filename.lastIndexOf(require('path').sep)+1, module.filename.length -3);` – forrestranger Aug 19 '14 at 00:23
  • 22
    the -3 assumes a length of extension, something like this might work better `path.basename(module.filename, path.extname(module.filename))` – dre Sep 02 '14 at 21:01
52

To get the file name only. No additional module simply:

// abc.js
console.log(__filename.slice(__dirname.length + 1));

 // abc
console.log(__filename.slice(__dirname.length + 1, -3));
Red Walrus
  • 529
  • 4
  • 4
26
'use strict';

const scriptName = __filename.split(/[\\/]/).pop();

Explanation

console.log(__filename);
// 'F:\__Storage__\Workspace\StackOverflow\yourScript.js'
const parts = __filename.split(/[\\/]/);
console.log(parts);
/*
 * [ 'F:',
 *   '__Storage__',
 *   'Workspace',
 *   'StackOverflow',
 *   'yourScript.js' ]
 *
**/

Here we use split function with regular expression as the first parameter.
The regular expression we want for separator is [\/] (split by / or \) but / symbol must be escaped to distinguish it from regex terminator /, so /[\\/]/.

const scriptName = __filename.split(/[\\/]/).pop(); // Remove the last array element
console.log(scriptName);
// 'yourScript.js'

Don't Use This

You really should use path.basename instead (first documented in Node.js v0.1.25), because it handles all the corner cases you don't want to know about like filenames with slashes inside (e.g. file named "foo\bar" on unix). See path answer above.

Community
  • 1
  • 1
ilyaigpetrov
  • 3,657
  • 3
  • 30
  • 46
3

You might also look at console-plus. This adds filename and linenumber to any logging text and has different colours for .log, .info and .error.

heinob
  • 19,127
  • 5
  • 41
  • 61
1

Well, I wanted to use the file name as the tag for the logger so the most straight forward and what I wanted is this:

__filename.substring(__dirname.length + 1, __filename.lastIndexOf("."))
TacB0sS
  • 10,106
  • 12
  • 75
  • 118
1

I know it's been already a long time, but what I did is __filename.split('\\').pop(). This will get the full path with the filename, split it by \ then get the last index which will be your filename.

Marcus
  • 57
  • 8
1

you can use this function to get filename:

/**
 * @description 
 * get file name from path
 * @param {string} path path to get file name
 * @returns {string} file name
 * @example 
 * getFileName('getFileName/index.js') // => index.js
 */
export default function getFileName(path) {
    return path.replace(/^.*[\\\/]/, '');
}

if you use nodejs, you can install the package that include this function https://www.npmjs.com/package/jotils

Josh
  • 670
  • 7
  • 14
1

Only because I don't see it listed here, another option is to just remove the __dirname from the __filename.

__filename.replace(`${__dirname}/`, '')

I think that is useful if you don't want to import a the path module. However, I do believe that path.basename(__filename) is the most appropriate.

Roi
  • 1,597
  • 16
  • 19