Node 中的文件路徑大概有?__dirname
,?__filename
,?process.cwd()
,?./
?或者?../
,前三個都是絕對路徑,為了便于比較,./
?和?../
?我們通過?path.resolve('./')
來轉換為絕對路徑。
先看一個簡單的栗子:
假如我們有這樣的文件結構:
app/-lib/-common.js-model-task.js-test.js
在 task.js 里編寫如下的代碼:
var path = require('path');console.log(__dirname);
console.log(__filename);
console.log(process.cwd());
console.log(path.resolve('./'));
在?model
?目錄下運行?node task.js
?得到的輸出是:
/Users/guo/Sites/learn/app/model
/Users/guo/Sites/learn/app/model/task.js
/Users/guo/Sites/learn/app/model
/Users/guo/Sites/learn/app/model
然后在?app
?目錄下運行?node model/task.js
,得到的輸出是:
/Users/guo/Sites/learn/app/model
/Users/guo/Sites/learn/app/model/task.js
/Users/guo/Sites/learn/app
/Users/guo/Sites/learn/app
那么,不好意思不是問題來了~T_T,我們可以得出一些膚淺的結論了:
- __dirname: 總是返回被執行的 js 所在文件夾的絕對路徑
- __filename: 總是返回被執行的 js 的絕對路徑
- process.cwd(): 總是返回運行 node 命令時所在的文件夾的絕對路徑
- ./: 跟 process.cwd() 一樣、一樣、一樣的嗎?
我明明記得在?require('../lib/common')
?里一直都是各種相對路徑寫,也沒見報什么錯啊,我們還在再來個栗子吧,還是上面的結構,'model/task.js' 里的代碼改成:
var fs = require('fs');
var common = require('../lib/common');fs.readFile('../lib/common.js', function (err, data) {if (err) return console.log(err);console.log(data);
});
在 model 目錄下運行?node task.js
,一切 Ok,沒有報錯。然后在 app 目錄下運行?node model/task.js
,然后很果斷滴報錯了:
那么這下問題真的都是來了,按照上面的理論,在 app 下運行時,../lib/common.js
?會被轉成?/Users/guo/Sites/learn/lib/common.js
,這個路徑顯然是不存在的,但是從運行結果可以看出?require('../lib/common')
?是 OK 的,只是 readFile 時報錯了。
那么關于?./
?正確的結論是:
在?require()
?中使用是跟?__dirname
?的效果相同,不會因為啟動腳本的目錄不一樣而改變,在其他情況下跟?process.cwd()
?效果相同,是相對于啟動腳本所在目錄的路徑。
三、總結:
只有在?require()
?時才使用相對路徑(./, ../) 的寫法,其他地方一律使用絕對路徑,如下:
// 當前目錄下
path.dirname(__filename) + '/test.js';
// 相鄰目錄下
path.resolve(__dirname, '../lib/common.js');
四、參考鏈接:
- What is the difference between __dirname and ./ in node.js
- nodejs API
- 路徑處理模塊path總結