В чем разница между __dirname и ./ в node.js? - PullRequest
448 голосов
/ 15 ноября 2011

При программировании в Node.js и обращении к файлам, которые находятся где-то относительно вашего текущего каталога, есть ли причина использовать переменную __dirname вместо обычной ./?До сих пор я использовал ./ в своем коде и только что обнаружил существование __dirname, и по сути хочу узнать, будет ли разумно конвертировать мои ./ в это, и если да, то почему это будетумная идея.

Ответы [ 2 ]

733 голосов
/ 17 августа 2013

Суть

В 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 всегда относительно файла, в котором вы его вызываете.Это не имеет ничего общего с вашим рабочим каталогом.

151 голосов
/ 15 ноября 2011

./ относится к текущему рабочему каталогу, кроме функции 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 не существует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...