常用的前端路径处理

705 阅读3分钟

两个重要路径

对由于一个可执行文件来说 它有两个path路径比较重要:

当前文件位置

比如 我有一个 /Users/dyf/workspace/path-demo/helloworld.js 文件

毫无疑问这个绝对路径就是我当前这个helloworld.js 的文件位置。

假设我要在执行这个helloworld脚本时访问 取得这个路径那么 我们可以:

  • 如果是commonjs文件 那么可以直接使用 __dirname
  • 如果是esm文件 import path模块 使用 path.dirname()

当前文件的执行目录

执行目录对于js文件来说也是一个很重要的路径。

比如 上面这个例子

/Users/dyf/workspace/path-demo/helloworld.js

如果我在 /Users/dyf/workspace/path-demo/ 此目录底下执行 node helloworld.js

那么此时当前js文件的执行目录就是 /Users/dyf/workspace/path-demo

然后我 cd ../ 来到上一层 执行 node path-demo/helloworld.js

执行目录就变成了 /Users/dyf/workspace/

两种方式取得这个执行目录

  • process.cwd()
  • path.resolve()

Node Path 模块常用API

path模块有一大堆api,官方文档也写的很过于官方容易让人一头雾水,在明确了上面两个路径之后,再来看/使用 Node中 path模块处理路径就变得比较简单了

最令人迷惑的两个api

path.resolve()

用法:path.resolve([from ...], to)

总是返回一个绝对路径

如果什么都不传 上面已经提到了相当于 返回当前文件的执行目录

path.resolve() === process.cwd()

如果传了多个参数 那么就相当于从左往右 逐个对这些参数执行 cd

举个🌰

还是上面那个helloworld.js

/Users/dyf/workspace/path-demo/ 目录下执行它

// helloworld.js
const path = require('path')
console.log('path.resolve()',path.resolve('../a','..','../b','./c'))

相当于执行

#  /Users/dyf/workspace/path-demo/

cd ../a     # /Users/dyf/workspace/a

cd ..       # /Users/dyf/workspace/

cd ../b     # /Users/dyf/b

cd ./c 			# /Users/dyf/b/c

需要注意的是 resolve方法并不会判断这个目录是否真实存在,只会做路径的解析


path.join()

用法:path.join([from ...], to)

这个用法看起来和resolve一样 但还是有许多注意点

目前网上很多文章都 把这个api解释成:

1.把路径连接起来

2.做规范化处理(官方文档中说的是normalize)


这个说法会让人误以为join确实重点只是拼接,而忽略了它的normalize

还是要来看🌰

// helloworld.js
const path = require('path')
console.log('path.join() - 1',path.join('../a','b','c','d')) // '../a/b/c/d'
console.log('path.join() - 2',path.join('../a','./b','../c','d')) // '../a/c/d'

上面这个示例 1 比较容易理解 就是把路径拼起来 '../a/b/c/d'

从示例里我们可以看出来join 会把后面的参数会加上 / 然后再拼接到第一个路径后面去 难道这就是 normalize 么?

再看示例 2

先用/拼接起来

 '../a/./b/../c/d'

最后输出的却是 ../a/c/d

b 跑哪去了?

看到这里我们可以发现其实 join方法 其实也同样适用上面 resolve中的 cd 大法

cd ../a  # ../a
cd ./b   # ../a/b
cd ../c  # ../a/c
cd d     # ../a/c/d

到这里我们终于知道所谓的 normalize 具体指的是什么样的了

因此,其实 resolve 和 join 的区别就在于

resolve方法会在 当前文件的 执行目录 基础上拼接规范化化 (cd)后面的参数并返回一个 绝对路径

而join方法 会往第一个参数后面拼接规范化(cd)后面的参数,是相对路径还是绝对路径取决你的第一个路径参数类型。

其他常用路径api

path.dirname()

第一部分已经提到那就是 这个文件的绝对路径

process.cwd()

文件的执行目录 === process.resolve()

path.basename()

path.extname()

这两个比较简单也比较常用看示例就能明白

const path = require('path'); 
  
path.basename('/home/user/bash/index.txt');  // index.txt
path.basename('/home/user/bash/index.txt', '.txt');  // index 第二个参数可以理解为replace掉

path.extname("/home/user/bash/hello.txt"); // .txt
path.extname("/home/user/bash/readme.md"); // .md

更多查阅 http://nodejs.cn/api/path.html