Vue 項目在 build 之后通常都需要部署到服務(wù)器才能夠訪問,本文介紹如果使用 Nginx 部署 Vue 項目
更多精彩
- 更多技術(shù)博客,請移步 IT人才終生實訓(xùn)與職業(yè)進(jìn)階平臺 - 實訓(xùn)在線
首先需要說明可能存在的誤區(qū)
- 我這個項目是使用的 Vue + SpringBoot 實現(xiàn)前后分離的項目
- 也就是說在部署時羽杰,前端和后端要分別單獨部署疾忍,前端通過請求后端的接口還實現(xiàn)數(shù)據(jù)交互
- 一開始我是打算將 build 后的 Vue 項目直接放到 Tomcat 的 /webapps/ 目錄中,然后啟動 Tomcat
- 后端由于是 SpringBoot 鸦致,所以不打算借助 Tomcat 潮剪,會直接通過
java -jar xxx.jar
啟動 - 由于前后端分別使用了不同的服務(wù)部署涣楷,兩者之間會出現(xiàn)端口號不一致的情況
- 這個時候就需要使用 Nginx 來實現(xiàn)代理轉(zhuǎn)發(fā),所以我就準(zhǔn)備 使用 Nginx 將部署在 Tomcat 中的前端項目發(fā)出的請求代理轉(zhuǎn)發(fā)到通過 SpringBoot 單獨啟動的后端項目中
- BUT 抗碰,這個思路實際上是 不行的Jǘ贰!弧蝇!
- 因為比如部署前端項目的 Tomcat 碳褒,使用的端口號是 8082 ,那么前端項目的訪問地址就會是
http://192.168.7.8?:8082/teamnote/#/
看疗,與之對應(yīng)的從前端項目發(fā)送出去的請求沙峻,比如請求任務(wù)列表就會是http://192.168.7.8:8082/teamnote/api/tasks
- 后端項目由于是通過 SpringBoot 單獨啟動,其接收任務(wù)列表請求的接口就會是
http://192.168.7.8:2592/teamnote/api/tasks
- 如果使用 Nginx 两芳,理所應(yīng)當(dāng)?shù)奈艺J(rèn)為是監(jiān)聽 8082 端口摔寨,然后將
/teamnote/api/
開頭的請求轉(zhuǎn)發(fā)到http://192.168.7.8:2592/teamnote/api/
中 - 看上去好像沒毛病,但當(dāng)在 Nginx 的 nginx.conf 中改完保存并重啟時怖辆,則會拋出以下錯誤
.... 0.0.0.0:8082 failed (98: Address already in use)
- 這是因為是复,8082 端口已經(jīng)被部署了前端項目的 Tomcat 使用了,Nginx 無法監(jiān)聽一個已經(jīng)被使用的端口竖螃,所以上述好像沒啥毛病的部署思路淑廊,全是錯的!L嘏亍季惩! ,這讓我在一條死胡同里耗了一個多小時
正確的部署方式
- 既然是使用 Nginx 部署項目腻格,那么就應(yīng)該直接將 Vue 項目部署到 Nginx 的服務(wù)目錄画拾,因為 Nginx 和 Tomcat 一樣,都是服務(wù)器
將打包好的前端項目文件放到指定目錄中
- 一開始我會想要把打包后的項目文件放到 Nginx 默認(rèn)的目錄菜职,但這樣實際上是不好的碾阁,項目文件完全可以放在單獨的目錄中方便統(tǒng)一管理,如下圖
- asl-teamnote-1.0.jar 是打包好的后端項目包
- run-backend.sh 是后端項目包的一鍵啟動腳本
-
teamnote 則是將前端項目 build 之后的 dist 目錄改名后的文件目錄
image
修改 Nginx 配置些楣,指向上述目錄
- 一般來說就是修改 Nginx 的默認(rèn)配置文件 nginx.conf 即可脂凶,但不推薦這么做,既然上面使用了單獨的目錄管理項目文件愁茁,那么這里也推薦創(chuàng)建單獨的 Nginx 配置文件來管理此項目的 Nginx 配置
- 在 Nginx 的默認(rèn)配置文件 nginx.conf 中蚕钦,最后一行寫著
include /etc/nginx/conf.d/*.conf;
- 這說明只要是該目錄下文件后綴為 conf 的文件都會被自動加載到 Nginx 配置中
- 所以可以前往該目錄,創(chuàng)建此項目的配置文件鹅很,例如 asing1elife.conf 嘶居,如下圖
image
編寫自定義的 Nginx 配置文件
server {
# 需要被監(jiān)聽的端口號,前提是此端口號沒有被占用,否則在重啟 Nginx 時會報錯
listen 8888;
# 服務(wù)名稱邮屁,無所謂
server_name localhost;
# 上述端口指向的根目錄
root /opt/asing1elife/teamnote;
# 項目根目錄中指向項目首頁
index index.html;
client_max_body_size 20m;
client_body_buffer_size 128k;
# 根請求會指向的頁面
location / {
# 此處的 @router 實際上是引用下面的轉(zhuǎn)發(fā)整袁,否則在 Vue 路由刷新時可能會拋出 404
try_files $uri $uri/ @router;
# 請求指向的首頁
index index.html;
}
# 由于路由的資源不一定是真實的路徑,無法找到具體文件
# 所以需要將請求重寫到 index.html 中佑吝,然后交給真正的 Vue 路由處理請求資源
location @router {
rewrite ^.*$ /index.html last;
}
# 關(guān)鍵步驟坐昙,這里表示將所有的 http://192.168.7.8:8888/teamnote/api/ 開頭的請求都轉(zhuǎn)發(fā)到下面 proxy_pass 指定的鏈接中
# 這里使用 /teamnote/api/ 而不是 /teamnote/ ,是因為前端項目本身的訪問鏈接就是 http:192.168.7.8:8888/teamnote/
# 為了防止在訪問頁面時請求就被 Nginx 代理轉(zhuǎn)發(fā)芋忿,這里需要更具體的配置炸客,才能和前端訪問請求區(qū)分開
location /teamnote/api/ {
# 后端的真實接口
proxy_pass http://192.168.7.8:2592/teamnote/api/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
# for Ajax
#fastcgi_param HTTP_X_REQUESTED_WITH $http_x_requested_with;
proxy_set_header HTTP-X-REQUESTED-WITH $http_x_requested_with;
proxy_set_header HTTP_X_REQUESTED_WITH $http_x_requested_with;
proxy_set_header x-requested-with $http_x_requested_with;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 128k;
proxy_buffers 32 32k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
}
}
重新啟動 Nginx
- 使用
nginx -s reload
可以重新加載 Nginx 的配置文件,但如果配置文件有錯戈钢,不一定會拋出異常 - 使用
nginx -s stop
先停止 Nginx 服務(wù)痹仙,再使用nginx
嘗試啟動 Nginx 服務(wù),如果配置文件有異常殉了,則會拋出異常告知啟動失敗
更新前端項目包
- 將更新后的前端項目打包开仰,直接傳到之前的前端文件目錄即可,Nginx 不需要重啟