Vue基于环境变量统一的多级路径部署终极指南

 更新时间:2025年08月14日 09:50:18   作者:前端大鱼  
这篇文章主要为大家详细介绍了一个完整的解决方案,从环境变量配置到Nginx部署,确保你的Vue项目可以灵活部署在任何路径下,下面小编就为大家简单介绍一下吧

一、环境变量统一配置

1. 环境变量配置文件

我们首先在项目根目录创建以下环境文件:

# .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/

关键点说明:

  • VUE_APP_BASE_URL: 路由基础路径
  • VUE_APP_PUBLIC_PATH: 静态资源基础路径
  • VUE_APP_API_BASE_URL: API请求基础路径

二、Vue项目核心配置

vue.config.js 完整配置

const path = require('path')

module.exports = {
  // 静态资源路径
  publicPath: process.env.VUE_APP_PUBLIC_PATH || '/',
  
  // 输出目录
  outputDir: 'dist',
  
  // 静态资源目录
  assetsDir: 'static',
  
  // 文件名哈希
  filenameHashing: true,
  
  // webpack配置
  chainWebpack: config => {
    // 设置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
      })
  },
  
  // 开发服务器配置
  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}`]: ''
        }
      }
    }
  },
  
  // 生产环境关闭sourcemap
  productionSourceMap: false
}

三、路由配置最佳实践

路由配置文件 (src/router/index.js)

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

// 获取基础路径,确保不以斜杠结尾
const BASE_PATH = (process.env.VUE_APP_BASE_URL || '/').replace(/\/$/, '')

const routes = [
  {
    // 根路径重定向
    path: '',
    redirect: 'home'
  },
  {
    // 注意:不要以斜杠开头
    path: 'home',
    component: () => import('@/views/Home.vue'),
    name: 'home',
    meta: { title: '首页' }
  },
  {
    path: 'about',
    component: () => import('@/views/About.vue'),
    name: 'about',
    meta: { title: '关于我们' }
  },
  {
    path: '*',
    component: () => import('@/views/NotFound.vue'),
    name: 'not-found',
    meta: { title: '页面不存在' }
  }
]

const router = new VueRouter({
  mode: 'history',
  base: BASE_PATH,
  routes,
  
  // 滚动行为
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return { x: 0, y: 0 }
    }
  }
})

router.beforeEach((to, from, next) => { 
  document.title = to.meta.title || '默认标题'  
 
  next()
})

export default router

四、资源加载与API请求规范

1. 资源加载工具类 (src/utils/resource.js)

/**
 * 获取静态资源完整URL
 * @param {string} relativePath 相对路径
 * @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端点
 * @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实例配置 (src/utils/request.js)

import axios from 'axios'
import { getApiUrl } from './resource'

// 创建axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_API_BASE_URL,
  timeout: 10000
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 可以在这里添加token等
    // config.headers['Authorization'] = getToken()
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  response => {
    return response.data
  },
  error => {
    return Promise.reject(error)
  }
)

export default service

五、Nginx服务器配置

1. 基础Nginx配置

server {
    listen       80;
    server_name  example.com;
    
    # 静态资源缓存设置
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, no-transform";
    }
    
    # 项目部署路径 - 使用环境变量中的路径
    location /department/project/ {
        alias   /var/www/html/department/project/dist/;
        try_files $uri $uri/ /department/project/index.html;
        
        # 开启gzip压缩
        gzip on;
        gzip_types text/plain text/css application/json application/javascript text/xml;
        
        # 安全头设置
        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增强配置

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优化配置
    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. 构建与部署脚本

#!/bin/bash

# 设置环境
ENV="production"
DEPLOY_PATH="/var/www/html/department/project"

# 安装依赖
npm install

# 构建项目
npm run build:${ENV}

# 同步文件到服务器
rsync -avz --delete dist/ user@server:${DEPLOY_PATH}/dist/

# 重启Nginx
ssh user@server "sudo systemctl restart nginx"

echo "Deployment completed!"

2. 多环境构建脚本 (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"
  }
}

七、常见问题解决方案

1. 页面刷新404问题

解决方案:

  • 确保Nginx配置中包含正确的try_files指令
  • 检查Vue路由的base配置是否与环境变量一致
  • 验证publicPath配置是否正确

2. 静态资源加载失败

排查步骤:

  • 检查浏览器开发者工具中的网络请求
  • 确认请求路径是否包含正确的基础路径
  • 验证Nginx的alias路径是否正确
  • 检查文件权限:chmod -R 755 /var/www/html

3. API请求路径错误

最佳实践:

  • 使用axios实例配置baseURL
  • 确保API路径与VUE_APP_API_BASE_URL一致
  • 开发环境使用代理,生产环境使用绝对路径

八、性能优化建议

1.资源压缩:

  • 开启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.代码分割:

// 使用动态导入实现路由懒加载
component: () => import('@/views/Home.vue')

总结

这种方案在多个大型项目中得到验证,能够满足企业级应用的部署需求。

到此这篇关于Vue基于环境变量统一的多级路径部署终极指南的文章就介绍到这了,更多相关Vue项目部署内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue 实现 tomato timer(蕃茄钟)实例讲解

    vue 实现 tomato timer(蕃茄钟)实例讲解

    下面小编就为大家带来一篇vue 实现 tomato timer(蕃茄钟)实例讲解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • vue3单文件组件中style特性的深入讲解

    vue3单文件组件中style特性的深入讲解

    单文件就是把一个页面拆分为多个,多层次的组件,通过多层引用,大大缩小vue文件的长度和页面复杂度,下面这篇文章主要给大家介绍了关于vue3单文件组件中style特性的相关资料,需要的朋友可以参考下
    2021-09-09
  • Vue.use源码学习小结

    Vue.use源码学习小结

    这篇文章主要介绍了Vue.use源码学习小结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • element-plus 按钮展开/隐藏功能实现

    element-plus 按钮展开/隐藏功能实现

    本文给大家介绍element-plus 按钮展开/隐藏功能实现,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2025-06-06
  • Vue中定义全局变量与常量的各种方式详解

    Vue中定义全局变量与常量的各种方式详解

    Vue.js 如何添加全局常量或变量? 这是最近一个同事问的问题,发现很多朋友对这块不熟悉,所以下面这篇文章主要给大家介绍了关于Vue中定义全局变量与常量的各种方式,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-08-08
  • vue2.0/3.0的响应式原理及区别浅析

    vue2.0/3.0的响应式原理及区别浅析

    这篇文章主要给大家介绍了关于vue2.0/3.0响应式原理及区别的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • vue-cli创建项目ERROR in Conflict: Multiple assets emit different content to the same filename index.html问题的解决办法

    vue-cli创建项目ERROR in Conflict: Multiple assets emit dif

    最近vue/cli创建项目后出现了错误,下面这篇文章主要给大家介绍了关于vue-cli创建项目ERROR in Conflict: Multiple assets emit different content to the same filename index.html问题的解决办法,需要的朋友可以参考下
    2023-02-02
  • vue3中配置文件vue.config.js不生效的解决办法

    vue3中配置文件vue.config.js不生效的解决办法

    这篇文章主要介绍了vue3中配置文件vue.config.js不生效的解决办法,文中通过代码示例讲解的非常详细,对大家解决问题有一定的帮助,需要的朋友可以参考下
    2024-05-05
  • 解决VUE项目localhost端口服务器拒绝连接,只能用127.0.0.1的问题

    解决VUE项目localhost端口服务器拒绝连接,只能用127.0.0.1的问题

    这篇文章主要介绍了解决VUE项目localhost端口服务器拒绝连接,只能用127.0.0.1的问题
    2020-08-08
  • 完美解决axios在ie下的兼容性问题

    完美解决axios在ie下的兼容性问题

    下面小编就为大家分享一篇完美解决axios在ie下的兼容性问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03

最新评论