如何在Node.js中获取脚本路径?
我知道有process.cwd
,但这只是指调用脚本的目录,而不是脚本本身的目录。例如,假设我在/home/kyle/
中,并运行以下命令:
node /home/kyle/some/dir/file.js
如果我调用process.cwd()
,我得到的是/home/kyle/
而不是/home/kyle/some/dir/
。有没有一种方法可以获取那个目录?
如何在Node.js中获取脚本路径?
我知道有process.cwd
,但这只是指调用脚本的目录,而不是脚本本身的目录。例如,假设我在/home/kyle/
中,并运行以下命令:
node /home/kyle/some/dir/file.js
如果我调用process.cwd()
,我得到的是/home/kyle/
而不是/home/kyle/some/dir/
。有没有一种方法可以获取那个目录?
我再次查看文档后找到了它。我需要查找的是模块级别的变量__filename
和__dirname
。
__filename
是当前模块的文件名。这是当前模块文件的解析绝对路径。(例如:/home/kyle/some/dir/file.js
)__dirname
是当前模块的目录名。(例如:/home/kyle/some/dir
)__dirname
获取当前文件所在的完整路径,然后使用split
方法按照操作系统的分隔符将路径分割成一个数组,最后使用pop
方法获取数组中最后一个元素,也就是当前文件所在的目录名。 - Burgirequire('path').basename(__dirname);
的意思是获取当前文件所在文件夹的名称。 - Vyacheslav Cotruta所以基本上你可以这样做:
fs.readFile(path.resolve(__dirname, 'settings.json'), 'UTF-8', callback);
使用resolve()代替使用'/'或'\'进行字符串拼接,否则会遇到跨平台问题。
注意:__dirname是模块或包含脚本的本地路径。如果你正在编写需要知道主脚本路径的插件,则应该使用:
require.main.filename
或者,仅获取文件夹名称:
require('path').dirname(require.main.filename)
var settings = require('./settings.json')
更轻松地实现此目的。当然,这是同步的fs IO操作,因此不要在运行时进行操作,但在启动时进行操作是可以的,一旦加载完成,它就会被缓存。 - isaacsNode.js 10支持ECMAScript模块,其中__dirname
和__filename
不再可用。
因此,要获取当前ES模块的路径,必须使用:
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
对于包含当前模块的目录:
import { dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
--experimental-modules
标志的情况下使用。 - Nickensoul使用 __dirname!!
__dirname
当前模块所在的目录名称。与__filename
的path.dirname()
相同。
例如:在路径 /Users/mjr 下运行 node example.js。
console.log(__dirname);
// Prints: /Users/mjr
console.log(path.dirname(__filename));
// Prints: /Users/mjr
https://nodejs.org/api/modules.html#modules_dirname
对于ES模块,您需要使用:import.meta.url
这个命令会返回当前目录:
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());
});
cd /foo; node bar/test.js
这样的命令,当前目录将是/foo
,但脚本位于/foo/bar/test.js
。 - rjmunrotext.txt
就可以了,不需要构造绝对路径。 - Michael Mrozek谈到主脚本,它就像这样简单:
process.argv[1]
根据 Node.js 文档:
process.argv
包含命令行参数的数组。第一个元素是 'node',第二个元素是JavaScript 文件的路径。接下来的元素是其他任何命令行参数。
如果您需要知道模块文件的路径,请使用 __filename。
process.argv[1]
只适用于主脚本,而 __filename
指向正在执行的模块文件。我更新了我的答案来强调这种区别。不过,我认为使用 process.argv[1]
并没有什么问题。这取决于个人需求。 - Lukasz Wiktorvar settings =
JSON.parse(
require('fs').readFileSync(
require('path').resolve(
__dirname,
'settings.json'),
'utf8'));
每个 Node.js 程序都有一些全局变量在其环境中,它们代表有关您的进程的某些信息,其中之一是 __dirname
。
我知道这已经很旧了,我要回复的原始问题被标记为重复并被引导到这里,但我遇到了一个问题,尝试让jasmine-reporters工作,但不想只能通过降级来解决它。我发现jasmine-reporters没有正确解析savePath
,实际上是将报告文件夹输出放在了jasmine-reporters目录中,而不是在我运行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
});
path
模块的 basename
方法:var path = require('path');
var filename = path.basename(__filename);
console.log(filename);
这里是上面例子的文档。
正如丹指出的那样,Node正在使用“--experimental-modules”标志开发ECMAScript模块。Node 12仍然支持上述的__dirname
和__filename
。
--experimental-modules
标志,有一种替代方法。import { fileURLToPath } from 'url';
const __filename = fileURLToPath(new URL(import.meta.url));
对于包含当前模块的目录:
import { fileURLToPath } from 'url';
import path from 'path';
const __dirname = path.dirname(fileURLToPath(new URL(import.meta.url)));
const sqlFolder = path.join(path.join(process.cwd(), 'db'), 'queries');
https://vercel.com/guides/loading-static-file-nextjs-api-route - Ryan