В чем разница между __dirname и./ в node.js?
При программировании в Node.js и обращении к файлам, которые находятся где-то относительно вашего текущего каталога, есть ли причина использовать __dirname
переменная вместо обычного ./
? Я использовал./ до сих пор в моем коде и только что обнаружил существование __dirname
и, по сути, хочу знать, будет ли разумно конвертировать мои./ в это, и если да, то почему это будет разумной идеей.
2 ответа
Суть
В Node.js, __dirname
всегда каталог, в котором находится исполняемый в данный момент скрипт ( см. это). Так что если вы набрали __dirname
в /d1/d2/myscript.js
, значение будет /d1/d2
,
В отличие от .
дает вам каталог, из которого вы запустили node
команда в окне терминала (т. е. ваш рабочий каталог), когда вы используете такие библиотеки, как 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
всегда относительно файла, в котором вы его вызываете. Это не имеет ничего общего с вашим рабочим каталогом.
./
ссылается на текущий рабочий каталог, кроме 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
не существует.