回顧Node檔案路徑
node中路徑在很多地方都有使用,基礎到不起眼。但有時候就是不起眼的東西,會在你不輕易間跳出來給你上一課。
想起來複習一下檔案路徑的起因,是因為最近整理了一下專案結構,調整了目錄。這也是基於對現代IDE的信任(都是IDE給慣的病),IDE會處理好路徑問題,所以我只管拖動,他負責善後。可是沒想到啊,我盡然忘了他不會處理path.join(__dirname, '/../logs/')
這種方式的路徑。
於是在程式碼運行了兩天後,發現怎麼project/logs
的裡面的日誌停更了兩天,是拖更嗎?這不行啊,我得催催更。
這才發現logger
中介軟體的目錄也變了,但是處理的路徑不對,logs
也沒有拖更,只是另尋他處了。
log4js.configure({ appenders: { console: { type: 'console' }, koa: { type: 'dateFile', filename: path.join(__dirname, '/../logs/'), // 問題出在我身上 pattern: 'yyyy-MM-dd.log', alwaysIncludePattern: true } }, categories: { default: { appenders: ['console', 'koa'], level: 'debug' } } }); 複製程式碼
那肛肛好複習一下檔案路徑吧。
複習
概念
node中分為相對路徑 和絕對路徑 兩種,相對路徑表示當前目錄層級相對於目標的位置,而絕對路徑表示目標當前所在的位置。
相對路徑:
-
./
當前目錄,../
上層目錄,...
絕對路徑
-
__dirname
被執行的js
所在目錄 的絕對路徑 -
__filename
被執行的js
的絕對路徑 -
process.cwd()
當前node
命令執行時所在的資料夾的絕對路徑
ofollow,noindex">
path
路徑
-
path.join([...paths])
使用平臺特定的分隔符把所有path
片段連線到一起,並規範化生成的路徑 -
path.resolve([...paths])
將路徑或路徑片段的序列處理成絕對路徑。指定的路徑序列是從右往左開始處理的,後面的path
被依次處理,直到構造完絕對路徑。 例如,指定的路徑片段序列為:/foo、/bar、baz
,則呼叫path.resolve('/foo', '/bar', 'baz')
會返回/bar/baz
// join path.join('/foo', 'bar', 'baz/asdf', 'quux', '..'); // 返回: '/foo/bar/baz/asdf' path.join('foo', {}, 'bar'); // 丟擲 'TypeError: Path must be a string. Received {}' // resolve path.resolve('/foo/bar', './baz'); // 返回: '/foo/bar/baz' path.resolve('/foo/bar', '/tmp/file/'); // 返回: '/tmp/file' path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif'); // 如果當前工作目錄是 /home/myself/node,則返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'。 複製程式碼
示例
在logger.js
的檔案裡寫下如下程式碼:
// 所在:/Users/simon/workspace/Inspiration/FitNoteServer/src/util/logger.js console.log(__dirname); console.log(process.cwd()); console.log(__filename); console.log('----------------------'); console.log(path.join(__dirname, '/')); console.log(path.join(__dirname, '../logs/')); console.log(path.join(__dirname, '../../logs')); console.log('----------------------'); console.log(path.resolve(__dirname, '/')); console.log(path.resolve(__dirname, '../logs/')); console.log(path.resolve(__dirname, '../../logs')); 複製程式碼
然後分別在不同目錄下啟動專案:
# workspace/Inspiration/FitNoteServer ▶ node src/index.js /Users/simon/workspace/Inspiration/FitNoteServer/src/util /Users/simon/workspace/Inspiration/FitNoteServer /Users/simon/workspace/Inspiration/FitNoteServer/src/util/logger.js ---------------------- /Users/simon/workspace/Inspiration/FitNoteServer/src/util/ /Users/simon/workspace/Inspiration/FitNoteServer/src/logs/ /Users/simon/workspace/Inspiration/FitNoteServer/logs ---------------------- / /Users/simon/workspace/Inspiration/FitNoteServer/src/logs /Users/simon/workspace/Inspiration/FitNoteServer/logs # Inspiration/FitNoteServer/src ▶ node index.js /Users/simon/workspace/Inspiration/FitNoteServer/src/util /Users/simon/workspace/Inspiration/FitNoteServer/src /Users/simon/workspace/Inspiration/FitNoteServer/src/util/logger.js ---------------------- /Users/simon/workspace/Inspiration/FitNoteServer/src/util/ /Users/simon/workspace/Inspiration/FitNoteServer/src/logs/ /Users/simon/workspace/Inspiration/FitNoteServer/logs ---------------------- / /Users/simon/workspace/Inspiration/FitNoteServer/src/logs /Users/simon/workspace/Inspiration/FitNoteServer/logs 複製程式碼
重點
上面兩個程式碼片段可以清楚的看到node
執行目錄不同對相對路徑的影響,相對路徑./
跟process.cwd()
相同,都是當前node
命令執行時所在的資料夾的絕對路徑。
而node
中,使用require
時可以忽略這點,你可以在require
中使用相對路徑,但是在其他的地方都需要使用絕對路徑。因為require
內部的路徑始終相對於你呼叫它的檔案,它與你的工作目錄無關。
總結
在專案中要格外注意相對路徑與絕對路徑,除了require()
其他地方路徑都要使用絕對路徑。
而絕對路徑要注意path.join
與path.resolve
的區別,同時注意專案啟動時node
執行的位置。