如何使用Node.js获取当前脚本的路径?

时间:2010-06-28 14:31:02

标签: node.js

我如何获得Node.js中脚本的路径?

我知道有process.cwd,但这只是指调用脚本的目录,而不是脚本本身。例如,假设我在/home/kyle/并运行以下命令:

node /home/kyle/some/dir/file.js

如果我致电process.cwd(),我会/home/kyle/,而不是/home/kyle/some/dir/。有没有办法获得该目录?

14 个答案:

答案 0 :(得分:1236)

我在再次查看文档后找到了它。我要找的是__filename__dirname模块级变量。

  • __filename是当前模块的文件名。这是当前模块文件的已解析绝对路径。 (例如:/home/kyle/some/dir/file.js
  • __dirname是当前模块的目录名称。 (例如:/home/kyle/some/dir

答案 1 :(得分:216)

所以基本上你可以这样做:

fs.readFile(path.resolve(__dirname, 'settings.json'), 'UTF-8', callback);

使用resolve()而不是与'/'或'\'连接,否则您将遇到跨平台问题。

注意:__ dirname是模块或包含脚本的本地路径。如果您正在编写一个需要知道主脚本路径的插件,那就是:

require.main.filename

或者,只需获取文件夹名称:

require('path').dirname(require.main.filename)

答案 2 :(得分:77)

此命令返回当前目录:

var currentPath = process.cwd();

例如,要使用路径来读取文件:

var fs = require('fs');
fs.readFile(process.cwd() + "\\text.txt", function(err, data)
{
    if(err)
        console.log(err)
    else
        console.log(data.toString());
});

答案 3 :(得分:59)

使用__dirname !!

__dirname

当前模块的目录名称。这与__filename

的path.dirname()相同

示例:从/ Users / mjr

运行节点example.js
console.log(__dirname);
// Prints: /Users/mjr
console.log(path.dirname(__filename));
// Prints: /Users/mjr

https://nodejs.org/api/modules.html#modules_dirname

对于ESModules,您可以使用: import.meta.url

答案 4 :(得分:43)

说到主脚本,它很简单:

process.argv[1]

来自Node.js documentation

  

process.argv

     

包含命令行参数的数组。第一个元素是'节点',第二个元素将是JavaScript文件的路径。下一个元素将是任何其他命令行参数。

如果您需要知道模块文件的路径,请使用__filename

答案 5 :(得分:26)

var settings = 
    JSON.parse(
        require('fs').readFileSync(
            require('path').resolve(
                __dirname, 
                'settings.json'),
            'utf8'));

答案 6 :(得分:23)

每个Node.js程序在其环境中都有一些全局变量,它代表有关您的流程的一些信息,其中一个是__dirname

答案 7 :(得分:14)

Node.js 10支持ECMAScript modules,其中__dirname and __filename are no longer available

然后要使用path to the current ES module必须使用:

const __filename = new URL(import.meta.url).pathname;

对于包含当前模块的目录:

import path from 'path';

const __dirname = path.dirname(new URL(import.meta.url).pathname);

答案 8 :(得分:8)

您可以使用process.env.PWD获取当前的应用程序文件夹路径。

答案 9 :(得分:8)

我知道这是相当古老的,我回答的原始问题被标记为重复并指示在这里,但我遇到了一个问题,试图让茉莉花 - 记者工作,并且不喜欢我的想法降级以使其发挥作用。我发现jasmine-reporter没有正确解析savePath,实际上是将报告文件夹输出放在jasmine-reporter目录而不是我运行gulp的根目录。为了使这项工作正常,我最终使用 process.env.INIT_CWD 来获取最初的当前工作目录,该目录应该是您运行gulp的目录。希望这有助于某人。

var reporters = require('jasmine-reporters');
var junitReporter = new reporters.JUnitXmlReporter({
  savePath: process.env.INIT_CWD + '/report/e2e/',
  consolidateAll: true,
  captureStdout: true
});

答案 10 :(得分:4)

如果您使用pkg打包应用,则可以找到有用的表达式:

appDirectory = require('path').dirname(process.pkg ? process.execPath : (require.main ? require.main.filename : process.argv[0]));
  • process.pkg告知应用是否已由pkg打包。

  • process.execPath包含可执行文件的完整路径,/usr/bin/node或类似名称,用于直接调用脚本(node test.js)或打包的应用程序。

  • require.main.filename包含主脚本的完整路径,但在Node以交互模式运行时它为空。

  • __dirname保存当前脚本的完整路径,所以我没有使用它(虽然它可能是OP要求的;然后更好地使用{{1}注意到在交互模式下appDirectory = process.pkg ? require('path').dirname(process.execPath) : (__dirname || require('path').dirname(process.argv[0]));为空。

  • 对于交互模式,使用__dirname获取节点可执行文件的路径,或使用process.argv[0]获取当前目录。

答案 11 :(得分:0)

使用basename模块的path方法:

var path = require('path');
var filename = path.basename(__filename);
console.log(filename);

Here是上面示例的文档。

正如Dan所指出的那样,Node正在ECMAScript modules上使用“ --experimental-modules”标志进行工作。节点12依旧supports __dirname and __filename


如果您使用的是--experimental-modules标志,则有一个alternative approach

另一种方法是获取path to the current ES module

const __filename = new URL(import.meta.url).pathname;

对于包含当前模块的目录:

import path from 'path';

const __dirname = path.dirname(new URL(import.meta.url).pathname);

答案 12 :(得分:0)

包含要导出的模块的任何文件夹中的 index.js

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;

这将在当前目录的根目录中查找所有文件,要求并导出与文件名词干具有相同导出名称的每个文件。

答案 13 :(得分:-2)

如果你想在shell脚本中使用更像$ 0的东西,试试这个:

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;
    }
}