path.join vs path.resolve com __dirname


142

Existe uma diferença ao usar ambos path.join e path.resolvecom __dirnamepara resolver o caminho absoluto no Node.js?

Um deles deve ser preferido ao ser usado assim (resoluções de caminho absoluto são 90% dos casos de uso)?

Ou seja,

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

vs.

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

Ambos os métodos normalizam o caminho.

Esta não é uma duplicata desta pergunta porque a resposta aceita está errada.


Esta questão está sendo discutida em meta
Nino Filiu 02/07/19

Respostas:


152

Sim, existe uma diferença entre as funções, mas a maneira como você as utiliza neste caso resultará no mesmo resultado.

path.joinretorna um caminho normalizado mesclando dois caminhos. Pode retornar um caminho absoluto, mas nem sempre necessariamente o faz.

Por exemplo:

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

resolve app/libs/ssl

path.resolve, por outro lado, resolverá um caminho absoluto.

Por exemplo, quando você executa:

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

O caminho retornado será /fooporque esse é o primeiro caminho absoluto que pode ser construído.

No entanto, se você executar:

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

O caminho retornado será /foo/testnovamente, porque esse é o primeiro caminho absoluto que pode ser formado da direita para a esquerda.

Se você não fornecer um caminho que especifique o diretório raiz, os caminhos dados à resolvefunção serão anexados ao diretório de trabalho atual. Portanto, se seu diretório de trabalho fosse /home/mark/project/:

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

resolve

/home/mark/project/test/back

Using __dirnameé o caminho absoluto para o diretório que contém o arquivo de origem. Quando você usa path.resolveou path.joineles retornarão o mesmo resultado se você der o mesmo caminho a seguir __dirname. Nesses casos, é realmente apenas uma questão de preferência.


25
Nit: __dirnameé o caminho absoluto para o diretório que contém o arquivo de origem que está sendo executado, não o diretório de trabalho atual . O primeiro será sempre o mesmo (a menos que você mova o arquivo); o último é um parâmetro de todo o processo que varia de acordo com a maneira como você ativou o nó e se o alterou ou não .
josh3736

2
Então, não há diferença entre __dirnamee path.resolve(__dirname)?
precisa saber é o seguinte

1
@georaldc: Encontrei um: node <<< "path = require ('path'); console.log (__ dirname); console.log (path.resolve (__ dirname))"
Colin

8
Detesto dizer isso, mas essa resposta realmente não faz sentido para mim e eu gostaria de receber alguns esclarecimentos. Você observa que path.resolve('/bar/bae', '/foo', 'test');essencialmente descarta o primeiro argumento porque /foo/test"é o primeiro caminho absoluto que pode ser formado da direita para a esquerda", mas você não explicou o porquê , então eu realmente não entendo a lógica no trabalho. Quero dizer, não tenho nenhuma visão da estrutura hipotética de diretório que você está usando no seu exemplo, portanto não consigo entender por que /bar/bae/foo/testé inválido.
temporary_user_name

3
@temporary_user_name A resposta está correta em relação path.resolveao comportamento aqui: path.resolveopera a partir do argumento mais à direita, movendo-se para a esquerda na lista de argumentos e precedendo o valor de cada argumento até um caminho absoluto (ou seja, um começando com o diretório raiz /ou [no Windows especificamente ] uma letra de unidade) é construída e, em seguida, retorna esse caminho. Ignora /bar/baeporque, a essa altura, já possui o caminho absoluto /foo/teste, portanto, não vê razão para ir mais longe.
21719 Jamie Ridding

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

vs.

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

path.joinconcatenará __dirnamequal é o nome do diretório do arquivo atual concatenado com valores de someedir com o separador específico da plataforma.

Enquanto que

path.resolveprocessará __dirname, somee dirda direita para a esquerda, precedendo-o pelo processamento.

se algum dos valores de someoudir corresponder a um caminho raiz, o caminho anterior será omitido e o processo será interrompido, considerando-o como raiz

Para entender melhor o conceito, deixe-me explicar um pouco mais detalhadamente da seguinte maneira:

O path.joinepath.resolve são dois métodos ou funções diferentes do módulo de caminho fornecido pelo nodejs.

Onde ambos aceitam uma lista de caminhos, mas a diferença vem no resultado, ou seja, como eles processam esses caminhos.

path.joinconcatena todos os segmentos de caminho fornecidos usando o separador específico da plataforma como um delimitador e normaliza o caminho resultante. Enquanto opath.resolve() processo a sequência de caminhos da direita para a esquerda, com cada caminho subsequente precedido até que um caminho absoluto seja construído.

Quando nenhum argumento é fornecido

O exemplo a seguir ajudará você a entender claramente os dois conceitos:

Meu nome de arquivo é index.jse o diretório de trabalho atual é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

Resultado

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

path.resolve()O método exibirá o caminho absoluto em que, como path.join()retornos. representando o diretório de trabalho atual se nada for fornecido

Quando algum caminho raiz é passado como argumentos

const path=require('path');

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

Resultado i

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

path.join()concatena apenas a lista de entrada com o separador específico da plataforma enquanto path.resolve()processa a sequência de caminhos da direita para a esquerda, com cada caminho subsequente precedido até que um caminho absoluto seja construído.


A questão era especificamente sobre path.join vs path.resolve com __dirname .
Estus Flask

Eu tinha atualizado resposta com base em seus comentários Obrigado pela atualização
samuelj90

3

do doc para path.resolve:

O caminho resultante é normalizado e as barras finais são removidas, a menos que o caminho seja resolvido para o diretório raiz.

Mas path.joinmantém barras à direita

assim

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

o que a palavra 'normalizado' significa neste contexto?
Apollo

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.