В чем разница между __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 не существует.

Другие вопросы по тегам