path.join против path.resolve с __dirname


142

Есть ли разница при использовании как path.join и path.resolveс __dirnameразрешением абсолютного пути в Node.js?

Должен ли один из них быть предпочтительным при использовании таким образом (абсолютные разрешения пути составляют 90% случаев использования)?

Т.е.

const absolutePath = path.join(__dirname, some, dir);

против

const absolutePath = path.resolve(__dirname, some, dir);

Оба метода нормализуют путь.

Это не дубликат этого вопроса, потому что принятый ответ неверен.


Этот вопрос обсуждается на мета
— Нино Филю

Отвечает ли это на ваш вопрос? Разница между вызовами path.resolve и path.join?
— user5532169

Ответы:


152

Да, между функциями есть разница, но то, как вы их используете в этом случае, приведет к тому же результату.

path.joinвозвращает нормализованный путь, объединяя два пути вместе. Он может вернуть абсолютный путь, но это не всегда так.

Например:

path.join('app/libs/oauth', '/../ssl')

решает в app/libs/ssl

path.resolveс другой стороны, приведет к абсолютному пути.

Например, когда вы запускаете:

path.resolve('bar', '/foo');

Возвращенный путь будет, /fooпоскольку это первый абсолютный путь, который можно построить.

Однако, если вы запустите:

path.resolve('/bar/bae', '/foo', 'test');

Возвращенный путь будет /foo/test снова, потому что это первый абсолютный путь, который может быть сформирован справа налево.

Если вы не укажете путь, указывающий корневой каталог, то пути, указанные для resolveфункции, будут добавлены в текущий рабочий каталог. Так что, если ваш рабочий каталог был /home/mark/project/:

path.resolve('test', 'directory', '../back');

решает в

/home/mark/project/test/back

Использование __dirname- это абсолютный путь к каталогу, содержащему исходный файл. Когда вы используете path.resolveили path.joinони будут возвращать тот же результат, если вы дадите тот же путь, следующий __dirname. В таких случаях это действительно просто вопрос предпочтений.


25
Nit: __dirnameэто абсолютный путь к каталогу, в котором находится исполняемый файл, а не к текущему рабочему каталогу . Первый всегда будет одинаковым (если вы не переместите файл); последний является параметром всего процесса, который зависит от того, как вы запустили узел и изменили ли вы его .
— Josh3736

2
Так нет ли разницы между __dirnameи path.resolve(__dirname)?
— georaldc

1
@georaldc: Я нашел один: узел <<< "path = require ('path'); console.log (__ dirname); console.log (path.resolve (__ dirname))"
— Колин

8
Я ненавижу это говорить, но этот ответ на самом деле не имеет никакого смысла для меня, и я был бы признателен за некоторые разъяснения. Вы замечаете, что по path.resolve('/bar/bae', '/foo', 'test');существу отбрасывает первый аргумент, потому что /foo/test«это первый абсолютный путь, который может быть сформирован справа налево», но вы не объяснили почему , поэтому я действительно не понимаю логику в работе. Я имею в виду, что у меня нет представления о гипотетической структуре каталогов, которую вы используете в своем примере, поэтому я не могу понять, почему /bar/bae/foo/testона недействительна.
— временное_имя_пользователя

3
@teditional_user_name Ответ правильный относительно path.resolveповедения здесь: path.resolveработает от самого правого аргумента, перемещаясь влево по списку аргументов и добавляя значение каждого аргумента до абсолютного пути (т. е. начинающегося с корневого каталога /или [в Windows специально ] буква диска), затем возвращает этот путь. Он игнорирует, /bar/baeпотому что к этому моменту он уже имеет абсолютный путь /foo/testи поэтому не видит причин идти дальше.
— Джейми Риддинг

23
const absolutePath = path.join(__dirname, some, dir);

против

const absolutePath = path.resolve(__dirname, some, dir);

path.joinбудет объединено, __dirnameкоторое является именем каталога текущего файла, объединенного со значениями someи dirсо специфичным для платформы разделителем.

В то время как

path.resolveбудет обрабатывать __dirname, someи dirто есть справа налево предваряя его обработки.

если какое-либо из значений someили dirсоответствует корневому пути, тогда предыдущий путь будет пропущен, и процесс rest будет считаться корневым.

Чтобы лучше понять концепцию, позвольте мне объяснить несколько более подробно следующее:

path.joinиpath.resolve два различных метода или функции модуля пути , предоставляемые nodejs.

Когда оба принимают список путей, но разница возникает в результате, т.е. как они обрабатывают этот путь.

path.joinобъединяет все заданные сегменты пути вместе, используя специфический для платформы разделитель в качестве разделителя, а затем нормализует результирующий путь. Во время path.resolve()процесса последовательность путей справа налево, с каждым последующим путем, предваряемым, пока не будет построен абсолютный путь.

Когда аргументы не предоставлены

Следующий пример поможет вам четко понять обе концепции:

Мое имя файла index.jsи текущий рабочий каталогE:\MyFolder\Pjtz\node

const path = require('path');

console.log("path.join() : ", path.join());
// outputs .
console.log("path.resolve() : ", path.resolve());
// outputs current directory or equalent to __dirname

результат

λ node index.js
path.join() :  .
path.resolve() :  E:\MyFolder\Pjtz\node

path.resolve()Метод выведет абсолютный путь, где в качестве path.join()возврата. представляет текущий рабочий каталог, если ничего не указано

Когда некоторый корневой путь передается в качестве аргументов

const path=require('path');

console.log("path.join() : " ,path.join('abc','/bcd'));
console.log("path.resolve() : ",path.resolve('abc','/bcd'));

Результат я

λ node index.js
path.join() :  abc\bcd
path.resolve() :  E:\bcd

path.join()только объединяет входной список с разделителем, специфичным для платформы, в то время как path.resolve()обрабатывает последовательность путей справа налево, причем каждый последующий путь добавляется до тех пор, пока не будет создан абсолютный путь.


Вопрос был конкретно о path.join против path.resolve с __dirname .
— Estus Колба

Я обновил ответ на основе ваших комментариев спасибо за обновление
— samuelj90

3

из документа для path.resolve:

Результирующий путь нормализуется, а завершающие косые черты удаляются, если только путь не разрешен к корневому каталогу.

Но path.joinдержит косые черты

Так

__dirname = '/';
path.join(__dirname, 'foo/'); // '/foo/'
path.resolve(__dirname, 'foo/'); // '/foo'

что означает слово «нормализованный» в этом контексте?
— Аполлон

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.