以前不多接觸前端項目的部署,此次爲了更全面的學習就在本機上裝了一個虛擬機上,在虛擬機上練習瞭如何把一個 react
寫的 spa
項目部署到這個虛擬機的服務器上。因爲 linux
也是剛接觸不久,因此整個過程仍是遇到了不少坑,這裏記錄下。html
我有一個用 react
寫的單頁面應用,而後但願部署到服務器上,經過 ip
如 192.168.1.240/config
這種路徑下訪問到個人應用。這個 react
項目依賴一個 node.js
的一個 api
服務,我須要在 nginx
上配置代理使得個人 react
應用可以訪問到個人 api
服務。前端
首先要準備的就是打包好的的 react
應用,而後在服務器上裝一個 nginx
和一個 node.js
。vue
針對我這個項目, 我把 react
打包好的項目所有放到了 /root/html/pageConfig
這個路徑下。node
修改 nginx
安裝目錄下的 ./conf/nginx.conf
文件:react
#user nodody; # 1. 因爲個人 react 項目打包出來放在 root 目錄下,須要設置user 爲 root 時內容纔可以被訪問 user root; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; } # 2. 對個人/api請求轉發到8989端口下node.js服務 location /api { proxy_pass http://127.0.0.1:8989; } # 3. 在/config下的請求都指向到我放在root下的configPage裏的內容 location /config { alias /root/html/configPage; index index.html index.htm; #rewrite /config /root/html/configPage/index.html; try_files $uri $uri/ /config/index.html; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html;
這裏就是隻修改了默認配置文件的三個地方,來知足個人要求:linux
user
爲 root
,使得 root
下的內容可以被訪問location /api
設置 proxy_pass
使得 /api
下的請求都被轉發到 proxy_pass
設置的 node.js
服務處,知足個人前端頁面 api
接口代理的問題location /config
的配置,使得 /config
下請求都轉發至我 react
打包文件所在的路徑。這樣我訪問 192.168.1.240/config
就能看到個人頁面。這裏我當初是複製的location /
的配置,用的也是 root
指向路徑,結果一直不行,查了資料,發現應該要寫成 alias
才行 這裏的配置文件可能須要更改屢次,才能成功,須要注意的是,每次修改完 nginx
配置,須要重啓下 nginx
:webpack
nginx -s reload
把打包好的文件傳到服務器上的時候,可能出現靜態資源文件找不到的狀況。nginx
可能的緣由是當 react
應用打包的時候,生成 index.html
文件中插入 style
和 script
標籤的路徑不對,從而找不到靜態資源。web
須要在 webpack
的配置文件中去修改一下 publicPath
這個屬性,這個屬性會影響你的靜態資源文件插入到 index.html
中的路徑。像我這個項目設置 publicPath: './'
就能夠了,具體能夠多修改幾回多打包幾回試試就好了。api
前端路由分爲兩種實現,一種就是 hashRouter
,另外一種就是用 H5
新的 History API
實現的 browserRouter
。因爲 hashRouter
的路徑帶一個 #
不是特別好看,通常仍是用 browserRouter
較多。
前端路由說白了就是路徑變了,不去請求服務器,而是用 js
去改變頁面的方式。這樣的話,用 browserRouter
的話這裏就存在一個問題,我用前端路由跳轉到某一個路徑下 /xxx
,這是我刷新頁面,這時候就會去服務器上拿資源,這個前端路由路徑下確定找不到資源,因此就會出現 404
報錯。
解決頁面刷新 404
這個問題,只須要把全部的請求所有返回 index.html
,能夠搜索 history fallback
這個關鍵詞查看相關資料。
針對個人這個 nginx
配置而言,只須要加入 try_files $uri $uri/ /config/index.html;
,就能把前端路由路徑發送給服務器時所有返回 index.html
,這樣就解決了 404
問題。
配置好上述的 nginx
以及把打包好的文件放到對應的目錄,再把個人 api
服務啓動,再訪問 192.168.1.240/config
時,已經可以正常的顯示頁面,而且接口也能正常代理請求到了。可是涉及到路由的頁面卻沒有被渲染出來。
回想一下,在 react-router-dom
的 Route
標籤裏傳遞一個 path={'/xx'}
的屬性時,前端路由會根據這個 path
來渲染對應的 Route
上傳遞過去的 Component
組件。那麼在個人 nginx
的設置中,我設置的是 location /config
,也就是說我實際訪問路徑都是加上了前綴 /config
,因此每一個 Route
標籤中傳過去的路徑都由於缺乏了 /config
前綴致使因此的匹配都不成立,因此 Route
的頁面都沒有辦法渲染。
方法很簡單,在 BrowserRouter
上加一個 basename
的屬性,給這屬性傳遞 config
(具體是什麼值,依據你給 nginx
設置 location
時的前綴,個人例子中是 config
),這樣 Route
在匹配路徑的時候會加上 basename
,這樣就能和對應路徑匹配上,而後渲染對應頁面。
對 linux
不熟悉,nginx
也不熟悉,依靠着百度,摸爬滾打嘗試修改了好屢次 nginx
配置,終於可以 react
打包好的文件部署上去了, vue
項目的部署也是沒什麼區別的。