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

时间:2011-11-15 04:05:05

标签: node.js

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

2 个答案:

答案 0 :(得分:714)

要点

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

相比之下,.为您提供了在使用node和{{1}等库时在终端窗口(即工作目录)中运行path命令的目录}}。从技术上讲,它最初是作为您的工作目录,但可以使用fs进行更改。

例外情况是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解析的内容。由于.位于pathtest.js/dir1/dir2也是__dirname所解决的。

但是,如果您从/dir1

运行脚本
cd /dir1
node dir2/pathtest.js

你得到了

. = /dir1
__dirname = /dir1/dir2

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

. ...

中使用require

如果在dir2/pathtest.js内有require来电,请在dir1内添加一个文件,您始终执行

require('../thefile')

因为require内的路径始终相对于您调用它的文件。它与您的工作目录无关。

答案 1 :(得分:150)

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

例如,使用以下文件结构

/home/user/dir/files/config.json

{
  "hello": "world"
}

/home/user/dir/files/somefile.txt

text file

/home/user/dir/dir.js

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不存在。