Reputation: 34808
How would I get the path to the script in Node.js?
I know there's process.cwd
, but that only refers to the directory where the script was called, not of the script itself. For instance, say I'm in /home/kyle/
and I run the following command:
node /home/kyle/some/dir/file.js
If I call process.cwd()
, I get /home/kyle/
, not /home/kyle/some/dir/
. Is there a way to get that directory?
Upvotes: 1354
Views: 1242076
Reputation: 34808
I found it after looking through the documentation again. What I was looking for were the __filename
and __dirname
module-level variables.
__filename
is the file name of the current module. This is the resolved absolute path of the current module file. (ex:/home/kyle/some/dir/file.js
)__dirname
is the directory name of the current module. (ex:/home/kyle/some/dir
)UPDATE: If your are working with ES Modules
, i.e. if you are using "type":"module"
in your package.json
, starting with Node.js 20.11 / 21.2, you can use import.meta.dirname
and import.meta.filename
:
console.log(import.meta.filename);
console.log(import.meta.dirname);
Upvotes: 1793
Reputation: 3225
Use __dirname!!
__dirname
The directory name of the current module. This is the same as the path.dirname() of the __filename
.
Example: running node example.js from /Users/mjr
console.log(__dirname);
// Prints: /Users/mjr
console.log(path.dirname(__filename));
// Prints: /Users/mjr
https://nodejs.org/api/modules.html#modules_dirname
For ESModules you would want to use:
import.meta.url
import { fileURLToPath } from 'url';
import path from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
console.log(__dirname);
// Prints: the directory of the current module
console.log(path.dirname(__filename));
// Prints: the directory of the current module, same as __dirname
Upvotes: 172
Reputation: 16257
Use the basename
method of the path
module:
var path = require('path');
var filename = path.basename(__filename);
console.log(filename);
Here is the documentation the above example is taken from.
As Dan pointed out, Node is working on ECMAScript modules with the "--experimental-modules" flag. Node 12 still supports __dirname
and __filename
as above.
If you are using the --experimental-modules
flag, there is an alternative approach.
The alternative is to get the path to the current ES module:
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(new URL(import.meta.url));
And for the directory containing the current module:
import { fileURLToPath } from 'url';
import path from 'path';
const __dirname = path.dirname(fileURLToPath(new URL(import.meta.url)));
Upvotes: 20
Reputation: 463
NodeJS exposes a global variable called __dirname
.
__dirname
returns the full path of the folder where the JavaScript file resides.
So, as an example, for Windows, if we create a script file with the following line:
console.log(__dirname);
And run that script using:
node ./innerFolder1/innerFolder2/innerFolder3/index.js
The output will be: C:\Users...<project-directory>\innerFolder1\innerFolder2\innerFolder3
Upvotes: 14
Reputation: 407
I know this is pretty old, and the original question I was responding to is marked as duplicate and directed here, but I ran into an issue trying to get jasmine-reporters to work and didn't like the idea that I had to downgrade in order for it to work. I found out that jasmine-reporters wasn't resolving the savePath
correctly and was actually putting the reports folder output in jasmine-reporters directory instead of the root directory of where I ran gulp. In order to make this work correctly I ended up using process.env.INIT_CWD
to get the initial Current Working Directory which should be the directory where you ran gulp. Hope this helps someone.
var reporters = require('jasmine-reporters');
var junitReporter = new reporters.JUnitXmlReporter({
savePath: process.env.INIT_CWD + '/report/e2e/',
consolidateAll: true,
captureStdout: true
});
Upvotes: 17
Reputation: 3084
index.js within any folder containing modules to export
const entries = {};
for (const aFile of require('fs').readdirSync(__dirname, { withFileTypes: true }).filter(ent => ent.isFile() && ent.name !== 'index.js')) {
const [ name, suffix ] = aFile.name.split('.');
entries[name] = require(`./${aFile.name}`);
}
module.exports = entries;
This will find all files in the root of the current directory, require and export every file present with the same export name as the filename stem.
Upvotes: 1
Reputation: 47861
Node.js 10 supports ECMAScript modules, where __dirname
and __filename
are no longer available.
Then to get the path to the current ES module one has to use:
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
And for the directory containing the current module:
import { dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
Upvotes: 209
Reputation: 5351
This command returns the current directory:
var currentPath = process.cwd();
For example, to use the path to read the file:
var fs = require('fs');
fs.readFile(process.cwd() + "\\text.txt", function(err, data)
{
if(err)
console.log(err)
else
console.log(data.toString());
});
Upvotes: 164
Reputation: 20422
When it comes to the main script it's as simple as:
process.argv[1]
From the Node.js documentation:
process.argv
An array containing the command line arguments. The first element will be 'node', the second element will be the path to the JavaScript file. The next elements will be any additional command line arguments.
If you need to know the path of a module file then use __filename.
Upvotes: 59
Reputation: 668
If you are using pkg
to package your app, you'll find useful this expression:
appDirectory = require('path').dirname(process.pkg ? process.execPath : (require.main ? require.main.filename : process.argv[0]));
process.pkg
tells if the app has been packaged by pkg
.
process.execPath
holds the full path of the executable, which is /usr/bin/node
or similar for direct invocations of scripts (node test.js
), or the packaged app.
require.main.filename
holds the full path of the main script, but it's empty when Node runs in interactive mode.
__dirname
holds the full path of the current script, so I'm not using it (although it may be what OP asks; then better use appDirectory = process.pkg ? require('path').dirname(process.execPath) : (__dirname || require('path').dirname(process.argv[0]));
noting that in interactive mode __dirname
is empty.
For interactive mode, use either process.argv[0]
to get the path to the Node executable or process.cwd()
to get the current directory.
Upvotes: 9
Reputation: 73
If you want something more like $0 in a shell script, try this:
var path = require('path');
var command = getCurrentScriptPath();
console.log(`Usage: ${command} <foo> <bar>`);
function getCurrentScriptPath () {
// Relative path from current working directory to the location of this script
var pathToScript = path.relative(process.cwd(), __filename);
// Check if current working dir is the same as the script
if (process.cwd() === __dirname) {
// E.g. "./foobar.js"
return '.' + path.sep + pathToScript;
} else {
// E.g. "foo/bar/baz.js"
return pathToScript;
}
}
Upvotes: -4
Reputation: 2865
Every Node.js program has some global variables in its environment, which represents some information about your process and one of it is __dirname
.
Upvotes: 20
Reputation: 287
var settings =
JSON.parse(
require('fs').readFileSync(
require('path').resolve(
__dirname,
'settings.json'),
'utf8'));
Upvotes: 27
Reputation: 14323
So basically you can do this:
fs.readFile(path.resolve(__dirname, 'settings.json'), 'UTF-8', callback);
Use resolve() instead of concatenating with '/' or '\' else you will run into cross-platform issues.
Note: __dirname is the local path of the module or included script. If you are writing a plugin which needs to know the path of the main script it is:
require.main.filename
or, to just get the folder name:
require('path').dirname(require.main.filename)
Upvotes: 322