Is there a different way, other than process.cwd()
, to get the pathname of the current project's root-directory. Does Node implement something like ruby's property, Rails.root
,. I'm looking for something that is constant, and reliable.
Node.js – Determine project root from a running node.js application
node.jsworking-directory
Related Topic
- Javascript – In Node.js, how to “include” functions from the other files
- Node.js fs.readdir recursive directory search
- Node.js – How to store Node.js deployment settings/configuration files
- Node.js – How to install package.json dependencies in the current directory using npm
- Node.js – How to use executables from a package installed locally in node_modules
- Javascript – How to completely uninstall Node.js, and reinstall from beginning (Mac OS X)
- Node.js – NodeJS – What does “socket hang up” actually mean
- Node.js – Proper way to return JSON using node or Express
Best Answer
Understanding the root directory as the one containing the
package.json
file, and that's basically the directory containing the nearestnode_modules
folder, there is exactly one way "to get the pathname of the current project's root-directory":This works because
module.paths
contains thenode_modules
search paths up to the root directory/
. So, starting from the0
index of themodule.paths
search list, the first existing directory we encounter is the desired target.Legacy answer follows below. Rather than provide a new answer, it made sense to improve the existing and accepted answer since it already had been considerably upvoted.
There are several ways to approach this, each with their own pros and cons:require.main.filename
From http://nodejs.org/api/modules.html:
So if you want the base directory for your app, you can do:
Pros & Cons
This will work great most of the time, but if you're running your app with a launcher like pm2 or running mocha tests, this method will fail.
global.X
Node has a a global namespace object called
global
— anything that you attach to this object will be available everywhere in your app. So, in yourindex.js
(orapp.js
or whatever your main app file is named), you can just define a global variable:Pros & Cons
Works consistently but you have to rely on a global variable, which means that you can't easily reuse components/etc.
process.cwd()
This returns the current working directory. Not reliable at all, as it's entirely dependent on what directory the process was launched from:
app-root-path
To address this issue, I've created a node module called app-root-path. Usage is simple:
The app-root-path module uses several different techniques to determine the root path of the app, taking into account globally installed modules (for example, if your app is running in
/var/www/
but the module is installed in~/.nvm/v0.x.x/lib/node/
). It won't work 100% of the time, but it's going to work in most common scenarios.Pros & Cons
Works without configuration in most circumstances. Also provides some nice additional convenience methods (see project page). The biggest con is that it won't work if:
node_modules
directory (for example, if you installed it globally)You can get around this by either setting a
APP_ROOT_PATH
environmental variable, or by calling.setPath()
on the module, but in that case, you're probably better off using theglobal
method.NODE_PATH environmental variable
If you're looking for a way to determine the root path of the current app, one of the above solutions is likely to work best for you. If, on the other hand, you're trying to solve the problem of loading app modules reliably, I highly recommend looking into the
NODE_PATH
environmental variable.Node's Modules system looks for modules in a variety of locations. One of these locations is wherever
process.env.NODE_PATH
points. If you set this environmental variable, then you canrequire
modules with the standard module loader without any other changes.For example, if you set
NODE_PATH
to/var/www/lib
, the the following would work just fine:A great way to do this is using
npm
:Now you can start your app with
npm start
and you're golden. I combine this with my enforce-node-path module, which prevents accidentally loading the app withoutNODE_PATH
set. For even more control over enforcing environmental variables, see checkenv.One gotcha:
NODE_PATH
must be set outside of the node app. You cannot do something likeprocess.env.NODE_PATH = path.resolve(__dirname)
because the module loader caches the list of directories it will search before your app runs.[added 4/6/16] Another really promising module that attempts to solve this problem is wavy.