path.join vs path.resolve z __dirname


142

Czy jest różnica w używaniu obu path.join i path.resolvez __dirnamedo rozwiązywania ścieżki bezwzględnej w Node.js?

Czy jeden z nich powinien być preferowany, gdy jest używany w ten sposób (bezwzględne rozwiązania ścieżki to 90% przypadków użycia)?

To znaczy

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

vs.

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

Obie metody normalizują ścieżkę.

To nie jest duplikat tego pytania, ponieważ przyjęta odpowiedź jest błędna.


To pytanie jest omawiane na meta
— Nino Filiu

Odpowiedzi:


152

Tak, istnieje różnica między funkcjami, ale sposób ich użycia w tym przypadku da taki sam wynik.

path.joinzwraca znormalizowaną ścieżkę poprzez scalenie dwóch ścieżek razem. Może zwrócić bezwzględną ścieżkę, ale niekoniecznie zawsze to robi.

Na przykład:

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

postanawia app/libs/ssl

path.resolvez drugiej strony zdecyduje się na absolutną ścieżkę.

Na przykład, kiedy uruchamiasz:

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

Zwrócona ścieżka będzie taka, /fooponieważ jest to pierwsza ścieżka bezwzględna, jaką można zbudować.

Jeśli jednak biegasz:

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

Zwrócona ścieżka będzie /foo/testponownie, ponieważ jest to pierwsza ścieżka bezwzględna, którą można utworzyć od prawej do lewej.

Jeśli nie podasz ścieżki określającej katalog główny, ścieżki podane do resolvefunkcji zostaną dołączone do bieżącego katalogu roboczego. Więc jeśli twój katalog roboczy to /home/mark/project/:

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

postanawia

/home/mark/project/test/back

Użycie __dirnamejest bezwzględną ścieżką do katalogu zawierającego plik źródłowy. Kiedy używasz path.resolvelub path.join, zwrócą ten sam wynik, jeśli podasz tę samą ścieżkę podążania __dirname. W takich przypadkach to tylko kwestia preferencji.


25
Nit: __dirnameto bezwzględna ścieżka do katalogu zawierającego plik źródłowy, który jest wykonywany, a nie bieżący katalog roboczy . Pierwszy zawsze będzie taki sam (chyba że przeniesiesz plik); ten ostatni jest parametrem obejmującym cały proces, który różni się w zależności od sposobu uruchomienia node i tego, czy go zmieniłeś .
— josh3736

2
Czy nie ma więc różnicy między __dirnamei path.resolve(__dirname)?
— georaldc

1
@georaldc: Znalazłem jeden: węzeł <<< "path = require ('path'); console.log (__ dirname); console.log (path.resolve (__ dirname))"
— Colin

8
Nienawidzę tego mówić, ale ta odpowiedź naprawdę nie ma dla mnie żadnego sensu i byłbym wdzięczny za pewne wyjaśnienia. Zauważasz, że path.resolve('/bar/bae', '/foo', 'test');zasadniczo odrzucasz pierwszy argument, ponieważ /foo/test„jest pierwszą absolutną ścieżką, którą można utworzyć od prawej do lewej”, ale nie wyjaśniłeś dlaczego , więc naprawdę nie rozumiem logiki w pracy. Chodzi mi o to, że nie mam żadnego wglądu w hipotetyczną strukturę katalogów, której używasz w swoim przykładzie, więc nie mogę pojąć, dlaczego /bar/bae/foo/testjest nieprawidłowa.
— temporary_user_name

3
@temporary_user_name Odpowiedź jest poprawna w odniesieniu do path.resolvezachowania tutaj: path.resolvedziała od skrajnego prawego argumentu, przesuwając się w lewo przez listę argumentów i poprzedzając wartość każdego argumentu aż do ścieżki bezwzględnej (np. zaczynającej się od katalogu głównego /lub [szczególnie w Windows ] litera dysku), a następnie zwraca tę ścieżkę. Ignoruje, /bar/baeponieważ w tym momencie ma już ścieżkę absolutną /foo/testi dlatego nie widzi powodu, aby iść dalej.
— Jamie Ridding

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

vs.

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

path.joinpołączy __dirnamenazwę katalogu bieżącego pliku połączoną z wartościami someiz dirseparatorem specyficznym dla platformy.

Natomiast

path.resolveprzetworzy __dirname, somea dirto jest od prawej do lewej poprzedzenie go przetwarzając go.

jeśli którakolwiek z wartości ścieżki głównej somelub dirodpowiada tej ścieżce, wówczas poprzednia ścieżka zostanie pominięta, a resztę przetworzy, uznając ją za główną

Aby lepiej zrozumieć tę koncepcję, wyjaśnię nieco bardziej szczegółowo oba zagadnienia: -

path.joinI path.resolvedwa różne sposoby lub funkcje modułu toru przewidziane nodejs.

Gdzie obaj akceptują listę ścieżek, ale różnica polega na wyniku, tj. W jaki sposób przetwarzają tę ścieżkę.

path.joinłączy wszystkie podane segmenty ścieżki razem, używając separatora specyficznego dla platformy jako separatora, a następnie normalizuje wynikową ścieżkę. Podczas path.resolve()przetwarzania sekwencja ścieżek od prawej do lewej, z każdą kolejną ścieżką poprzedzoną, aż do zbudowania ścieżki bezwzględnej.

Gdy nie podano argumentów

Poniższy przykład pomoże ci jasno zrozumieć obie koncepcje: -

Moja nazwa pliku to index.js a bieżący katalog roboczy toE:\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

Wynik

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

path.resolve()wyświetli ścieżkę bezwzględną, gdzie jako path.join()zwraca. reprezentuje bieżący katalog roboczy, jeśli nic nie zostanie podane

Kiedy jakaś ścieżka główna jest przekazywana jako argumenty

const path=require('path');

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

Wynik i

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

path.join()tylko łączy listę wejściową z separatorem specyficznym dla platformy, podczas gdy path.resolve()proces przetwarza sekwencję ścieżek od prawej do lewej, z każdą kolejną ścieżką poprzedzoną, aż do zbudowania ścieżki bezwzględnej.


Pytanie dotyczyło w szczególności path.join vs path.resolve z __dirname .
— Estus Flask

Zaktualizowałem odpowiedź na podstawie twoich komentarzy dzięki za aktualizację
— samuelj90

3

z dokumentu dla path.resolve:

Wynikowa ścieżka jest znormalizowana, a końcowe ukośniki są usuwane, chyba że ścieżka jest tłumaczona na katalog główny.

Ale path.joinciągłe ukośniki

Więc

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

co w tym kontekście oznacza słowo „znormalizowany”?
— apollo

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.