node的核心模块path中有两个方法join和resolve,很多时候会发现这两个方法可以互相替换,也不会出错,因此记录一下这两个的区别。
path.join([...path])
官网描述:path.join() 方法会将所有给定的 path 片段连接到一起(使用平台特定的分隔符作为定界符),然后规范化生成的路径。
由于windows和linux系统下文件路径分隔符表示不同,windows使用"",linux使用"/",因此为了考虑兼容平台,node使用path模块下的方法对其进行拼接,内部会做兼容处理。
path.join
方法,抛开path,join就是指对字符进行拼接,将path.join()方法中的参数进行拼接,然后处理成路径返回。
看例子:
console.log(path.join('a', 'b', 'c')); // a/b/c
console.log(path.join('a', '/b', '/c')); // a/b/c
输出是一样的,因为它不仅仅是做字符拼接,还做了规范化路径处理。
console.log(path.join('a', '/b', '/c')); // a/b/c
console.log(path.join('a', '../b', '/c')); // b/c
可以看出对其中字符进行了解析,会根据路径规则解析后再拼接返回规范化路径。
相对来说path.join()
方法是比较好理解的.
path.resolve([...paths])
官网描述:path.resolve方法会将路径或路径片段的序列解析为绝对路径。
注意:
- 给定的路径序列会从右到左进行处理,后面的每个 path 会被追加到前面,直到构造出绝对路径
- 如果在处理完所有给定的 path 片段之后还未生成绝对路径,则会使用当前工作目录
- 生成的路径会被规范化,并且尾部的斜杠会被删除(除非路径被解析为根目录)
- 零长度的 path 片段会被忽略。
- 如果没有传入 path 片段,则 path.resolve() 会返回当前工作目录的绝对路径。
根据以上几点总结一下:path.resolve()方法无论如何会返回一个绝对路径,什么样的路径是绝对路径?以'/'
开头的路径是绝对路径。那就是说在解析中,从右往左,当遇到 '/'
开头的字符时,立即停止解析,直接返回解析好的路径。
console.log(path.resolve('/a', '/b')) // /b 解析到第一个/b 直接返回 /b
console.log(path.resolve('/a', 'b')) // /a/b 解析到/a 将解析后的/a/b返回
console.log(path.resolve('a', 'b', '/')) // / 解析到 / 直接返回不再进行
console.log(path.resolve('a', 'b')) // /Users/tianleilei/Desktop/testProject/node/a/b 未解析到 / 所以使用到当前工作目录
console.log(path.resolve('/a', '../b')) // /b 遵循路径级别规则,解析到/a停止,当解析../向上一级,返回/b
相对来说path.resolve方法比较难记,但是理解核心path.resolve()方法无论如何会返回一个绝对路径这样就会好记一些。
可以总结如下记忆:
- 从后向前看
- 字符以 / 开头不会拼接直接返回,因为已经是绝对路径(绝对路径就结束)
- 字符以 ../ 开头拼接前面的路径,且不含最后一节字符(路径解析规则)
- 字符以 ./ 开头直接拼接前面的路径(路径解析规则)
- 如果在处理完所有给定的 path 片段之后还未生成绝对路径,则再加上当前工作目录(最终要绝对路径)
在使用中,一般都是配合__dirname生成绝对路径
console.log(path.join(__dirname, './a')); // /Users/tianleilei/Desktop/testProject/node/a
console.log(path.resolve(__dirname, './a')); // /Users/tianleilei/Desktop/testProject/node/a
console.log(path.join(__dirname, '../a')); // /Users/tianleilei/Desktop/testProject/a
console.log(path.resolve(__dirname, '../a')); // /Users/tianleilei/Desktop/testProject/a
结果是一样的,前端一般在webpack配置路径的时候会用到,两个都可以用。