nginx部署發(fā)布Vite項(xiàng)目
1 引言
在之前的文章《Ubuntu云服務(wù)器上部署發(fā)布Vite項(xiàng)目》中筆者使用了Vite提供的預(yù)覽服務(wù)(npm run preview)來在云服務(wù)器上發(fā)布Web應(yīng)用。這樣做輕量應(yīng)用是沒問題的,不過遇到一些專業(yè)的問題就不行了,最好還是使用專業(yè)的HTTP服務(wù)器。除此之外,筆者還有一些其他的需求:
- 前后端分離的項(xiàng)目,需要將后端的服務(wù)轉(zhuǎn)發(fā)到前端服務(wù)IP相同的端口(443端口)。
- 子域名的項(xiàng)目,需要將服務(wù)轉(zhuǎn)發(fā)到主域名服務(wù)IP相同的端口(443端口)。
這個(gè)時(shí)候就需要使用nginx,畢竟nginx不僅是一款輕量、高性能的HTTP服務(wù)器,還支持轉(zhuǎn)發(fā)和代理服務(wù)功能。不過上述兩個(gè)問題后面在討論,本篇就詳細(xì)記錄一下部署發(fā)布單個(gè)Vite項(xiàng)目的問題。
2 詳述
2.1 操作
首先,還是需要先安裝nginx:
sudo apt install nginx
然后,準(zhǔn)備Vite項(xiàng)目,需要確保項(xiàng)目已經(jīng)通過npm run build構(gòu)建好,并且生成了靜態(tài)文件目錄(通常是dist目錄下)。
接下來,在/etc/nginx/sites-available/目錄下創(chuàng)建一個(gè)新的配置文件,例如筆者這里創(chuàng)建一個(gè)charlee44文件。在這個(gè)文件中填入如下內(nèi)容:
server { # 定義服務(wù)器
listen 80; # 監(jiān)聽80端口
server_name charlee44.com; # 服務(wù)器域名
root /path/to/your/project/dist; # 項(xiàng)目build后的實(shí)際路徑
index index.html; # 主頁
location / { #位置塊,定義路由
try_files $uri $uri/ /index.html;
}
}
sites-available目錄下創(chuàng)建的配置是可用的配置,要真正啟用這個(gè)配置需要在sites-enabled目錄中,因此創(chuàng)建軟鏈接:
sudo ln -s /etc/nginx/sites-available/charlee44 /etc/nginx/sites-enabled/
最后就是測試Nginx配置并重啟服務(wù),在終端輸入以下命令:
sudo nginx -t
sudo systemctl restart nginx
2.2 配置
上面的配置很好理解,基本已經(jīng)注釋清楚了,就是位置塊部分有點(diǎn)難理解,具體意思是:
- $uri:先看看有沒有和請求路徑完全一致的文件存在,比如 /about.html
- $uri/:如果沒有,再看看是否是一個(gè)目錄,比如 /about/
- 如果都沒有,就返回 /index.html
不太理解也沒關(guān)系,等以后有需求了再來了解清楚。如果這個(gè)配置測試沒有問題,在訪問主頁時(shí)頁面提示:
500 Internal Server Error
nginx/1.18.0 (Ubuntu)
那么有可能是權(quán)限不夠,可以檢查一下文件/var/log/nginx/error.log是否有類似“Permission denied”的提示。Ubuntu中有些目錄是受保護(hù)的目錄(例如/root目錄),可以將build項(xiàng)目移動到nginx可以正常訪問的目錄,例如/var下目錄。
如果想配置HTTPS服務(wù),那么就可以使用如下配置:
# HTTP 跳轉(zhuǎn) HTTPS
server {
listen 80;
server_name charlee44.com;
return 301 https://$host$request_uri; # 返回301永久重定向,將請求跳轉(zhuǎn)到HTTPS版本
}
# HTTPS 服務(wù)
server {
listen 443 ssl;
server_name charlee44.com;
# SSL證書
ssl_certificate /etc/nginx/ssl/charlee44.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/charlee44.com/charlee44.com.key;
ssl_protocols TLSv1.2 TLSv1.3; # 啟用安全的加密協(xié)議版本
ssl_ciphers HIGH:!aNULL:!MD5; # 設(shè)置加密套件,禁用不安全的算法
root /var/www/charlee44.com;
index index.html;
location / {
try_files $uri $uri/ =404; # 嘗試查找對應(yīng)文件或目錄,否則返回404頁面
}
}
這段配置的意思是如果用戶通過HTTP訪問網(wǎng)站,那么就將請求轉(zhuǎn)發(fā)到HTTPS的443端口上。另外,HTTPS最重要的一點(diǎn)還有需要申請SSL證書(可以參考筆者之前的文章《在Ubuntu上使用Certbot申請Let’s Encrypt SSL證書》來進(jìn)行申請)。
2.3 優(yōu)化
上述HTTPS服務(wù)的配置,經(jīng)過筆者的實(shí)際測試,性能比不上Vite提供的預(yù)覽服務(wù)(npm run preview)。原因是因?yàn)閚ginx是高度可配,還有很多優(yōu)化選項(xiàng)可以配置,具體配置如下:
# HTTP 跳轉(zhuǎn) HTTPS
server {
listen 80;
server_name charlee44.com;
return 301 https://$host$request_uri;
}
# HTTPS 服務(wù)
server {
listen 443 ssl http2; # ? 啟用 HTTP/2
server_name charlee44.com;
ssl_certificate /etc/letsencrypt/live/charlee44.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/charlee44.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/charlee44.com;
index index.html;
# ? 靜態(tài)資源緩存 + Cache-Control
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires max;
add_header Cache-Control "public, immutable";
log_not_found off;
}
# ? HTML 文件緩存短一些(可選)
location ~ \.html$ {
expires 1h;
}
# ? 默認(rèn)處理入口
location / {
try_files $uri $uri/ =404;
}
# ? 啟用 Gzip 壓縮
gzip on;
gzip_types application/javascript text/css;
gzip_comp_level 6;
# ? 提升文件傳輸效率
sendfile on;
tcp_nopush on;
tcp_nodelay on;
}
相比之前的配置,在性能上主要優(yōu)化了以下幾點(diǎn):
2.3.1 啟用HTTP/2
使用HTTP/2協(xié)議可以實(shí)現(xiàn)多路復(fù)用、頭部壓縮等特性,顯著提升加載速度:
listen 443 ssl http2; # ? 啟用 HTTP/2
2.3.2 靜態(tài)資源緩存控制
設(shè)置瀏覽器緩存策略,減少重復(fù)請求,加快頁面加載速度:
# ? 靜態(tài)資源緩存 + Cache-Control
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires max; # 設(shè)置些資源永不過期
add_header Cache-Control "public, immutable"; # 設(shè)置緩存策略:公開可緩存,內(nèi)容不變
log_not_found off; # 不記錄不存在的文件的404日志
}
# ? HTML 文件緩存短一些(可選)
location ~ \.html$ {
expires 1h; # HTML文件可能經(jīng)常更新,設(shè)置較短緩存時(shí)間
}
2.3.3 Gzip壓縮
啟用Gzip并指定壓縮類型,以減少傳輸體積,加快網(wǎng)頁加載速度(尤其對 JS/CSS):
# ? 啟用 Gzip 壓縮
gzip on;
gzip_types application/javascript text/css;
gzip_comp_level 6; # 啟用 Gzip 壓縮時(shí),使用壓縮級別 6(共 1 到 9 級)
2.3.4 文件傳輸優(yōu)化
提升網(wǎng)絡(luò)傳輸效率,降低延遲,提高吞吐量:
# ? 提升文件傳輸效率
sendfile on;
tcp_nopush on; # 合并頭部+正文,減少小包數(shù)量
tcp_nodelay on; # 對動態(tài)請求或 WebSocket 立即發(fā)送數(shù)據(jù)
3 結(jié)語
其實(shí)HTTP服務(wù)器的性能優(yōu)化遠(yuǎn)不止這點(diǎn)內(nèi)容,針對本篇內(nèi)容的性能優(yōu)化配置,筆者就可以想到兩點(diǎn):
- 靜態(tài)資源緩存控制的性能優(yōu)化是通知客戶端緩存文件資源,那么是否可以在服務(wù)器上緩存文件資源到內(nèi)存呢?這樣當(dāng)客戶端請求過來,就可以不經(jīng)過硬盤直接傳輸內(nèi)存中的數(shù)據(jù),這樣可以節(jié)省一次磁盤IO。
- 啟用Gzip壓縮,壓縮文件也是算在客戶端請求響應(yīng)時(shí)間的,那么是否可以預(yù)先將文件按照最高級別進(jìn)行壓縮,然后需要的時(shí)候再直接傳輸出去呢?這樣可以節(jié)省臨時(shí)文件的時(shí)間,同時(shí)也最大程度的減少的文件傳輸體積。
其實(shí)這兩個(gè)問題,甚至更多的性能優(yōu)化思路,nginx都有一定程度的解決方案,就留待以后再研究吧。

浙公網(wǎng)安備 33010602011771號