nodejs的路徑問題的解決
最近公司的一個(gè)開發(fā)項(xiàng)目,后端用的是nodejs。這兩天需要打包給客戶演示,就讓公司一個(gè)小伙把之前3D機(jī)房的打包工具移植過來。打包之后,發(fā)現(xiàn)原本在開發(fā)環(huán)境下的跑的好好的項(xiàng)目,不能訪問了。出現(xiàn)項(xiàng)目的首頁(yè)不能訪問的問題:
can not get file index.html
express.static
問題出在哪兒?
nodejs后端的用了express,index.html是一個(gè)靜態(tài)文件。我們知道,通過 Express 內(nèi)置的 express.static 可以方便地托管靜態(tài)文件,例如圖片、CSS、JavaScript 文件等。
將靜態(tài)資源文件所在的目錄作為參數(shù)傳遞給 express.static 中間件就可以提供靜態(tài)資源文件的訪問了。例如,假設(shè)在 public 目錄放置了圖片、CSS 和 JavaScript 文件,可以使用如下代碼:
app.use(express.static('public'));
所以,找到項(xiàng)目中的代碼,查看static調(diào)用的地方,和上面一行代碼很一樣:
app.use(express.static('public'));
到此,我已經(jīng)發(fā)現(xiàn)了問題,我告訴小伙伴,這個(gè)地方不用相對(duì)路徑可以解決這個(gè)問題。由于打包時(shí)間限制,我讓小伙伴先簡(jiǎn)單處理下,打完包之后,在來整理下思路:
app.use(express.static('resource/public'));
當(dāng)然最重要的是,這個(gè)問題其實(shí)不難,自己多鉆研下,很容易發(fā)現(xiàn)問題,也就不會(huì)出這個(gè)問題,所以小伙伴自己打手心吧。
恩,你沒看錯(cuò),這個(gè)地方還是相對(duì)目錄。后續(xù)產(chǎn)品中會(huì)改成比較好的一種情況。
express.static方法解析
事實(shí)上,express.static方法如果傳入的是相對(duì)路徑,express會(huì)自己把他轉(zhuǎn)換為絕對(duì)路徑,我們可以查看下源代碼,在express.js找到如下代碼:
exports.static = require('serve-static');
說明static 調(diào)用了serve-static這個(gè)包,直接找到這個(gè)包,查看index.js, 可以看到代碼,下面列出重要的兩行
...
var resolve = require('path').resolve
...
opts.root = resolve(root)
...
這兩行就是,express把相對(duì)目錄轉(zhuǎn)換成絕對(duì)目錄的代碼,可以看出,最終使用的path這個(gè)內(nèi)置對(duì)象的resolve方法,繼續(xù)往下看。
path對(duì)象的resolve方法
直接查看這個(gè)方法的api文檔,如下:https://nodejs.org/api/path.html#path_path_resolve_paths
下面是這個(gè)方法的解釋:
The path.resolve() method resolves a sequence of paths or path segments into an absolute path.
啥意思呢? 就是這個(gè)方法把一系列的paths或者path segments 組織成一個(gè)絕對(duì)路徑,比如
path.resolve('/foo','bar');
// return /foo/bar
詳細(xì)的說明請(qǐng)自行參考文檔,這個(gè)地方有一句話需要特別注意:
If after processing all given path segments an absolute path has not yet been generated, the current working directory is used.
啥意思,就是如果處理完了所有的path segments,也沒有生成一個(gè)絕對(duì)路徑, 就要使用 當(dāng)前工作目錄(current working directory)。比如:
path.resolve('bar');
// 加上 /Users/terry 是當(dāng)前工作目錄, return /Users/terry/bar
api文檔中一個(gè)比較復(fù)雜的示例(此處注意resolve的時(shí)候,從右到左,參考文檔了解詳情):
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// if the current working directory is /home/myself/node,
// this returns '/home/myself/node/wwwroot/static_files/gif/image.gif'
現(xiàn)在的問題是,啥是當(dāng)前工作目錄。
nodejs 當(dāng)前工作目錄 current working directory
nodejs 當(dāng)前工作目錄是啟動(dòng)Node的目錄。也就是說,從哪個(gè)目錄進(jìn)去啟動(dòng)node,就返回哪個(gè)目錄。
注意,這個(gè)目錄不是指js文件所在的目錄
通過process.cwd()方法可以獲取當(dāng)前工作目錄。
下面通過一個(gè)示例來介紹這個(gè)當(dāng)前工作目錄,假如在/Users/terry/Documents/JSWorkspace目錄下寫一個(gè)js文件,test.js,代碼只有一行:
console.log(process.cwd());
此時(shí)如果,在目錄/Users/terry/Documents/JSWorkspace下面執(zhí)行命令 :node test.js 輸出如下:
/Users/terry/Documents/JSWorkspace
但是如果在在目錄/Users/terry/Documents/下面執(zhí)行命令:node ./JSWorkspace/test.js,輸出的結(jié)果是:
/Users/terry/Documents
因此可以看出你在那個(gè)目錄執(zhí)行node命令,當(dāng)前目錄就是那個(gè)目錄。
回到之前的打包的問題,由于在開發(fā)階段,一般都是直接在js文件所在目錄執(zhí)行node命令,所以相對(duì)目錄寫的是相對(duì)于當(dāng)前js文件的目錄沒有問題。
可是打包之后,node的執(zhí)行放到了js目錄的上一層去了。此時(shí)相對(duì)目錄“public”不在是相對(duì)于js文件的相對(duì)目錄,而是相對(duì)于上一層的,自然就找不到這個(gè)文件夾了,從而也找不到該文件夾下的index.html文件。
如何解決
解決的方法:
1.在前面已經(jīng)說過了,改這個(gè)相對(duì)目錄。但這種方法很蹩腳。因?yàn)?,啟?dòng)node命令的目錄可能會(huì)變;而是如果這應(yīng)該,開發(fā)階段的node命令執(zhí)行也需要跟著改。 總之不是兼容性很好的方法。
2.直接使用絕對(duì)路徑。 但是這個(gè)絕對(duì)路徑在不同的機(jī)器上又不一樣,該如何解決呢?可以考慮使用全局變量__dirname.
全局變量__dirname
查看api文檔 https://nodejs.org/api/modules.html#modules_dirname
看到解釋如下:
The directory name of the current module. This is the same as the path.dirname() of the __filename。
啥意思呢,及時(shí)返回nodejs 的js文件的所在目錄。
有了這個(gè)變量之后,我們就可以用如下代碼解決這個(gè)問題。
app.use(express.static(__dirname + '/public'));
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Node4-5靜態(tài)資源服務(wù)器實(shí)戰(zhàn)以及優(yōu)化壓縮文件實(shí)例內(nèi)容
這篇文章主要介紹了Node4-5靜態(tài)資源服務(wù)器實(shí)戰(zhàn)以及優(yōu)化壓縮文件實(shí)例內(nèi)容,有需要的朋友們可以參考學(xué)習(xí)下。2019-08-08
詳解NodeJs項(xiàng)目 CentOs linux服務(wù)器線上部署
這篇文章主要介紹了NodeJs項(xiàng)目 CentOs linux服務(wù)器線上部署,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09
Express+Nodejs 下的登錄攔截實(shí)現(xiàn)代碼
本篇文章主要介紹了Express+Nodejs 下的登錄攔截實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07
在Nodejs中實(shí)現(xiàn)一個(gè)緩存系統(tǒng)的方法詳解
在數(shù)據(jù)庫(kù)查詢遇到瓶頸時(shí),我們通??梢圆捎镁彺鎭硖嵘樵兯俣?同時(shí)緩解數(shù)據(jù)庫(kù)壓力,在一些簡(jiǎn)單場(chǎng)景中,我們也可以自己實(shí)現(xiàn)一個(gè)緩存系統(tǒng),避免使用額外的緩存中間件,這篇文章將帶你一步步實(shí)現(xiàn)一個(gè)完善的緩存系統(tǒng),需要的朋友可以參考下2024-03-03
Node.js API詳解之 V8模塊用法實(shí)例分析
這篇文章主要介紹了Node.js API詳解之 V8模塊用法,結(jié)合實(shí)例形式分析了Node.js API中V8模塊基本功能、函數(shù)、使用用法及操作注意事項(xiàng),需要的朋友可以參考下2020-06-06
M2實(shí)現(xiàn)Nodejs項(xiàng)目自動(dòng)部署的方法步驟
這篇文章主要介紹了M2實(shí)現(xiàn)Nodejs項(xiàng)目自動(dòng)部署的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05
Node.js實(shí)現(xiàn)簡(jiǎn)單管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Node.js實(shí)現(xiàn)簡(jiǎn)單管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
npm?does?not?support?Node.js問題的解決辦法
這篇文章主要給大家介紹了關(guān)于npm?does?not?support?Node.js問題的解決辦法,文中通過代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-10-10

