若是從頭開始搭建React項目,create-react-app一般是開發者的首選。畢竟不是誰都有精力去了解WebPack的複雜配置,而CRA將配置隱藏開箱即用的特性必然會受到廣泛歡迎。css
到了部署階段,我一般使用nginx做爲web容器,將項目部署到一個根目錄下訪問。如html
# nginx配置 server { listen 80; server_name my.website.com; ... location / { alias /data/www/react-project/dist; index index.html } }
那麼只要咱們將項目文件放到對應的目錄下,重啓nginx便可開始訪問web頁面。react
有時咱們有多個web項目,多個項目不可能同時掛在根目錄下,因此咱們會劃分二級目錄來分別訪問各個web項目。如nginx
此時,若是簡單將nginx配置的location改成/project1,則會出現網頁沒法訪問的錯誤。web
# 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)。json
CRA(create-react-app)的項目配置默認是跑在根目錄下的。若是查看dist目錄下的html會發現,全部的css或js文件的引用路徑都是/開頭的絕對路徑。服務器
將打包路徑從絕對路徑改成相對路徑:react-router
# package.json { ... "homepage": ".", // 添加homepage屬性,將路徑改成當前目錄 ... }
從新編譯後看到,全部的資源文件路徑都改過來了。app
從新上傳到服務器,更新dist目錄下的文件,重啓nginx後訪問網頁。dom
結果發現,網頁仍然是空白一片。查看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> ...
修改以上配置並編譯部署,重啓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。
問題解決。