Vite + Vue3 跨域环境变量配置全过程
一、环境变量配置
1. 创建环境变量文件
在项目根目录创建以下文件:
.env # 所有环境通用(最低优先级)
.env.local # 本地环境通用,git忽略
.env.development # 开发环境
.env.production # 生产环境
.env.staging # 预发布环境
2. 环境变量示例
.env.development (开发环境):
# API 基础地址
VITE_API_BASE_URL = /api
# 完整 API 地址(用于其他配置)
VITE_API_FULL_URL = http://localhost:3000
# 其他变量
VITE_APP_TITLE = My App (Development)
.env.production (生产环境):
VITE_API_BASE_URL = /api
VITE_API_FULL_URL = https://api.example.com
VITE_APP_TITLE = My App
3. 使用环境变量
在代码中通过 import.meta.env 访问:
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL
const appTitle = import.meta.env.VITE_APP_TITLE
二、跨域代理配置
1.
vite.config.js 配置
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
export default defineConfig(({ mode }) => {
// 加载环境变量
const env = loadEnv(mode, process.cwd())
return {
plugins: [vue()],
// 服务器配置
server: {
port: 5173, // 开发服务器端口
host: true, // 监听所有地址
open: true, // 自动打开浏览器
// 代理配置
proxy: {
// 代理规则1:以 /api 开头的请求
'/api': {
target: env.VITE_API_FULL_URL, // 从环境变量读取
changeOrigin: true, // 修改请求头中的host值
rewrite: (path) => path.replace(/^\/api/, '') // 重写路径
},
// 代理规则2:多个API端点
'/auth': {
target: 'http://auth.example.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/auth/, '/api/auth')
},
// WebSocket 代理
'/socket': {
target: 'ws://localhost:3001',
ws: true,
changeOrigin: true
}
}
},
// 构建配置
build: {
outDir: 'dist',
sourcemap: mode !== 'production', // 生产环境关闭sourcemap
// 环境变量定义
define: {
__APP_ENV__: JSON.stringify(env.APP_ENV)
}
},
// 路径别名
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
}
}
})
三、TypeScript 支持
1. 创建
env.d.ts 文件
在 src 目录下创建 env.d.ts:
/// <reference types="vite/client" />
interface ImportMetaEnv {
// 基础配置
readonly VITE_APP_TITLE: string
readonly VITE_API_BASE_URL: string
readonly VITE_API_FULL_URL: string
// 业务相关变量
readonly VITE_UPLOAD_URL: string
readonly VITE_CDN_URL: string
// 第三方配置
readonly VITE_GA_ID: string
readonly VITE_SENTRY_DSN: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
四、封装 API 请求
1. 创建
src/utils/request.ts
import axios, { type AxiosRequestConfig, type AxiosResponse } from 'axios'
// 创建 axios 实例
const service = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
})
// 请求拦截器
service.interceptors.request.use(
(config) => {
// 添加 token
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
// 开发环境打印请求信息
if (import.meta.env.DEV) {
console.log(`📤 ${config.method?.toUpperCase()} ${config.url}`, config.params || config.data)
}
return config
},
(error) => {
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
(response: AxiosResponse) => {
// 开发环境打印响应信息
if (import.meta.env.DEV) {
console.log(`📥 ${response.status} ${response.config.url}`, response.data)
}
return response.data
},
(error) => {
// 统一错误处理
if (error.response) {
switch (error.response.status) {
case 401:
// token 过期处理
break
case 403:
// 权限不足
break
case 500:
// 服务器错误
break
}
}
return Promise.reject(error)
}
)
export default service
2. 创建 API 模块
// src/api/user.ts
import request from '@/utils/request'
export const userAPI = {
// 登录
login(data: { username: string; password: string }) {
return request.post('/auth/login', data)
},
// 获取用户信息
getUserInfo() {
return request.get('/user/info')
},
// 上传文件
uploadFile(data: FormData) {
return request.post('/upload', data, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
}
五、环境变量验证
1. 创建验证脚本
// scripts/validate-env.js
const fs = require('fs')
const path = require('path')
// 必需的环境变量
const requiredEnvVars = [
'VITE_API_BASE_URL',
'VITE_API_FULL_URL'
]
function validateEnvFile(filePath) {
if (!fs.existsSync(filePath)) {
return
}
console.log(`检查 ${filePath}`)
const content = fs.readFileSync(filePath, 'utf-8')
const lines = content.split('\n')
lines.forEach(line => {
if (line.trim() && !line.startsWith('#')) {
const [key] = line.split('=')
if (!key) return
if (requiredEnvVars.includes(key.trim())) {
console.log(`✓ ${key.trim()}`)
}
}
})
}
// 检查所有环境文件
const envFiles = [
'.env.development',
'.env.production',
'.env.staging'
]
envFiles.forEach(file => {
validateEnvFile(path.join(__dirname, '..', file))
})
2. package.json 添加脚本
{
"scripts": {
"dev": "vite",
"dev:local": "vite --mode development",
"dev:test": "vite --mode staging",
"build": "vite build",
"build:prod": "vite build --mode production",
"build:staging": "vite build --mode staging",
"preview": "vite preview",
"validate-env": "node scripts/validate-env.js",
"lint": "eslint . --ext .vue,.js,.ts"
}
}
六、部署配置
1. Docker 配置
# Dockerfile
FROM node:18-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
2. Nginx 配置
# nginx.conf
server {
listen 80;
server_name localhost;
# 开启 gzip
gzip on;
gzip_min_length 1k;
gzip_comp_level 9;
gzip_types text/plain text/css text/javascript application/json application/javascript application/xml+rss;
gzip_vary on;
# 静态资源
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
# API 代理
location /api/ {
proxy_pass http://backend:3000/;
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;
}
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
七、使用示例
1. 组件中使用
<template>
<div>
<h1>{{ title }}</h1>
<button @click="fetchData">获取数据</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { userAPI } from '@/api/user'
const title = import.meta.env.VITE_APP_TITLE
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL
const fetchData = async () => {
try {
const data = await userAPI.getUserInfo()
console.log('数据:', data)
} catch (error) {
console.error('请求失败:', error)
}
}
</script>
2. 开发时使用不同环境
# 开发环境(默认)
npm run dev
# 指定开发环境
npm run dev --mode development
# 测试环境
npm run dev --mode staging
# 生产环境构建
npm run build:prod
# 预发布环境构建
npm run build:staging
# 预览生产构建
npm run preview
八、注意事项
环境变量命名:必须以
VITE_ 开头才能在客户端访问
敏感信息:不要在前端环境变量中存储敏感信息
类型安全:及时更新
env.d.ts 类型定义
代理配置:开发环境使用代理,生产环境使用 Nginx 等服务器配置
缓存问题:修改环境变量后需要重启开发服务器
这样配置后,你的 Vite + Vue3 项目就具备了完整的跨域代理和环境变量管理能力。