在佈署前,把React.js建立的前端build目錄上傳到主機後,後端API可能會不見,因為路徑被前端覆蓋了。要怎麼解決呢?你需要在Node.js的啟動檔中設定前後端的路徑,將前後端分離。
一、建立前端頁面
1-1. 建立前端頁面之前的所需設定
在MERN專案中,伺服器端(server)與客戶端(client)是分離的,它們都有各自的目錄與package.json檔,第一步需要找到客戶端的package.json,並對 homepage 屬性填入即將佈署的網域,例如:
{
"name": "mobuyashea",
"version": "0.1.0",
"private": true,
"homepage": "https://mobuyashea.club/",
"dependencies": {
//下略
1-2. 生成build資料夾
接著,你需要幫客戶端的內容建立靜態頁面,確定位於client目錄下,於終端機輸入:
npm run build
按下確認鍵後,npm會於client目錄建立一個build資料夾,裡面的內容為前端靜態頁面。
二、MERN佈署時的目錄結構
MERN專案的佈署目錄結構大概如下,外面根目錄放伺服器端的內容,包括啟動檔、伺服器端的package.json、資料表或路由等;build則是客戶端的內容,就是把第一步建立的目錄整包上傳:
/root
|– /build(前端)
|– /models
|– /public
|– /routes
|– server.js (啟動檔)
|– package.json
|– package-lock.json
也可以把伺服器端跟客戶端的目錄完全分開,不過要注意下一步路由的設定,根據路由文件與首頁相對位置的不同,可能會變成“/../client/build”
/root
|– /client/build(前端)
|– /server
|–– server.js (啟動檔)
三、分離MERN專案的前後端路由
打開你的啟動檔(假設文件叫server.js),引入path模組:
const path = require('path');
用 ‘ * ‘ 將所有路由通通歸類於前端頁面,不管訪問哪個路由都返回build目錄下的index.html:
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});
用path.join() 簡單的規範路徑,或用path.resolve() 返回絕對路徑,兩者在此範例下返回的是相同的路徑__dirname 是目前文件所處的位置。
四、注意先後順序
撰寫API時,定位前端靜態目錄的程式碼必須位於後端路由之後,後端路由都發配完後才輪到'*'
。順序不能優先於其他後端路徑,否則會把其他路徑給覆蓋掉。