Jaka jest różnica między path.resolve i path.join?


199

Czy jest jakaś różnica między następującymi wywołaniami?

path.join(__dirname, 'app')

vs.

path.resolve(__dirname, 'app')

Który powinien być preferowany?


To pytanie jest omawiane na meta
Nino Filiu

Odpowiedzi:


266

Te dwie funkcje radzą sobie z segmentami zaczynającymi się /na bardzo różne sposoby; joinpo prostu połączy go z poprzednim argumentem, jednak resolvepotraktuje go jako katalog główny i zignoruje wszystkie poprzednie ścieżki - pomyśl o tym jako wyniku wykonania cdz każdym argumentem:

path.join('/a', '/b') // Outputs '/a/b'

path.resolve('/a', '/b') // Outputs '/b'

Inną rzeczą, na którą należy zwrócić uwagę, jest to, że path.resolvezawsze spowoduje to bezwzględny adres URL i użyje katalogu roboczego jako podstawy do rozwiązania tej ścieżki. Ale jak i tak __dirnamejest to ścieżka absolutna, w twoim przypadku nie ma to znaczenia.

Jeśli chodzi o to, którego należy użyć, odpowiedź brzmi: zależy to od tego, jak /mają się zachowywać segmenty zaczynające się - czy powinny być po prostu połączone, czy powinny działać jako nowy rdzeń?

Jeśli inne argumenty są zakodowane na stałe, to naprawdę nie ma to znaczenia, w takim przypadku prawdopodobnie powinieneś rozważyć (a) jak ta linia może się zmienić w przyszłości i (b) jak spójna jest z innymi miejscami w kodzie.


68
Jeśli nadal go nie dostaniesz: path.join('/a', '/b', 'c')wróci /a/b/c, while path.resolve('/a', '/b', 'c')wróci /b/c.
totymedli

30
Powiedziałbym, że nazwa resolvenie jest najbardziej przejrzysta, path.cd([starting dir], [final dir])byłaby znacznie bardziej intuicyjna.
João Pimentel Ferreira,

22
To think of it as the result of executing cd with each argumentsprawiło, że w końcu to zrozumiałem. Dzięki
André Pena,

@ JoãoPimentelFerreira, zaktualizowałem powyższą odpowiedź, ponieważ wskazałeś ważny punkt. :)
Rin Minase

więc path.resolve => rozwiązać ścieżkę, biorąc pod uwagę katalog roboczy jako punkt początkowy ścieżki?
Webwoman,

23

Domyślne operacje na ścieżce systemu plików różnią się w zależności od systemu operacyjnego, potrzebujemy czegoś, co go abstrakcyjnie. pathModuł dostarcza narzędzi lub API do pracy ze ścieżkami plików i katalogów. możesz dołączyć go do swojego projektu za pomocą

const path = require('path');

path.joinI path.resolvedwa różne sposoby modułu przenośnika.

Obie te metody akceptują sekwencję ścieżek lub segmentów ścieżek.

path.resolve()Sposób usuwa sekwencję segmentów toru ścieżki lub do w absolutnym ścieżki .

path.join()Sposób łączy wszystkie podane segmenty ścieżki razem za pomocą separatora konkretnej platformy jako separatora, normalizuje otrzymanego drogą.

Aby lepiej zrozumieć i zróżnicować zachowania, pozwólcie, że wyjaśnię to za pomocą różnych scenariuszy.

1. Jeśli nie podamy żadnych argumentów lub pusty łańcuch

w moim przypadku moja nazwa pliku to, index.jsa 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 of the node process

a na biegu wynik jest jak poniżej

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

Wnioskowanie z powyższego eksperymentu jest takie, że path.resolve()metoda wyświetli ścieżkę bezwzględną, gdzie jako path.join()zwraca. reprezentuje bieżący katalog roboczy lub ścieżkę względną, jeśli nic nie jest podane

2. Dodanie / path jako dowolnego argumentu.

const path=require('path');

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

a wynik jest

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

Wniosek, który możemy znaleźć w tym eksperymencie, jest taki, że path.join()tylko konkatenuje listę wejściową z separatorem specyficznym dla platformy podczas path.resolve()przetwarzania sekwencji ścieżek od prawej do lewej, z każdą kolejną ścieżką poprzedzoną, aż do zbudowania ścieżki bezwzględnej.

path.join()łączy każdy argument z separatorami specyficznymi dla systemu operacyjnego, podczas gdy path.resolve()rozwiąże każdy argument z korzeniem i wygeneruje wynik.


path.resolve()to nie równoważne do __dirname. Pierwsza zwraca katalog roboczy, a druga jest ścieżką do bieżącego pliku.
Emile Bergeron,

@EmileBergeron W moim rozumieniu obie są funkcjami na ścieżce. Możesz spróbować podążać za fragmentem, aby sprawdzić, czy myślę, że oba są takie same. const path = require('path'); console.log(path.resolve()) console.log(__dirname) console.log(path.resolve()===__dirname)
samuelj90

Zdarza się, że są takie same tylko wtedy, gdy uruchamiany plik znajduje się w bieżącym katalogu roboczym.
Emile Bergeron,

@EmileBergeron Ok, zgadzam się, ale nadal nie wiem, gdzie to określiłempath.resolve() is equivalent to __dirname
samuelj90

1
@EmileBergeron Zaktualizowałem komentarz, myślę, że rozwiąże to zamieszanie
samuelj90

20

1) path.resolve tworzy ścieżkę bezwzględną.

Metoda tworzy bezwzględną ścieżkę od prawej do lewej, aż do zbudowania ścieżki bezwzględnej.

Na przykład:

path.resolve('/a', 'b', 'c');     //    C:\a\b\c
path.resolve('/a', '/b', 'c');    //    C:\b\c
path.resolve('/a', '/b', '/c');   //    C:\c

Jeśli ścieżka bezwzględna nie jest generowana, metoda wykorzystująca bieżący katalog roboczy:

Na przykład:

path.resolve('a', 'b', 'c');     //    C:\{current_working_directory}\a\b\c

2) path.join łączy wszystkie ścieżki i normalizuje wynik

Na przykład:

path.join('/a', '/b', '/c');   //   \a\b\c
path.join('/a', '/b', 'c');    //   \a\b\c
path.join('/a', 'b', 'c');     //   \a\b\c
path.join('a', 'b', 'c');      //   \a\b\c

4
Ostatni przykład łączenia path.join('a','b','c')powinien skutkować a\b\c.
spmdc
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.