29

Let's say I have two files, dir/a.js and lib/b.js

a.js:

b = require('../lib/b'); b.someFn(); 

b.js:

var fallback = "./config.json"; module.exports = { someFn = function(jsonFile) { console.log(require(jsonFile || fallback); } } 

The entire purpose of b.js in this example is to read a json file, so I might call it as b.someFn("path/to/file.json").

But I want there to be a default, like a config file. But the default should be relative to a.js and not b.js. In other words, I should be able to call b.someFn() from a.js, and it should say, "since you didn't pass me the path, I will assume a default path of config.json." But the default should be relative to a.js, i.e. should be dir/config.json and not lib/config.json, which I would get if I did require(jsonFile).

I could get the cwd, but that will only work if I launch the script from within dir/.

Is there any way for b.js to say, inside someFn(), "give me the __dirname of the function that called me?"

3
  • Can you modify the b module? Commented Aug 9, 2013 at 11:07
  • Yes, I own b, no problem. Actually, b is turning into a module, I just want it to be able to have a default file relative to the caller. Commented Aug 9, 2013 at 12:19
  • Then simply set use the directory where a.js is located. See the answer. Commented Aug 9, 2013 at 12:53

4 Answers 4

37

Use callsite, then:

b.js:

var path = require('path'), callsite = require('callsite'); module.exports = { someFn: function () { var stack = callsite(), requester = stack[1].getFileName(); console.log(path.dirname(requester)); } }; 
Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what I was looking for
1

You give the function in b.js the __dirname in a.js. Example:

a.js:

const b = require("../lib/b.js"); b.someFn(__dirname); 

Comments

0

Alternatively, using parent-module:

const path = require('path'); const parentModule = require('parent-module'); // get caller of current script console.log(path.dirname(parentModule())); // get caller of module, change './index.js' to your "main" script console.log(path.dirname(parentModule(require.resolve('./index.js')))); 

Comments

-1

If you want to get the directory of the script of the caller function, then use the stacktrace as the above answer shows, otherwise, what's the problem of hardcoding the directory of a.js?

var fallback = "dir_a/config.json"; module.exports = { someFn = function(jsonFile) { console.log(require(jsonFile || fallback); } } 

1 Comment

Because b.js doesn't know about the directory of a.js. In my example, I simplified it so that we know both, but really b.js is inside an npm module.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.