在 Node.js 中编程并引用与当前目录相关的某个位置的文件时,是否有任何理由使用 __dirname
变量而不仅仅是常规的 ./
?到目前为止,我一直在我的代码中使用 ./ 并且刚刚发现 __dirname
的存在,并且本质上想知道将我的 ./ 转换为它是否明智,如果是,为什么会这样一个聪明的主意。
require
中使用 .
时。 require
内的路径始终与包含对 require
的调用的文件相关。
要点
在 Node.js 中,__dirname
始终是当前执行脚本所在的目录 (see this)。因此,如果您在 /d1/d2/myscript.js
中键入 __dirname
,则值为 /d1/d2
。
相比之下,当您使用 path
和 fs
之类的库时,.
会为您提供在终端窗口中运行 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
中的路径总是相对于您调用它的文件。它与您的工作目录无关。
./
指的是当前工作目录,但在 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
不存在。
/movies
加载文件,但由于我的模块位于文件 /custom_modules/
中,__dirname
尝试从 /custom_modules/movies
中获取电影
不定期副业成功案例分享
./
并非始终启动节点的目录。它以这种方式开始,但可以通过process.chdir()
进行更改。因此,./
始终是当前工作目录,通常是从中启动的目录节点,除非您的代码显式更改了工作目录。../someDir
并且您要从不同的文件夹运行该命令,您会怎么做?