两个重要路径
对由于一个可执行文件来说 它有两个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