path.join vs path.resolve avec __dirname


142

Y a-t-il une différence lors de l'utilisation des deux path.join et path.resolveavec __dirnamepour résoudre le chemin absolu dans Node.js?

Doit-on préférer l'un d'entre eux lorsqu'il est utilisé comme ça (les résolutions de chemin absolues représentent 90% des cas d'utilisation)?

C'est à dire

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

contre.

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

Les deux méthodes normalisent le chemin.

Ce n'est pas un double de cette question car la réponse acceptée est fausse.


Cette question est en cours de discussion sur meta
— Nino Filiu

Est-ce que cela répond à votre question? Différence entre les appels path.resolve et path.join?
— user5532169

Réponses:


152

Oui, il y a une différence entre les fonctions, mais la façon dont vous les utilisez dans ce cas entraînera le même résultat.

path.joinrenvoie un chemin normalisé en fusionnant deux chemins ensemble. Il peut renvoyer un chemin absolu, mais il ne le fait pas nécessairement toujours.

Par exemple:

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

se résout à app/libs/ssl

path.resolve, d'autre part, se résoudra à un chemin absolu.

Par exemple, lorsque vous exécutez:

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

Le chemin retourné sera /foopuisque c'est le premier chemin absolu qui peut être construit.

Cependant, si vous exécutez:

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

Le chemin retourné le sera à /foo/testnouveau car c'est le premier chemin absolu qui peut être formé de droite à gauche.

Si vous ne fournissez pas de chemin qui spécifie le répertoire racine, les chemins d'accès donnés à la resolvefonction sont ajoutés au répertoire de travail actuel. Donc, si votre répertoire de travail était /home/mark/project/:

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

se résout à

/home/mark/project/test/back

Using __dirnameest le chemin absolu vers le répertoire contenant le fichier source. Lorsque vous utilisez path.resolveou, path.joinils renverront le même résultat si vous donnez le même chemin suivant __dirname. Dans de tels cas, ce n'est vraiment qu'une question de préférence.


25
Nit: __dirnameest le chemin absolu du répertoire contenant le fichier source en cours d'exécution, et non le répertoire de travail actuel . Le premier sera toujours le même (sauf si vous déplacez le fichier); ce dernier est un paramètre à l'échelle du processus qui varie en fonction de la façon dont vous avez lancé le nœud et si vous l'avez modifié ou non .
— josh3736

2
Alors n'y a-t-il pas de différence entre __dirnameet path.resolve(__dirname)?
— georaldc

1
@georaldc: J'en ai trouvé un: node <<< "path = require ('path'); console.log (__ dirname); console.log (path.resolve (__ dirname))"
— Colin

8
Je déteste le dire, mais cette réponse n'a vraiment aucun sens pour moi et j'apprécierais quelques éclaircissements. Vous remarquez que cela path.resolve('/bar/bae', '/foo', 'test');écarte essentiellement le premier argument parce que /foo/test"est le premier chemin absolu qui peut être formé de droite à gauche", mais vous n'avez pas expliqué pourquoi , donc je ne comprends vraiment pas la logique à l'œuvre. Je veux dire que je n'ai aucune vue sur la structure de répertoires hypothétique que vous utilisez dans votre exemple, donc je ne peux pas concevoir pourquoi /bar/bae/foo/testest invalide.
— temporary_user_name

3
@temporary_user_name La réponse est correcte en ce path.resolvequi concerne le comportement de ici: path.resolveopère à partir de l'argument le plus à droite, se déplaçant vers la gauche dans la liste d'arguments et précédant la valeur de chaque argument jusqu'à un chemin absolu (c'est-à-dire commençant par le répertoire racine /ou [sous Windows spécifiquement ] une lettre de lecteur) est construite, puis renvoie ce chemin. Il ignore /bar/baecar à ce moment-là, il a déjà le chemin absolu /foo/testet ne voit donc aucune raison d'aller plus loin.
— Jamie Ridding

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

contre.

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

path.joinconcaténera __dirnamequel est le nom de répertoire du fichier actuel concaténé avec les valeurs de someet diravec le séparateur spécifique à la plate-forme.

Tandis que

path.resolvetraitera __dirname, someet à- dirdire de droite à gauche préfixer par son traitement.

si l'une des valeurs de someou dircorrespond à un chemin racine, le chemin précédent sera omis et le processus de repos sera considéré comme racine

Afin de mieux comprendre le concept, laissez-moi vous expliquer les deux un peu plus en détail comme suit: -

Les path.joinet path.resolvesont deux méthodes ou fonctions différentes du module de chemin fourni par nodejs.

Où les deux acceptent une liste de chemins mais la différence vient du résultat, c'est-à-dire comment ils traitent ces chemins.

path.joinconcatène tous les segments de chemin donnés ensemble en utilisant le séparateur spécifique à la plate-forme comme délimiteur, puis normalise le chemin résultant. Pendant le path.resolve()processus, la séquence de chemins de droite à gauche, chaque chemin suivant étant ajouté jusqu'à ce qu'un chemin absolu soit construit.

Quand aucun argument n'est fourni

L'exemple suivant vous aidera à comprendre clairement les deux concepts: -

Mon nom de fichier est index.jset le répertoire de travail actuel estE:\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

Résultat

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

path.resolve()La méthode affichera le chemin absolu où les path.join()retours. représentant le répertoire de travail courant si rien n'est fourni

Quand un chemin racine est passé comme arguments

const path=require('path');

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

Résultat i

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

path.join()concatène uniquement la liste d'entrée avec un séparateur spécifique à la plate-forme tandis que le path.resolve()processus traite la séquence de chemins de droite à gauche, chaque chemin suivant étant ajouté au début jusqu'à ce qu'un chemin absolu soit construit.


La question concernait spécifiquement path.join vs path.resolve avec __dirname .
— Estus Flask

J'avais mis à jour la réponse en fonction de vos commentaires merci pour la mise à jour
— samuelj90

3

de doc pour path.resolve:

Le chemin résultant est normalisé et les barres obliques de fin sont supprimées à moins que le chemin ne soit résolu dans le répertoire racine.

Mais path.joincontinue de glisser des barres obliques

Alors

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

que signifie le mot «normalisé» dans ce contexte?
— apollo

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.