nodejs 当前文件路径_NodeJs的几种文件路径
上次寫刪除文件夾的時候用到了fs模塊,也集中用到了很多種路徑,當時就想寫一下,在Node中使用各種路徑的問題,于是就簡單寫了一下,可以從 這里 獲取demo源代碼。
剛寫Node的時候經(jīng)常會遇到這種情況:比如項目入口是app.js,而app.js并不一定在根目錄下,比如他在bin目錄下,到了啟動項目時,使用node /bin/app.js和進入bin文件夾直接node app.js總會有一個起不起來,都是些路徑找不到的錯誤,究其原因就是啟動應(yīng)用時執(zhí)行的目錄不同了,不過為什么啟動腳本的位置會有這么多影響呢,讓我們來總結(jié)一下。
對比常用的幾種路徑
Node 中的文件路徑大概有 __dirname,__filename,process.cwd(),./ 或者 ../。前三個都是絕對路徑,為了便于比較,./ 和 ../ 我們通過 path.resolve('./')來轉(zhuǎn)換為絕對路徑。先看一個簡單的例子。
假如我們有這樣的文件結(jié)構(gòu):
在 server.js 里編寫如下的代碼:1
2
3
4
5
6var path = require('path');
console.log(__dirname);
console.log(__filename);
console.log(process.cwd());
console.log(path.resolve('./'));
在 path-test 目錄下運行 node bin/server.js 得到的結(jié)果:
進入 bin 目錄下運行 node server.js 得到的結(jié)果:
現(xiàn)在我們可以總結(jié)下這幾個路徑的意思:1
2
3
4__dirname: Nodejs的一個全局變量,獲得當前執(zhí)行文件所在目錄的完整目錄名
__filename: Nodejs的一個全局變量,獲得當前執(zhí)行文件的帶有完整絕對路徑的文件名
process.cwd():Nodejs的全局變量process的一個方法,返回當前進程的工作目錄
./: 一般情況跟 process.cwd() 一樣,返回 node 命令運行時所在的文件夾的絕對路徑
注意__dirname得到的目錄和命令執(zhí)行所在的目錄、__filename得到的文件名和參數(shù)指定的文件名都不一定相同,因為可能在一個文件中調(diào)用了另一個目錄中的另一個文件。
更復雜的情況
我們把例子升級一下,在bin目錄下新建一個test.js:1
2
3
4
5
6
7var fs = require('fs');
require('./server.js');
fs.readFile('./server.js', function (err, data){
if (err) return console.log(err);
console.log(data);
});
現(xiàn)在目錄結(jié)構(gòu)如下:
我們這次先進入bin目錄執(zhí)行node test.js,得到的結(jié)果:
可以看到是正常的,然后我們退出bin目錄,在上一級執(zhí)行node bin/test.js,得到結(jié)果:
我們可以看到報錯了,但是require是OK的,只是fs.readFile時路徑出現(xiàn)了錯誤。從第一個例子我們可以知道,使用相對路徑出現(xiàn)錯誤是預期之內(nèi)的,因為在bin目錄外執(zhí)行時目錄下已經(jīng)沒有server.js這個文件了,但是為什么在require中使用相對路徑,就不受啟動應(yīng)用時執(zhí)行命令目錄不同的影響呢?實際上是require有自己的搜索機制,具體可以看require() 源碼解讀。
使用path模塊處理文件路徑
面對復雜的路徑問題,path模塊可以幫你規(guī)范化連接和解析路徑,還可以用于絕對路徑到對路徑的轉(zhuǎn)換、提取路徑的組成部分及判斷路徑是否存在等。常用的兩個命令:
path.join
path.join()方法可以連接任意多個路徑字符串,只是簡單的連接,不會看是否真的存在。1
2
3
4
5var path = require('path');
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')
// 連接后
'/foo/bar/baz/asdf'
path.resolve
path.resolve()方法可以將多個路徑解析為一個規(guī)范化的絕對路徑。其處理方式類似于對這些路徑逐一進行cd操作,與cd操作不同的是,這引起路徑可以是文件,并且可不必實際存在(resolve()方法不會利用底層的文件系統(tǒng)判斷路徑是否存在,而只是進行路徑字符串操作)。1path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile')
其處理方式類型于1
2
3
4
5cd foo/bar
cd /tmp/file/
cd ..
cd a/../subfile
pwd
如果解析的不是絕對路徑,path.resolve()會將當前工作目錄(非進程工作目錄)加到解析結(jié)果的前面。例如:1
2
3
4
5
6
7
8
9
10
11path.resolve('/foo/bar', './baz')
// 輸出結(jié)果為
'/foo/bar/baz'
path.resolve('/foo/bar', '/tmp/file/')
// 輸出結(jié)果為
'/tmp/file'
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')
// 當前的工作路徑是 /Users/tyb/workspace/NodeJs/path-test/bin,則輸出結(jié)果為
'/Users/tyb/workspace/NodeJs/path-test/bin/wwwroot/static_files/gif/image.gif'
兩者區(qū)別join只是把各個path片段連接在一起, resolve會把‘/’當成根目錄1
2path.join('/a', '/b') // 返回 '/a/b'
path.resolve('/a', '/b') // 返回 '/b'join直接拼接字段,resolve解析路徑,如果解析的不是絕對路徑,會在前面增加當前文件所在的目錄1
2path.join("a", "b1", "..", "b2") // 返回 'a/b2'
path.resolve("a", "b1", "..", "b2") // 返回 '/Users/tyb/workspace/NodeJs/path-test/bin/a/b2'
相同之處都會規(guī)范化路徑
都不會去驗證路徑是否真的存在
總結(jié)一下
最好只在 require() 時才使用相對路徑./或者../的寫法,其他地方一律配合path`模塊使用絕對路徑。
參考鏈接
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的nodejs 当前文件路径_NodeJs的几种文件路径的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql报错3534_win7下安装M
- 下一篇: java保留小数_(转)Java保留小数