path.join vs path.resolve з __dirname


142

Чи є різниця при використанні обох path.join і path.resolveз __dirnameдля вирішення абсолютного шляху в Node.js?

Чи слід віддати перевагу одній із них при такому використанні (абсолютна роздільна здатність шляху становить 90% випадків використання)?

Тобто

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

vs.

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

Обидва методи нормалізують шлях.

Це не дублікат цього питання, оскільки прийнята відповідь неправильна.


Це питання обговорюється на мета
— Nino

Чи відповідає це на ваше запитання? Різниця між path.resolve та path.join invocation?
— користувач5532169

Відповіді:


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 = requ ('path'); console.log (__ dirname); console.log (path.resolve (__ dirname))"
— Колін

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

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

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

vs.

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

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

Де як

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

якщо будь-яке значення someабо dirвідповідає кореневому шляху, попередній шлях буде опущено та обробляє решта, вважаючи його кореневим

З метою кращого розуміння концепції, дозвольте мені пояснити обидві детальніше так:

Два 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'));

Результат i

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

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


Питання стосувалося конкретно про path.join vs path.resolve з __dirname .
— колба Естуса

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

3

від doc для 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.