14

I'm wondering if there is a best way or best practice to get the full path of application in Node.js. Example: I have a a module in sub folder /apps/myapp/data/models/mymodel.js, and I would like to get the full path of the app (not full path of the file), which will return me /apps/myapp, how do I do that? I know _dirname or _file is only relative to the file itself but not the full path of the app.

Nam Nguyen
  • 5,668
  • 14
  • 56
  • 70

2 Answers2

27

There's probably a better solution, BUT this should work:

var path = require('path');

// find the first module to be loaded
var topModule = module;

while(topModule.parent)
  topModule = topModule.parent;

var appDir = path.dirname(topModule.filename);
console.log(appDir);

EDIT: Andreas proposed a better solution in the comments:

path.dirname(require.main.filename)

EDIT: another solution by Nam Nguyen

path.dirname(process.mainModule.filename)
Nam Nguyen
  • 5,668
  • 14
  • 56
  • 70
Laurent Perrin
  • 14,671
  • 5
  • 50
  • 49
  • woo.. I did not expect that complicated but I will try that and thanks. – Nam Nguyen Sep 04 '13 at 18:03
  • 1
    `path.dirname(require.main.filename)` should do the exact same thing. Note that this (as well as OP's) solution will fail if you run the app through another app (pm2, forever or mocha being common cases). – Andreas Hultgren Sep 04 '13 at 18:41
  • If you want to turn this into a function, and put it in a single place (say `common.js`), there will be a problem: you need to know the location of `common.js` (relative to the current file) so that you can use `require('common.js')`. Actually `__dirname` will never solve the problem nicely. I think in nodejs apps, files are supposed to know *where they are*, and there's simply no need for the root path. – Khanh Nguyen Sep 04 '13 at 18:42
  • yeup, console.log(require('path').dirname(require.main.filename)); works. Thanks ALL! – Nam Nguyen Sep 05 '13 at 04:54
  • 2
    I also found out another solution: require('path').dirname(process.mainModule.filename) – Nam Nguyen Sep 06 '13 at 04:41
  • @AndreasHultgren, look like path.dirname(process.mainModule.filename) solution might be safer instead of require.main.filename if we run the app through another app? I'm not sure though and wondering if you have any thought. – Nam Nguyen Sep 06 '13 at 04:51
  • Indeed it seems more supervisor-proof, but it still would fail with eg mocha (or other testing frameworks). Then I realize that might not be a problem since I guess one can override process.mainModule in the tests? – Andreas Hultgren Sep 06 '13 at 06:18
  • I'm not sure either if it will be the issue, we only know when we test it :) – Nam Nguyen Sep 06 '13 at 16:38
3

This worked for me.. With supervisor running the app from a different dir.

require('path').dirname(Object.keys(require.cache)[0])

example.. files: /desktop/ya/node.js

  require('./ya2/submodule')();

/desktop/ya/ya2/submodule.js

module.exports = function(){
    console.log(require('path').dirname(Object.keys(require.cache)[0]))
}

$ node node.js  
       => /desktop/ya

$ (from /desktop) supervisor ya/node.js
       => /desktop/ya
C B
  • 12,482
  • 5
  • 36
  • 48