如果從頭開始搭建React專案,create-react-app通常是開發者的首選。畢竟不是誰都有精力去了解WebPack的複雜配置,而CRA將配置隱藏開箱即用的特性必然會受到普遍歡迎。
根目錄訪問
到了部署階段,我通常使用nginx作為web容器,將專案部署到一個根目錄下訪問。如
# nginx配置
server {
listen 80;
server_name my.website.com;
...
location / {
alias /data/www/react-project/dist;
index index.html
}
}
那麼只要我們將專案檔案放到對應的目錄下,重啟nginx即可開始訪問web頁面。
二級目錄訪問
有時我們有多個web專案,多個專案不可能同時掛在根目錄下,所以我們會劃分二級目錄來分別訪問各個web專案。如
- http://my.website.com/project1 => 訪問react-project1專案
- http://my.website.com/project2 => 訪問react-project2專案
問題1:CSS等資源載入失敗
此時,如果簡單將nginx配置的location改為/project1,則會出現網頁無法訪問的錯誤。
# nginx配置
server {
listen 80;
server_name my.website.com;
...
# location / {
location /project1 {
alias /data/www/react-project/dist;
index index.html
}
}
現象
從dev工具可以看出,html檔案有取得,但css、js等資源引用失敗。css和js的檔案路徑都是http://my.website.com/static/…(或css)。
分析
CRA(create-react-app)的專案配置預設是跑在根目錄下的。如果檢視dist目錄下的html會發現,所有的css或js檔案的引用路徑都是/開頭的絕對路徑。
解決
將打包路徑從絕對路徑改為相對路徑:
# package.json
{
...
"homepage": ".", // 新增homepage屬性,將路徑改為當前目錄
...
}
重新編譯後看到,所有的資原始檔路徑都改過來了。
問題2:載入成功,網頁空白
重新上傳到伺服器,更新dist目錄下的檔案,重啟nginx後訪問網頁。
現象
結果發現,網頁仍然是空白一片。檢視html的渲染結果,發現似乎js並沒有執行。
分析
在react-router-dom的例子中,通常使用的是BrowserRouter。這種型別的Router在向伺服器傳送請求時,如果相對於二級目錄的路由去指向對應的頁面路由,就會找不到資源,因此也就不會渲染。
解決
BrowserRouter有一個屬性叫做basename,就是用於解決此類問題。
...
import { Route, BrowserRouter as Router, Switch, Redirect } from `react-router-dom`;
...
...
<Router basename=`/project1`>
<Switch>
<Redirect exact key=`index` path=`/` to=`/home` />
{ routes }
</Switch>
</Router>
...
問題3:訪問成功,重新整理後404
修改以上配置並編譯部署,重啟nginx後可正常訪問網頁。但重新整理後,網頁變為一片空白。
現象
網頁顯示,在請求頁面路由如http://my.website.com/project… 時,該路由的請求狀態為404。
分析
還是因為BrowserRouter的問題,之前能正常訪問時因為路由中設定了Redirect,所以能訪問到根目錄並自動跳轉到/home。但直接訪問則會訪問失敗。
解決
在nginx配置中加入try_files命令
location /project1 {
alias /data/www/react-project/dist;
# index index.html
try_files $uri /project1/index.html
}
這樣,在請求$uri時如果找不到對應的資源,會fallback回去載入index.html。
問題解決。