node.js中的__dirname和./有什么区别?

当在Node.js中编程并引用与当前目录相关的文件时,是否有任何理由使用__dirname变量而不是常规的./?到目前为止,我一直在使用。/在我的代码中,刚刚发现了__dirname的存在,基本上想知道它是否将我的。/转换为它是聪明的,如果是这样,为什么这将是一个聪明的想法。

300247 次浏览

./指当前的工作目录,除了在require()函数中。当使用require()时,它将./转换为当前文件的目录。__dirname始终是当前文件的目录。

例如,使用下面的文件结构

# EYZ0

{
"hello": "world"
}

# EYZ0

text file

# EYZ0

var fs = require('fs');


console.log(require('./files/config.json'));
console.log(fs.readFileSync('./files/somefile.txt', 'utf8'));

如果我cd/home/user/dir和运行node dir.js,我将得到

{ hello: 'world' }
text file

但是当我从/home/user/运行相同的脚本时,我得到

{ hello: 'world' }


Error: ENOENT, no such file or directory './files/somefile.txt'
at Object.openSync (fs.js:228:18)
at Object.readFileSync (fs.js:119:15)
at Object.<anonymous> (/home/user/dir/dir.js:4:16)
at Module._compile (module.js:432:26)
at Object..js (module.js:450:10)
at Module.load (module.js:351:31)
at Function._load (module.js:310:12)
at Array.0 (module.js:470:10)
at EventEmitter._tickCallback (node.js:192:40)

使用./require有效,但对fs.readFileSync无效。这是因为对于fs.readFileSync./转换为cwd(在本例中是/home/user/)。/home/user/files/somefile.txt不存在。

要点

在Node.js中,__dirname始终是当前执行脚本所在的目录(看到这个)。因此,如果您在/d1/d2/myscript.js中输入__dirname,则值将是/d1/d2

相比之下,.给出了您在终端窗口中运行node命令的目录(即您的工作目录),当您使用pathfs这样的库时。从技术上讲,它开始作为您的工作目录,但可以使用process.chdir()进行更改。

例外情况是当您使用.require()时。require内的路径总是相对于包含对require调用的文件。

例如……

假设您的目录结构是

/dir1
/dir2
pathtest.js

pathtest.js包含

var path = require("path");
console.log(". = %s", path.resolve("."));
console.log("__dirname = %s", path.resolve(__dirname));

你确实做到了

cd /dir1/dir2
node pathtest.js

你得到

. = /dir1/dir2
__dirname = /dir1/dir2

您的工作目录是/dir1/dir2,因此.解析为/dir1/dir2。因为pathtest.js位于/dir1/dir2,所以__dirname也解析为/dir1/dir2

但是,如果从/dir1 . #运行脚本

cd /dir1
node dir2/pathtest.js

你得到

. = /dir1
__dirname = /dir1/dir2

在这种情况下,您的工作目录是/dir1,因此.解析为.,但__dirname仍然解析为/dir1/dir2

使用.require

如果在dir2/pathtest.js中你有一个require调用,在dir1中包含一个文件,你会做总是

require('../thefile')

因为require中的路径总是相对于调用它的文件。它与您的工作目录无关。