vue3+vite+ts打包后在根目录生成一个app.config.js文件用于部署后切换axios请求地址
1. 创建配置文件类型定义
首先在src/types目录下创建配置文件类型:
// src/types/config.ts export interface AppConfig { apiBaseUrl: string; timeout: number; env: string; [key: string]: any; }
2. 创建配置管理工具
// src/utils/config.ts import type { AppConfig } from '@/types/config'; // 默认配置 const defaultConfig: AppConfig = { apiBaseUrl: '/api', timeout: 10000, env: 'production' }; class ConfigManager { private config: AppConfig = defaultConfig; private configLoaded = false; // 加载配置 async loadConfig(): Promise<AppConfig> { if (this.configLoaded) { return this.config; } try { // 尝试从外部配置文件加载 const response = await fetch('/app.config.js?t=' + Date.now()); if (response.ok) { const configText = await response.text(); const configMatch = configText.match(/window\.APP_CONFIG\s*=\s*({[^}]+})/); if (configMatch && configMatch[1]) { const externalConfig = JSON.parse(configMatch[1]); this.config = { ...defaultConfig, ...externalConfig }; } } } catch (error) { console.warn('Failed to load external config, using defaults:', error); } this.configLoaded = true; return this.config; } // 获取配置 getConfig(): AppConfig { return this.config; } // 获取API基础URL getApiBaseUrl(): string { return this.config.apiBaseUrl; } } export const configManager = new ConfigManager();
3. 创建Vite插件生成配置文件
// src/plugins/generateConfigPlugin.ts import { Plugin } from 'vite'; interface GenerateConfigOptions { outputPath?: string; config?: Record<string, any>; } export function generateConfigPlugin(options: GenerateConfigOptions = {}): Plugin { const { outputPath = 'dist/app.config.js', config = { apiBaseUrl: '/api', timeout: 10000, env: 'production' } } = options; return { name: 'generate-config-plugin', apply: 'build', generateBundle() { const configContent = `// 应用配置文件 - 自动生成 // 修改此文件中的配置项后,刷新页面即可生效 window.APP_CONFIG = ${JSON.stringify(config, null, 2)}; `; this.emitFile({ type: 'asset', fileName: 'app.config.js', source: configContent }); } }; }
4. 配置Vite插件
在vite.config.ts中引入插件:
// vite.config.ts import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import { generateConfigPlugin } from './src/plugins/generateConfigPlugin'; export default defineConfig({ plugins: [ vue(), generateConfigPlugin({ config: { apiBaseUrl: 'http://localhost:3000/api', timeout: 10000, env: process.env.NODE_ENV || 'production' } }) ], // 其他配置...
build: {
chunkSizeWarningLimit: 1000,
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
// Element Plus 单独分包(通常是大头)
if (id.includes('element-plus')) return 'element-plus'
// Vue 核心单独分包
if (id.includes('/vue/') || id.includes('@vue')) return 'vue-vendor'
// 其他第三方统一打包
return 'vendor'
}
},
},
},
},
server: {
proxy: {
'/api': {
target: 'http://localhost:3000/api', // 目标服务器地址
changeOrigin: true, // 是否改变源地址
rewrite: (path) => path.replace(/^\/api/, ''), // 重写路径
// 可以配置更多选项,如 logLevel, timeout 等
},
}
}
});
5. 创建Axios实例
// src/api/axios
import axios from 'axios'; import { configManager } from "./config" // 创建axios实例 const request = axios.create({ timeout: 20000, headers: { 'Content-Type': 'application/json' } }); // 请求拦截器 request.interceptors.request.use( async (config) => { // 确保配置已加载 await configManager.loadConfig(); const apiBaseUrl = configManager.getApiBaseUrl(); // 可以在这里添加请求头、认证token等 console.log('拦截器:', localStorage.getItem('token')); config.headers['Authorization'] = localStorage.getItem('token'); // 如果是绝对路径,直接使用;否则拼接基础URL if (config.url?.startsWith('http')) { return config; } if (config.url && !config.url.startsWith('/')) { config.url = '/' + config.url; } config.baseURL = apiBaseUrl; return config; }, (error: any) => { // 请求错误处理 return Promise.reject(error); } ); // 响应拦截器 request.interceptors.response.use( (response) => { return response; }, (error: any) => { // 响应错误处理 return Promise.reject(error); } ); function checkStatus(response: any): Promise<any> { return new Promise((resolve, reject) => { if (!response) { reject(new Error('响应对象为空')); return; } const { status, data } = response; try { if (status === 200 || status === 304) { // 成功状态 resolve(data as any); } else if (status >= 400 && status < 500) { // 客户端错误 reject(new Error(`客户端错误: ${status}`)); } else if (status >= 500) { // 服务端错误 reject(new Error(`服务器错误: ${status}`)); } else { // 其他状态码 reject(new Error(`未知状态码: ${status}`)); } } catch (error) { reject(error); } }); } export default { post(url: any, params?: any) { return request({ method: "post", url, data: params }).then(response => { return checkStatus(response); }); }, get(url: any, params?: any) { return request({ method: "get", url, params }).then(response => { return checkStatus(response); }); } };
6. 在Vue应用中使用
// src/main.ts import { createApp } from 'vue'; import App from './App.vue'; import { configManager } from './api/config'; const app = createApp(App); // 在应用启动时加载配置 configManager.loadConfig().then(() => { app.mount('#app'); });
7. 生成的配置文件示例
打包后会在dist目录生成app.config.js文件:
// 应用配置文件 - 自动生成 // 修改此文件中的配置项后,刷新页面即可生效 window.APP_CONFIG = { "apiBaseUrl": "http://localhost:3000/api", "timeout": 10000, "env": "production" };
使用说明
-
开发环境:配置通过Vite的proxy处理
-
生产环境:
-
打包后会在根目录生成
app.config.js -
修改该文件中的
apiBaseUrl即可改变API请求地址 -
无需重新打包部署
-

浙公网安备 33010602011771号