最近公司的一個開發項目,後端用的是nodejs。這兩天須要打包給客戶演示,就讓公司一個小夥把以前3D機房的打包工具移植過來。打包以後,發現本來在開發環境下的跑的好好的項目,不能訪問了。出現項目的首頁不能訪問的問題:html
can not get file index.html
問題出在哪兒?
nodejs後端的用了express,index.html是一個靜態文件。咱們知道,經過 Express 內置的 express.static 能夠方便地託管靜態文件,例如圖片、CSS、JavaScript 文件等。
將靜態資源文件所在的目錄做爲參數傳遞給 express.static 中間件就能夠提供靜態資源文件的訪問了。例如,假設在 public 目錄放置了圖片、CSS 和 JavaScript 文件,可使用以下代碼:node
app.use(express.static('public'));
因此,找到項目中的代碼,查看static調用的地方,和上面一行代碼很同樣:express
app.use(express.static('public'));
到此,我已經發現了問題,我告訴小夥伴,這個地方不用相對路徑能夠解決這個問題。因爲打包時間限制,我讓小夥伴先簡單處理下,打完包以後,在來整理下思路:後端
app.use(express.static('resource/public'));
固然最重要的是,這個問題其實不難,本身多鑽研下,很容易發現問題,也就不會出這個問題,因此小夥伴本身打手心吧。
恩,你沒看錯,這個地方仍是相對目錄。後續產品中會改爲比較好的一種狀況。api
事實上,express.static方法若是傳入的是相對路徑,express會本身把他轉換爲絕對路徑,咱們能夠查看下源代碼,在express.js找到以下代碼:app
exports.static = require('serve-static');
說明static 調用了serve-static這個包,直接找到這個包,查看index.js, 能夠看到代碼,下面列出重要的兩行工具
... var resolve = require('path').resolve ... opts.root = resolve(root) ...
這兩行就是,express把相對目錄轉換成絕對目錄的代碼,能夠看出,最終使用的path這個內置對象的resolve方法,繼續往下看。ui
直接查看這個方法的api文檔,以下:
https://nodejs.org/api/path.h...
下面是這個方法的解釋:
The path.resolve() method resolves a sequence of paths or path segments into an absolute path.
啥意思呢? 就是這個方法把一系列的paths或者path segments 組織成一個絕對路徑,好比this
path.resolve('/foo','bar'); // return /foo/bar
詳細的說明請自行參考文檔,這個地方有一句話須要特別注意:
If after processing all given path segments an absolute path has not yet been generated, the current working directory is used.
啥意思,就是若是處理完了全部的path segments,也沒有生成一個絕對路徑, 就要使用 當前工做目錄(current working directory)。好比:spa
path.resolve('bar'); // 加上 /Users/terry 是當前工做目錄, return /Users/terry/bar
api文檔中一個比較複雜的示例(此處注意resolve的時候,從右到左,參考文檔瞭解詳情):
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'
如今的問題是,啥是當前工做目錄。
nodejs 當前工做目錄是啓動Node的目錄。也就是說,從哪一個目錄進去啓動node,就返回哪一個目錄。
注意,這個目錄不是指js文件所在的目錄
經過process.cwd()方法能夠獲取當前工做目錄。
下面經過一個示例來介紹這個當前工做目錄,假如在/Users/terry/Documents/JSWorkspace目錄下寫一個js文件,test.js,代碼只有一行:
console.log(process.cwd());
此時若是,在目錄/Users/terry/Documents/JSWorkspace下面執行命令 :node test.js 輸出以下:
/Users/terry/Documents/JSWorkspace
可是若是在在目錄/Users/terry/Documents/下面執行命令:node ./JSWorkspace/test.js,輸出的結果是:
/Users/terry/Documents
所以能夠看出你在那個目錄執行node命令,當前目錄就是那個目錄。
回到以前的打包的問題,因爲在開發階段,通常都是直接在js文件所在目錄執行node命令,因此相對目錄寫的是相對於當前js文件的目錄沒有問題。
但是打包以後,node的執行放到了js目錄的上一層去了。此時相對目錄「public」不在是相對於js文件的相對目錄,而是相對於上一層的,天然就找不到這個文件夾了,從而也找不到該文件夾下的index.html文件。
解決的方法:
查看api文檔 https://nodejs.org/api/module...
看到解釋以下:
The directory name of the current module. This is the same as the path.dirname()
of the __filename
。
啥意思呢,及時返回nodejs 的js文件的所在目錄。
有了這個變量以後,咱們就能夠用以下代碼解決這個問題。
app.use(express.static(__dirname + '/public'));
更多精彩內容,請關注公衆號。