【问题标题】:path.join vs path.resolve with __dirnamepath.join vs path.resolve with __dirname
【发布时间】:2016-12-30 20:24:53
【问题描述】:

在Node.js 中使用path.joinpath.resolve__dirname 来解析绝对路径时有区别吗?

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

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

对比

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

这两种方法都归一化路径。

【问题讨论】:

标签: node.js


【解决方案1】:

是的,功能之间存在差异,但在这种情况下您使用它们的方式将产生相同的结果。

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.resolvepath.join 时,如果您在__dirname 之后给出相同的路径,它们将返回相同的结果。在这种情况下,这实际上只是一个偏好问题。

【讨论】:

  • Nit: __dirname 是包含正在执行的源文件的目录的绝对路径,而不是当前工作目录。前者总是一样的(除非你移动文件);后者是 process-wide parameter,取决于您启动节点的方式以及您是否拥有 changed it
  • 那么__dirnamepath.resolve(__dirname)之间没有区别吗?
  • @georaldc: 我找到了一个:node
  • 我不想这么说,但这个答案对我来说真的没有任何意义,我希望能得到一些澄清。您说path.resolve('/bar/bae', '/foo', 'test'); 基本上丢弃了第一个参数,因为/foo/test“是第一个可以从右到左形成的绝对路径”,但是您没有解释为什么,所以我真的不不明白工作的逻辑。我的意思是我对您在示例中使用的假设目录结构没有任何看法,所以我无法理解为什么 /bar/bae/foo/test 无效。
  • @temporary_user_name 关于path.resolve 在此处的行为,答案是正确的:path.resolve 从最右边的参数开始操作,在参数列表中向左移动并将每个参数的值添加到绝对值之前路径(即以根目录/ 或[在Windows 中] 驱动器号开头的路径),然后返回该路径。它忽略了/bar/bae,因为到那时,它已经有了绝对路径/foo/test,因此没有理由再进一步了。
【解决方案2】:
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模块的两种不同的方法或功能。

两者都接受路径列表,但不同之处在于结果,即它们如何处理这些路径。

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 equivalent to __dirname

结果

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

path.resolve() 方法将输出绝对路径,而 path.join() 返回。如果未提供任何内容,则表示当前工作目录

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

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() 处理从右到左的路径序列,每个后续路径都在前面,直到构造出绝对路径。

【讨论】:

  • 这个问题具体是关于 path.join vs path.resolve with __dirname
  • 我已经根据您的 cmets 更新了答案,感谢您的更新
【解决方案3】:

来自path.resolve的文档:

生成的路径被规范化并删除尾部斜杠,除非路径被解析为根目录。

但是path.join 一直在尾部斜杠

所以

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

【讨论】:

【解决方案4】:

用最简单的术语:

当您使用path.resolve() 时,它会执行以下操作

from left to right-

  • 将最右边的参数与/ 直接与根路径连接以形成绝对路径(查看示例)
  • 然后将没有/ 的任何内容连接为目录

例如

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


使用join() 时,无论是否有/,都只是从左到右连接每个参数

path.join("/a", "b", "/c", "d")   simply returns   "\a\b\c\d"

【讨论】:

  • 直接用根路径创建一个绝对路径 - 它不只是连接,而是实际上考虑 /a 和 /b 绝对路径,Unix 的前缀是当前磁盘Windows 上的字母。
猜你喜欢
  • 1970-01-01
  • 2018-04-28
  • 2016-08-22
  • 2016-05-05
  • 1970-01-01
  • 2018-06-29
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多