前言
在沒有相關經驗的同學,在學習webpack和使用node時,經常會遇到__dirname
path.resolve
等,這時往往會一臉懵逼這些都是什麼,幹嘛的,為什麼這些資料和書都完全不提,難道就我不知道 -。-
其實path模組是很常見很通用的。這裡我就簡單總結一些在專案中經常會用到的方法,幫助大家儘快掌握。
1, 獲取規範化的路徑/路徑/檔名/副檔名
- 獲取規範化的路徑:path.normaliz(filepath)
- 獲取路徑:path.dirname(filepath)
- 獲取檔名:path.basename(filepath)
- 獲取副檔名:path.extname(filepath)
1.1獲取規範化的路徑格式
- path.normalize() 方法會規範化給定的 path,並解析 '..' 和 '.' 片段。
- 當發現多個連續的路徑分隔符時(如 POSIX 上的 / 與 Windows 上的 \ 或 /),它們會被單個的路徑分隔符(POSIX 上是 /,Windows 上是 \)替換。 末尾的多個分隔符會被保留。
- 如果 path 是一個長度為零的字串,則返回 '.',表示當前工作目錄。
path.normalize('C:\\temp\\\\foo\\bar\\..\\');
// 返回: 'C:\\temp\\foo\\'
var myPath = path.normalize(__dirname + '/test/a//b//../c/helloWorld.js');
console.log(myPath); //windows: E:\workspace\NodeJS\app\fs\test\a\c\helloWorld.js
複製程式碼
PS:
- Windows系統下,'/'和'\'均可以表示路徑,但是在網路連結裡只能用'/'表示路徑。
- 如果 path 不是一個字串,則丟擲 TypeError。
1.2 獲取所在路徑
例子如下:
var path = require('path');
var filepath = '/tmp/demo/js/test.js';
// 輸出:/tmp/demo/js
console.log( path.dirname(filepath) );
var myPath = path.dirname(__dirname + '/test/util/helloWorld.js');
console.log(myPath);
//Users/cayley/Documents/webpack-demo/test/util
複製程式碼
__dirname是node.js中的一個全域性變數,用來獲取當前模組檔案所在目錄的完整絕對路徑
1.3 獲取檔名
嚴格意義上來說,path.basename(filepath) 只是輸出路徑的最後一部分,並不會判斷是否檔名。
但大部分時候,我們可以用它來作為簡易的“獲取檔名“的方法。
var path = require('path');
// 輸出:test.js
console.log( path.basename('/tmp/demo/js/test.js') );
// 輸出:test
console.log( path.basename('/tmp/demo/js/test/') );
// 輸出:test
console.log( path.basename('/tmp/demo/js/test') );
複製程式碼
如果只想獲取檔名,單不包括檔案擴充套件呢?可以用上第二個引數。
// 輸出:test
console.log( path.basename('/tmp/demo/js/test.js', '.js') );
複製程式碼
1.4 獲取副檔名
簡單的例子如下:
var path = require('path');
var filepath = '/tmp/demo/js/test.js';
// 輸出:.js
console.log( path.extname(filepath) );
複製程式碼
更詳細的規則是如下:(假設 path.basename(filepath) === B )
-
從B的最後一個
.
開始擷取,直到最後一個字元。 -
如果B中不存在
.
,或者B的第一個字元就是.
,那麼返回空字串。
直接看官方文件的例子
path.extname('index.html')
// returns '.html'
path.extname('index.coffee.md')
// returns '.md'
path.extname('index.')
// returns '.'
path.extname('index')
// returns ''
path.extname('.index')
// returns ''
複製程式碼
2, 路徑組合
-
path.join([...paths])
-
path.resolve([...paths])
2.1 path.join([...paths])
path.join()
方法使用平臺特定的分隔符把全部給定的 path 片段連線到一起,並規範化生成的路徑。
長度為零的 path 片段會被忽略。 如果連線後的路徑字串是一個長度為零的字串,則返回 '.',表示當前工作目錄。
引數說明:
...paths <string>
一個路徑片段的序列。
返回:
把paths
拼起來,然後再normalize一下。意思就是會先把路徑拼接在一起,然後進行規範化,返回正確的路徑。
例子如下:
var path = require('path');
// 輸出 '/foo/bar/baz/asdf'
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
複製程式碼
path定義的虛擬碼如下:
module.exports.join = function(){
var paths = Array.prototye.slice.call(arguments, 0);
return this.normalize( paths.join('/') );
};
複製程式碼
更多例子:
path.join('/foo', 'bar', 'baz/asdf', 'quux', '.'); // 返回 /foo/bar/baz/asdf/quux, "."和"/"沒什麼影響
path.join('/foo', './bar', 'baz/asdf', '.', 'quux'); // 返回 /foo/bar/baz/asdf/quux
path.join('/foo', './bar', './baz/asdf', 'quux', '..'); // 返回 /foo/bar/baz/asdf
path.join('/foo', 'bar', 'baz/asdf', '.', '.'); // 返回 /foo/bar/baz/asdf
path.join('/foo', 'bar', 'baz/asdf', 'quux'); // 返回 /foo/bar/baz/asdf/quux
path.join('/foo', 'bar', 'baz/asdf', '..', '..'); // 返回 /foo/bar
複製程式碼
2.2 path.resolve([...paths])
智慧解析絕對路徑 path.resolve() 方法會把一個路徑或路徑片段的序列解析為一個絕對路徑。層級關係是從左到右的.
規則:
1\. 給定的路徑的序列是從右往左被處理的,後面每個 path 被依次解析,直到構造完成一個絕對路徑。
2\. 如果處理完全部給定的 path 片段後還未生成一個絕對路徑,則當前工作目錄會被用上。
3\. 生成的路徑是規範化後的,且末尾的斜槓會被刪除,除非路徑被解析為根目錄。
4\. 長度為零的 path 片段會被忽略。
5\. 如果沒有傳入 path 片段,則 path.resolve() 會返回當前工作目錄的絕對路徑。
6\. path.resolve將以/開始的路徑片段作為根目錄,在此之前的路徑將會被丟棄,就像是在terminal中使用cd命令一樣。而path.join只是簡單的將該路徑片段進行拼接
複製程式碼
比如 path.resolve('/foo/bar', './baz')
可以看成下面命令的結果
cd /foo/bar
cd ./baz
複製程式碼
更多對比例子如下:
var path = require('path');
// 假設當前工作路徑是 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path
// 輸出 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path
console.log( path.resolve('') )
// 輸出 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path
console.log( path.resolve('.') )
// 輸出 /foo/bar/baz
console.log( path.resolve('/foo/bar', './baz') );
// 輸出 /foo/bar/baz
console.log( path.resolve('/foo/bar', './baz/') );
// 輸出 /tmp/file
console.log( path.resolve('/foo/bar', '/tmp/file/') );
// 輸出 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path/www/js/mod.js
console.log( path.resolve('www', 'js/upload', '../mod.js') );
複製程式碼
更多例子:
// 當前工作目錄與當前檔案路徑(F:/1/2/task6/test/dist)有區別
path.resolve(); // F:/1/2/task6/test 當前工作目錄的絕對路徑
path.resolve('./a'); // F:/1/2/task6/test/a
path.resolve('../a'); // F:/1/2/task6/a
path.resolve('.'); // F:/1/2/task6/test
path.resolve('..'); // F:/1/2/task6
path.resolve('/')); // F:/
path.resolve('./a','../c/d'); // F:/1/2/task6/test/c/d
path.resolve('./a','./c/d'); // F:/1/2/task6/test/a/c/d
path.resolve('/a','../c/d'); // F:c/d
path.resolve('/a','./c/d'); // F:/a/c/d
path.resolve('./a','/b','./c/d'); // F:/b/c/d
path.resolve('a','b','c/d'); // F:/1/2/task6/test/a/b/c/d
path.resolve('./a','./b','c/d'); // F:/1/2/task6/test/a/b/c/d
path.resolve('./a','/b','c/d'); // F:/b/c/d
path.resolve('./a/b','..','c/d'); // F:/1/2/task6/test/a/c/d
path.resolve('./a','..','c/d'); // F:/1/2/task6/test/c/d
複製程式碼
3, 獲取相對路徑
介面:path.relative(from, to)
描述:從from
路徑,到to
路徑的相對路徑。
邊界:
-
如果
from
、to
指向同個路徑,那麼,返回空字串。 -
如果
from
、to
中任一者為空,那麼,返回當前工作路徑。
上例子:
var path = require('path');
var p1 = path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb');
console.log(p1); // 輸出 "../../impl/bbb"
var p2 = path.relative('/data/demo', '/data/demo');
console.log(p2); // 輸出 ""
var p3 = path.relative('/data/demo', '');
console.log(p3); // 輸出 "../../Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path"
複製程式碼