Vue基于環(huán)境變量統(tǒng)一的多級(jí)路徑部署終極指南
一、環(huán)境變量統(tǒng)一配置
1. 環(huán)境變量配置文件
我們首先在項(xiàng)目根目錄創(chuàng)建以下環(huán)境文件:
# .env.development VUE_APP_BASE_URL=/ VUE_APP_PUBLIC_PATH=/ VUE_APP_API_BASE_URL=/api/
# .env.production VUE_APP_BASE_URL=/department/project/ VUE_APP_PUBLIC_PATH=/department/project/ VUE_APP_API_BASE_URL=/department/project/api/
關(guān)鍵點(diǎn)說(shuō)明:
VUE_APP_BASE_URL: 路由基礎(chǔ)路徑VUE_APP_PUBLIC_PATH: 靜態(tài)資源基礎(chǔ)路徑VUE_APP_API_BASE_URL: API請(qǐng)求基礎(chǔ)路徑
二、Vue項(xiàng)目核心配置
vue.config.js 完整配置
const path = require('path')
module.exports = {
// 靜態(tài)資源路徑
publicPath: process.env.VUE_APP_PUBLIC_PATH || '/',
// 輸出目錄
outputDir: 'dist',
// 靜態(tài)資源目錄
assetsDir: 'static',
// 文件名哈希
filenameHashing: true,
// webpack配置
chainWebpack: config => {
// 設(shè)置publicPath
config.output
.publicPath(process.env.VUE_APP_PUBLIC_PATH || '/')
// 圖片處理
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.tap(options => {
options.limit = 8192
options.fallback = {
loader: 'file-loader',
options: {
name: 'static/img/[name].[hash:8].[ext]',
publicPath: process.env.VUE_APP_PUBLIC_PATH || '/'
}
}
return options
})
},
// 開(kāi)發(fā)服務(wù)器配置
devServer: {
// 支持history模式
historyApiFallback: {
disableDotRule: true,
rewrites: [
{
from: new RegExp('^.*'),
to: path.posix.join(process.env.VUE_APP_PUBLIC_PATH || '/', 'index.html')
}
]
},
// 代理配置
proxy: {
[process.env.VUE_APP_API_BASE_URL]: {
target: 'http://your-api-server.com',
changeOrigin: true,
pathRewrite: {
[`^${process.env.VUE_APP_API_BASE_URL}`]: ''
}
}
}
},
// 生產(chǎn)環(huán)境關(guān)閉sourcemap
productionSourceMap: false
}
三、路由配置最佳實(shí)踐
路由配置文件 (src/router/index.js)
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// 獲取基礎(chǔ)路徑,確保不以斜杠結(jié)尾
const BASE_PATH = (process.env.VUE_APP_BASE_URL || '/').replace(/\/$/, '')
const routes = [
{
// 根路徑重定向
path: '',
redirect: 'home'
},
{
// 注意:不要以斜杠開(kāi)頭
path: 'home',
component: () => import('@/views/Home.vue'),
name: 'home',
meta: { title: '首頁(yè)' }
},
{
path: 'about',
component: () => import('@/views/About.vue'),
name: 'about',
meta: { title: '關(guān)于我們' }
},
{
path: '*',
component: () => import('@/views/NotFound.vue'),
name: 'not-found',
meta: { title: '頁(yè)面不存在' }
}
]
const router = new VueRouter({
mode: 'history',
base: BASE_PATH,
routes,
// 滾動(dòng)行為
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
})
router.beforeEach((to, from, next) => {
document.title = to.meta.title || '默認(rèn)標(biāo)題'
next()
})
export default router
四、資源加載與API請(qǐng)求規(guī)范
1. 資源加載工具類(lèi) (src/utils/resource.js)
/**
* 獲取靜態(tài)資源完整URL
* @param {string} relativePath 相對(duì)路徑
* @returns {string} 完整URL
*/
export const getAssetUrl = (relativePath) => {
const baseUrl = process.env.VUE_APP_PUBLIC_PATH || '/'
return `${baseUrl.replace(/\/$/, '')}/${relativePath.replace(/^\//, '')}`
}
/**
* 獲取API完整URL
* @param {string} endpoint API端點(diǎn)
* @returns {string} 完整API URL
*/
export const getApiUrl = (endpoint) => {
const baseUrl = process.env.VUE_APP_API_BASE_URL || '/api/'
return `${baseUrl.replace(/\/$/, '')}/${endpoint.replace(/^\//, '')}`
}
2. Axios實(shí)例配置 (src/utils/request.js)
import axios from 'axios'
import { getApiUrl } from './resource'
// 創(chuàng)建axios實(shí)例
const service = axios.create({
baseURL: process.env.VUE_APP_API_BASE_URL,
timeout: 10000
})
// 請(qǐng)求攔截器
service.interceptors.request.use(
config => {
// 可以在這里添加token等
// config.headers['Authorization'] = getToken()
return config
},
error => {
return Promise.reject(error)
}
)
// 響應(yīng)攔截器
service.interceptors.response.use(
response => {
return response.data
},
error => {
return Promise.reject(error)
}
)
export default service
五、Nginx服務(wù)器配置
1. 基礎(chǔ)Nginx配置
server {
listen 80;
server_name example.com;
# 靜態(tài)資源緩存設(shè)置
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, no-transform";
}
# 項(xiàng)目部署路徑 - 使用環(huán)境變量中的路徑
location /department/project/ {
alias /var/www/html/department/project/dist/;
try_files $uri $uri/ /department/project/index.html;
# 開(kāi)啟gzip壓縮
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
# 安全頭設(shè)置
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
}
# API代理
location /department/project/api/ {
proxy_pass http://api-server/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
2. HTTPS增強(qiáng)配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# SSL優(yōu)化配置
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
location /department/project/ {
alias /var/www/html/department/project/dist/;
try_files $uri $uri/ /department/project/index.html;
# 安全頭
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header Content-Security-Policy "default-src 'self'";
}
}
六、完整部署流程
1. 構(gòu)建與部署腳本
#!/bin/bash
# 設(shè)置環(huán)境
ENV="production"
DEPLOY_PATH="/var/www/html/department/project"
# 安裝依賴(lài)
npm install
# 構(gòu)建項(xiàng)目
npm run build:${ENV}
# 同步文件到服務(wù)器
rsync -avz --delete dist/ user@server:${DEPLOY_PATH}/dist/
# 重啟Nginx
ssh user@server "sudo systemctl restart nginx"
echo "Deployment completed!"
2. 多環(huán)境構(gòu)建腳本 (package.json)
{
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build:dev": "vue-cli-service build --mode development",
"build:test": "vue-cli-service build --mode test",
"build:production": "vue-cli-service build --mode production",
"lint": "vue-cli-service lint"
}
}
七、常見(jiàn)問(wèn)題解決方案
1. 頁(yè)面刷新404問(wèn)題
解決方案:
- 確保Nginx配置中包含正確的try_files指令
- 檢查Vue路由的base配置是否與環(huán)境變量一致
- 驗(yàn)證publicPath配置是否正確
2. 靜態(tài)資源加載失敗
排查步驟:
- 檢查瀏覽器開(kāi)發(fā)者工具中的網(wǎng)絡(luò)請(qǐng)求
- 確認(rèn)請(qǐng)求路徑是否包含正確的基礎(chǔ)路徑
- 驗(yàn)證Nginx的alias路徑是否正確
- 檢查文件權(quán)限:
chmod -R 755 /var/www/html
3. API請(qǐng)求路徑錯(cuò)誤
最佳實(shí)踐:
- 使用axios實(shí)例配置baseURL
- 確保API路徑與VUE_APP_API_BASE_URL一致
- 開(kāi)發(fā)環(huán)境使用代理,生產(chǎn)環(huán)境使用絕對(duì)路徑
八、性能優(yōu)化建議
1.資源壓縮:
- 開(kāi)啟Nginx gzip壓縮
- 使用Brotli壓縮(需要Nginx支持)
- 壓縮圖片資源
2.緩存策略:
location ~* \.(js|css)$ {
expires 365d;
add_header Cache-Control "public";
}
location ~* \.(jpg|jpeg|png|gif|ico)$ {
expires 30d;
add_header Cache-Control "public";
}
3.代碼分割:
// 使用動(dòng)態(tài)導(dǎo)入實(shí)現(xiàn)路由懶加載
component: () => import('@/views/Home.vue')
總結(jié)
這種方案在多個(gè)大型項(xiàng)目中得到驗(yàn)證,能夠滿足企業(yè)級(jí)應(yīng)用的部署需求。
到此這篇關(guān)于Vue基于環(huán)境變量統(tǒng)一的多級(jí)路徑部署終極指南的文章就介紹到這了,更多相關(guān)Vue項(xiàng)目部署內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue自定義render統(tǒng)一項(xiàng)目組彈框功能
這篇文章主要介紹了Vue自定義render統(tǒng)一項(xiàng)目組彈框功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
Vue中實(shí)現(xiàn)在線畫(huà)流程圖的方法
最近在調(diào)研一些在線文檔的實(shí)現(xiàn),包括文檔編輯器、在線思維導(dǎo)圖、在線流程圖等,本文分享在Vue框架下基于metaeditor-mxgraph實(shí)現(xiàn)在線流程圖,感興趣的朋友一起看看吧2024-07-07
一次Vue中computed沒(méi)有觸發(fā)的原因以及排查經(jīng)歷
這篇文章主要介紹了一次Vue中computed沒(méi)有觸發(fā)的原因以及排查經(jīng)歷,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
通過(guò)Element ui往頁(yè)面上加一個(gè)分頁(yè)導(dǎo)航條的方法
這篇文章主要介紹了通過(guò)Element ui往頁(yè)面上加一個(gè)分頁(yè)導(dǎo)航條的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
vue使用$emit時(shí),父組件無(wú)法監(jiān)聽(tīng)到子組件的事件實(shí)例
下面小編就為大家分享一篇vue使用$emit時(shí),父組件無(wú)法監(jiān)聽(tīng)到子組件的事件實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
vue中使用vant的Toast輕提示報(bào)錯(cuò)的解決
這篇文章主要介紹了vue中使用vant的Toast輕提示報(bào)錯(cuò)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
axios取消請(qǐng)求與避免重復(fù)請(qǐng)求
在項(xiàng)目中經(jīng)常有一些場(chǎng)景會(huì)連續(xù)發(fā)送多個(gè)請(qǐng)求,而異步會(huì)導(dǎo)致最后得到的結(jié)果不是我們想要的,并且對(duì)性能也有非常大的影響,這篇文章主要給大家介紹了關(guān)于axios取消請(qǐng)求與避免重復(fù)請(qǐng)求的相關(guān)資料,需要的朋友可以參考下2021-06-06
Vue 將后臺(tái)傳過(guò)來(lái)的帶html字段的字符串轉(zhuǎn)換為 HTML
這篇文章主要介紹了Vue 將后臺(tái)傳過(guò)來(lái)的帶html字段的字符串轉(zhuǎn)換為 HTML ,需要的朋友可以參考下2018-03-03
解決vue $http的get和post請(qǐng)求跨域問(wèn)題
這篇文章主要介紹了解決vue $http的get和post請(qǐng)求跨域問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06

