【vue3】10 - vue3项目打包部署

【vue3】10 - vue3项目打包部署

客户端 → Nginx (前端) → 网关层 → 后端服务集群
              ↑
              ├── 静态资源 (Vue3)
              └── API 代理

一:打包前的准备

确保你的项目可以正常运行:

# 如果是vue cli
npm run serve

# 如果是vite
npm run dev

1:vite.config.ts (核心构建配置)

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'
import { visualizer } from 'rollup-plugin-visualizer'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    visualizer({ 
      open: true, 
      filename: 'dist/stats.html' 
    })
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
    
  // 注意这里
  build: {
    outDir: 'dist',
    assetsDir: 'assets',
    emptyOutDir: true,
    minify: 'terser',
    sourcemap: false,
    chunkSizeWarningLimit: 1500,
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (id.includes('node_modules')) {
            return id.toString().split('node_modules/')[1].split('/')[0].toString()
          }
        },
        chunkFileNames: 'assets/js/[name]-[hash].js',
        entryFileNames: 'assets/js/[name]-[hash].js',
        assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
      }
    }
  },
  // 注意这里
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
})

2:tsconfig.json (TS配置)

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "useDefineForClassFields": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "types": ["vite/client"],
    "lib": ["ESNext", "DOM", "DOM.Iterable"]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue"
  ],
  "exclude": ["node_modules"]
}

3:地址信息配置

.env.production文件中

# 基础API地址 (会被Nginx代理)
VITE_API_BASE_URL=/api

# 应用标题
VITE_APP_TITLE=My Production App

# 是否启用分析工具
VITE_ANALYZE=false

4:配置env.d.ts

/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_BASE_URL: string
  readonly VITE_APP_TITLE: string
  readonly VITE_ANALYZE: string
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

二:vue3项目打包

1:执行打包操作

npm run build

打包完成后会在项目根目录下生成 dist 文件夹,包含:

  • index.html - 应用入口文件
  • static/ - 静态资源目录(JS、CSS、图片等)

2:dist发送到服务器的指定位置

# 方式一:scp
scp -r dist/* username@your-server-ip:/path/to/your/webroot

# 方式二:rsync
rsync -avz --delete dist/ username@your-server-ip:/path/to/your/webroot


# 例如
ssh user@203.0.113.45
sudo mkdir -p /var/www/html/vue-app
sudo chown -R user:www-data /var/www/html/vue-app

# -a:归档模式(保留权限、时间戳等)
# -v:显示详细传输信息
# -z:压缩传输数据
# --delete:删除目标目录中不存在于源目录的文件
# dist/:本地打包目录(注意结尾的 / 表示同步目录内容)
# user@203.0.113.45:服务器用户名和IP
# /var/www/html/vue-app/:服务器目标路径
rsync -avz --delete dist/ user@203.0.113.45:/var/www/html/vue-app/

当然也可以提前创建和配置好存储路径文件夹,然后使用 FTP/SFTP 工具,如 FileZilla、WinSCP 等图形化工具

三:nginx配置

1:配置前的确认

一般确定三个内容

  1. 假设前端已经成功打包并且前端存放路径是/var/www/html/vue-app

  2. 假设后端网关服务器的地址是192.0.0.1.9000,192.0.0.1.9001,192.0.0.1.9002

  3. 假设前端生产环境和开发环境使用/api进行代理

// 最简单且最常用的方式,直接使用相对路径/api,依靠Nginx代理转发:
// src/utils/request.js (或你的axios封装文件)
const service = axios.create({
  baseURL: '/api', // 生产环境直接使用相对路径
  timeout: 15000
})

在没有接入nginx之前,可以通过vite.config.ts中代理的配置访问后端的开发环境

// vite.config.ts
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'

// https://vite.dev/config/
export default defineConfig({
    // 配置插件
    plugins: [
        vue(),
        vueDevTools(),  // 允许在script setup中使用console.log()
        VueSetupExtend(), // 允许在script setup中使用name
    ],
    // 配置别名
    resolve: {
        alias: {
            // @ -> src
            // @/utils -> src/utils
            '@': fileURLToPath(new URL('./src', import.meta.url))  // @ -> src
        },
    },
    // 配置代理
    server: {
        proxy: {
            // 例如: /api/user -> http://localhost:3000/user
            '/api': { // 代理路径, 匹配的请求路径的前缀,对应的是.env.development中的VITE_BASE_API
                target: 'http://localhost:8081', // 代理目标地址(实际的开发环境的服务端地址)
                changeOrigin: true, // 允许跨域
                // 重写路径 -> 去掉/api前缀
                rewrite: (path) => path.replace(/^\/api/, '')
            }
        }
    }
})

2:nginx配置示例

# 定义上游服务器组(后端服务负载均衡)
upstream backend_servers {
    server 192.0.0.1:9000;  # 后端服务器1
    server 192.0.0.1:9001;  # 后端服务器2
    server 192.0.0.1:9002;  # 后端服务器3
    
    # 负载均衡策略(默认是轮询)
    # least_conn;  # 最少连接策略
    # ip_hash;     # 基于客户端IP的哈希策略(会话保持)
}

server {
    listen 80;              # 监听80端口(HTTP)
    server_name yourdomain.com;  # 替换为你的域名或IP
    
    # 前端Vue应用配置
    location / {
        root /var/www/html/vue-app;  # Vue应用的存放路径
        index index.html;            # 默认入口文件
        
        # 尝试按顺序查找文件,如果找不到则返回index.html(Vue路由需要)
        try_files $uri $uri/ /index.html;
    }
    
    # 后端API代理配置
    location /api/ {
        # 反向代理到上游服务器组
        proxy_pass http://backend_servers;
        
        # 以下是一些常用的代理设置
        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 X-Forwarded-Proto $scheme;
        
        # 连接超时设置
        proxy_connect_timeout 60s;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
        
        # 启用HTTP/1.1 keepalive
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
    
    # 静态资源缓存设置
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        root /var/www/html/vue-app;
        expires 30d;  # 缓存30天
        add_header Cache-Control "public, no-transform";
    }
    
    # 错误页面配置
    error_page 404 /index.html;  # Vue应用处理404
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值