1、挖坑 & 掉坑:
緣起一段這樣的代碼:node
fs.readFile('./docs/use.md', function (err, buffer) { if (err) { return console.log('error: ', err); } console.log('OK'); });
本地運行時一切 OK,線上部署時卻死活找不到 ./docs/use.md 這個文件,後來才發現是由於線上啓動應用時不是從當前目錄啓動了,不過爲何啓動腳本的位置也會影響這個路徑呢,且往下看。app
2、填坑:
Node 中的文件路徑大概有 __dirname, __filename, process.cwd(), ./ 或者 ../,前三個都是絕對路徑,爲了便於比較,./ 和 ../ 咱們經過 path.resolve('./')來轉換爲絕對路徑。ui
先看一個簡單的栗子:code
假如咱們有這樣的文件結構:部署
app/ -lib/ -common.js -model -task.js -test.js
在 task.js 裏編寫以下的代碼:it
var path = require('path'); console.log(__dirname); console.log(__filename); console.log(process.cwd()); console.log(path.resolve('./'));
在 model 目錄下運行 node task.js 獲得的輸出是:io
/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,獲得的輸出是:console
/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,咱們能夠得出一些膚淺的結論了:function
__dirname: 老是返回被執行的 js 所在文件夾的絕對路徑
__filename: 老是返回被執行的 js 的絕對路徑
process.cwd(): 老是返回運行 node 命令時所在的文件夾的絕對路徑
./: 跟 process.cwd() 同樣、同樣、同樣的嗎?
我明明記得在 require('../lib/common') 裏一直都是各類相對路徑寫,也沒見報什麼錯啊,咱們還在再來個栗子吧,仍是上面的結構,'model/task.js' 裏的代碼改爲:test
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() 效果相同,是相對於啓動腳本所在目錄的路徑。
3、總結:
只有在 require() 時才使用相對路徑(./, ../) 的寫法,其餘地方一概使用絕對路徑,以下:
// 當前目錄下 path.dirname(__filename) + '/test.js'; // 相鄰目錄下 path.resolve(__dirname, '../lib/common.js');