使用__dirname的path.join与path.resolve


142

同时 使用path.joinpath.resolve__dirname来解析Node.js中的绝对路径?

这样使用时,是否应该首选其中之一(绝对路径分辨率为用例的90%)?

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

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

两种方法都将路径标准化。

这不是该问题的重复项,因为接受的答案是错误的。


这个问题是正在讨论的元
尼诺Filiu

Answers:


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 = require('path'); console.log(__ dirname); console.log(path.resolve(__ dirname))”
Colin

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);

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

path.join将串联在一起__dirname,这是当前文件的目录名,其值与somedir特定于平台的分隔符。

在哪里

path.resolve将处理__dirnamesomedir即由右至左通过处理它前面加上它。

如果根路径的任何值somedir对应于根路径,则将忽略先前的路径,并通过将其视为根来处理其余部分

为了更好地理解这个概念,让我对这两者进行更详细的解释,如下:

path.joinpath.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()return。如果未提供任何内容,则表示当前工作目录

当一些根路径作为参数传递时

const path=require('path');

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

结果我

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

path.join()仅将输入列表与特定于平台的分隔符连接在一起,同时path.resolve()处理从右到左的路径顺序,并在每个后续路径之前添加一条路径,直到构造出绝对路径为止。


问题特别是关于__dirname的path.join 与path.resolve的关系
Estus Flask

我已经根据您的评论更新了答案,感谢您的更新
samuelj90 '17

3

从doc中获取path.resolve

除非将路径解析到根目录,否则将对生成的路径进行规范化并删除尾部的斜杠。

path.join总是尾随斜杠

所以

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

在这种情况下,“标准化”一词是什么意思?
阿波罗

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.