ChatGPT解决这个技术问题 Extra ChatGPT

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

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

tl;dr:所以,基本上,区别在于“./”和“process.cwd()”指的是调用脚本的终端的当前目录,而“__dirname”指的是脚本所在的目录存储。
除了require 中使用 . 时。 require 内的路径始终与包含对 require 的调用的文件相关。

C
Community

要点

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

相比之下,当您使用 pathfs 之类的库时,. 会为您提供在终端窗口中运行 node 命令的目录(即您的工作目录)。从技术上讲,它最初是您的工作目录,但可以使用 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

使用 。里面需要...

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

require('../thefile')

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


IMO,这个解释比接受的答案更清楚一些(你知道,“当前目录”在那里有点模棱两可)。
我同意。我将更改接受的答案。请记住,这个答案是在原始答案被接受 2.5 年后添加的,而我现在才注意到它(又过了 2 年)。 :) 迟到总比不到好!
值得注意的是,./ 并非始终启动节点的目录。它以这种方式开始,但可以通过 process.chdir() 进行更改。因此,./ 始终是当前工作目录,通常是从中启动的目录节点,除非您的代码显式更改了工作目录。
我对 Using 有点困惑。在 require 部分,如果 require 中的路径总是相对于您正在调用的文件,那么路径不应该是 require('../thefile') 而不是 require('../dir1/thefile') 吗?我认为 .. 已经将路径的当前位置从 dir2 拉回到 dir1 一级。你还需要把 dir1 放在路径中还是我想念什么?
如果您需要在某个脚本中使用 ../someDir 并且您要从不同的文件夹运行该命令,您会怎么做?
T
Timo Tijhof

./ 指的是当前工作目录,但在 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 不存在。


哦,我以为 __dirname 是当前的工作目录...感谢您的澄清!
有没有办法用 fs 引用应用程序的工作目录?例如,我尝试从工作目录 /movies 加载文件,但由于我的模块位于文件 /custom_modules/ 中,__dirname 尝试从 /custom_modules/movies 中获取电影
您可以使用 ./process.cwd()。见nodejs.org/api/process.html#process_process_cwd
值得注意的是,在 require 语句中使用 __dirname 而不是 ./ 并不是一个好主意,因为尽管它们在 node 中的行为相同,但它可能会导致易于避免的包的 browserify 构建问题。