path.resolve 与 path.join 的区别详解

发布于 2023-05-05 22:14:36 字数 4156 浏览 67 评论 0

配图源自 Freepik

相信大家一定用过 path.resolve()path.join(),特别是 Webpack、Rollup、Vite 等构建工具,再熟悉不过了。

path.resolve(__dirname, 'src/index.js')

像这个例子,用 path.join(__dirname, 'src/index.js') 所得到的结果也是完全一样的。
那么它俩究竟有何不同,在什么情况下使用才能体现出区别呢?

path.resolve

该函数接受「零或多个」字符串类型的路径参数,并返回一个 normalized 的「绝对路径」。

path.resolve(path1, path2, ..., pathN)

有以下几个特点:

  • 其中 zero-length 的参数会被忽略,比如 ''(空字符串)和 '.'(表示当前目录)。
  • / 开头的参数会被当作文件系统根路径,不以 .././ 开头的参数会被当作是目录。
  • 若参数不为字符串类型,则会抛出 TypeError。
  • 若不传递任何参数时,返回 Node 进程的当前工作目录。因此 path.resolve() === process.cwd() 结果为 true
  • 结果返回之前其内部也会做类似 path.normalize() 的路径规范化处理。

看例子:

path.resolve('/a', 'b', 'c') // return: "/a/b/c"
path.resolve('/a', '/b', 'c') // return: "/b/c"
path.resolve('/a', '/b', '/c') // return: "/c"

其实在官网就描述得很清晰了。无非就是,「从右到左」一个一个参数开始解析,每解析一个就将其加到原来路径的「前面」,参数之间使用平台对应的路径分隔符连接。若能拼接成一个绝对路径,就停止解析并立即返回。如果将所有参数都解析完,仍然无法拼凑得出一个绝对路径,那么就讲这些参数的结果拼到当前工作目录中,以得出绝对路径。

因此,上述示例内部解析过程如下:

"c" -> "b/c" -> "/a/b/c"
"c" -> "/b/c"
"/c"

假设有 path.resolve('a', 'b'),就是 "b" -> "a/b" -> "process.cwd()/a/b" 的过程,相当于 path.resolve(process.cwd(), 'a', 'b')。其中 proccess.cwd() 就是当前工作目录。

**个人认为,更好的理解倒是「从左往右」看,将 path.resolve() 方法看作 Shell 的 cd 操作,只是前者不管文件系统是否存在此目录或文件。**如伪代码:

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

// 相当于
$ cd /a; cd /b; cd c

或许 path.resolve() 称为 path.cd() 更让人豁然开朗吧。

path.join

该函数接受「零或多个」字符串类型的路径参数,返回一个所有参数拼接起来的(相对/绝对)路径。

path.join(path1, path2, ..., pathN)

有以下几个特点:

  • 其中 zero-length 的参数会被忽略,比如 ''(空字符串)和 '.'(表示当前目录)。
  • ../ 开头的参数认为是上一级目录。
  • 第一个参数若以 / 会被认为是根目录,其他以 / 开头的参数作用与 ./ 相同。
  • 若参数不为字符串类型,则会抛出 TypeError。
  • 若不传递任何参数时,返回 .(当前目录)。
  • 结果返回之前其内部也会做类似 path.normalize() 的路径规范化处理。

看例子:

path.join('a', 'b', 'c') // return: "a/b/c"
path.join('/a', 'b', 'c') // return: "/a/b/c"
path.join('/a', '/b', 'c') // return: "/a/b/c"
path.join('/a', '/b', '/c') // return: "/a/b/c"

其实不用看那么多,换个角度去理解或许更清晰,两个步骤:

  1. 用相加运算符 + 将所有参数连接起来(参数之间用 / 连接)。
  2. 使用 path.normalize() 对相加后的字符串路径作规范化处理。

有人可能会问,path.normalize() 又是干嘛的啊。很简单:把 ./../ 翻译成对应路径;把多余无用的路径连接符干掉(如 a//b => a/b);将路径连接符转换为特定平台的连接符(比如 Unix 的 /,Windows 的 \)。

因此,可以把 path.join('/a', '/b', 'c') 理解成这样:

let args = ['/a', '/b', 'c']
let str = args.join('/') // "/a//b/c"
str = path.normalize(str) // "/a/b/c"

区别

以几个示例做总结:

无参数时

path.resolve() // 返回当前工作目录,相当于 `process.cwd()`,是绝对路径。
path.join() // 返回 `.`(当前目录),是相对路径。

请注意「当前工作目录」和「当前目录」的区别。

有多个参数,且中间参数以 / 开头

path.resolve('/a', '/b', 'c') // 返回 `/b/c`,绝对路径。
path.join('/a', '/b', 'c') // 返回 `/a/b/c`,绝对路径。
path.resolve('a', '/b', 'c') // 返回 `/b/c`,绝对路径。
path.join('a', '/b', 'c') // 返回 `a/b/c`,相对路径。

相信大家都懂了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

请别遗忘我

暂无简介

0 文章
0 评论
24 人气
更多

推荐作者

懂王

文章 0 评论 0

清秋悲枫

文章 0 评论 0

niceone-tech

文章 0 评论 0

小伙你站住

文章 0 评论 0

刘涛

文章 0 评论 0

南街九尾狐

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文