Files
mp-vue/src/utils/port-config-manager.ts
赵忠林 7052ccce61 feat(port): 实现智能端口管理系统
- 新增端口管理器类,支持端口分配、验证和缓存管理
- 实现环境优先级策略,根据环境自动选择合适的端口范围
- 集成租户识别系统,为每个租户分配独立端口
- 添加端口分配结果统计和历史记录查询功能
- 优化端口缓存机制,自动清理过期绑定
2025-09-03 18:52:39 +08:00

358 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 端口配置管理器
* 集成环境变量和智能端口管理
*/
import type { PortStrategy } from '@/lib/port-manager';
import type { Environment } from '@/lib/port-strategy';
// 端口配置接口
export interface PortEnvironmentConfig {
// 基础配置
strategy: 'auto' | 'manual' | 'tenant-based' | 'sequential';
basePort: number;
portRangeStart: number;
portRangeEnd: number;
// 租户配置
tenantPortOffset: number;
environmentPortOffset: number;
// 行为配置
autoDetect: boolean;
strictMode: boolean;
cacheEnabled: boolean;
cacheExpiry: number;
// 开发服务器配置
devHost: string;
openBrowser: boolean;
corsEnabled: boolean;
httpsEnabled: boolean;
}
// 配置验证结果
export interface ConfigValidationResult {
isValid: boolean;
errors: string[];
warnings: string[];
recommendations: string[];
}
// 端口配置管理器
export class PortConfigManager {
private config: PortEnvironmentConfig;
private environment: Environment;
constructor() {
this.environment = this.detectEnvironment();
this.config = this.loadConfiguration();
this.validateConfiguration();
}
/**
* 检测当前环境
*/
private detectEnvironment(): Environment {
// 在 Vite 配置阶段import.meta.env 可能不可用,使用 process.env
const nodeEnv = (typeof process !== 'undefined' ? process.env.NODE_ENV : undefined) ||
(typeof import.meta !== 'undefined' && import.meta.env ? import.meta.env.NODE_ENV : undefined) ||
'development';
switch (nodeEnv.toLowerCase()) {
case 'production':
case 'prod':
return 'production';
case 'test':
case 'testing':
return 'test';
case 'staging':
case 'stage':
return 'staging';
default:
return 'development';
}
}
/**
* 加载配置
*/
private loadConfiguration(): PortEnvironmentConfig {
// 获取环境变量的辅助函数
const getEnv = (key: string, defaultValue?: string) => {
if (typeof process !== 'undefined' && process.env) {
return process.env[key];
}
if (typeof import.meta !== 'undefined' && import.meta.env) {
return import.meta.env[key];
}
return defaultValue;
};
return {
// 基础配置
strategy: (getEnv('VITE_PORT_STRATEGY') as any) || 'auto',
basePort: parseInt(getEnv('VITE_BASE_PORT') || '3000'),
portRangeStart: parseInt(getEnv('VITE_PORT_RANGE_START') || '3000'),
portRangeEnd: parseInt(getEnv('VITE_PORT_RANGE_END') || '9999'),
// 租户配置
tenantPortOffset: parseInt(getEnv('VITE_TENANT_PORT_OFFSET') || '10'),
environmentPortOffset: parseInt(getEnv('VITE_ENVIRONMENT_PORT_OFFSET') || '1000'),
// 行为配置
autoDetect: getEnv('VITE_PORT_AUTO_DETECT') !== 'false',
strictMode: getEnv('VITE_PORT_STRICT_MODE') === 'true',
cacheEnabled: getEnv('VITE_PORT_CACHE_ENABLED') !== 'false',
cacheExpiry: parseInt(getEnv('VITE_PORT_CACHE_EXPIRY') || '86400000'), // 24小时
// 开发服务器配置
devHost: getEnv('VITE_DEV_HOST') || 'localhost',
openBrowser: getEnv('VITE_DEV_OPEN_BROWSER') !== 'false',
corsEnabled: getEnv('VITE_DEV_CORS_ENABLED') !== 'false',
httpsEnabled: getEnv('VITE_DEV_HTTPS_ENABLED') === 'true'
};
}
/**
* 验证配置
*/
private validateConfiguration(): ConfigValidationResult {
const errors: string[] = [];
const warnings: string[] = [];
const recommendations: string[] = [];
// 验证端口范围
if (this.config.portRangeStart >= this.config.portRangeEnd) {
errors.push('端口范围无效:起始端口必须小于结束端口');
}
if (this.config.portRangeStart < 1024 && this.environment === 'production') {
warnings.push('生产环境使用系统端口(<1024可能需要管理员权限');
}
// 验证基础端口
if (this.config.basePort < this.config.portRangeStart ||
this.config.basePort > this.config.portRangeEnd) {
errors.push('基础端口不在允许的端口范围内');
}
// 验证租户偏移
if (this.config.tenantPortOffset <= 0) {
warnings.push('租户端口偏移为0可能导致端口冲突');
}
// 环境特定验证
switch (this.environment) {
case 'development':
if (this.config.httpsEnabled) {
warnings.push('开发环境启用HTTPS可能增加配置复杂度');
}
if (!this.config.autoDetect) {
recommendations.push('开发环境建议启用端口自动检测');
}
break;
case 'production':
if (!this.config.httpsEnabled) {
warnings.push('生产环境建议启用HTTPS');
}
if (this.config.autoDetect) {
warnings.push('生产环境不建议启用端口自动检测');
}
if (!this.config.strictMode) {
recommendations.push('生产环境建议启用严格模式');
}
break;
case 'test':
if (this.config.openBrowser) {
recommendations.push('测试环境建议禁用自动打开浏览器');
}
break;
}
// 缓存配置验证
if (this.config.cacheEnabled && this.config.cacheExpiry < 60000) {
warnings.push('缓存过期时间过短可能影响性能');
}
const result = {
isValid: errors.length === 0,
errors,
warnings,
recommendations
};
// 输出验证结果
if (errors.length > 0) {
console.error('❌ 端口配置验证失败:', errors);
}
if (warnings.length > 0) {
console.warn('⚠️ 端口配置警告:', warnings);
}
if (recommendations.length > 0) {
console.info('💡 端口配置建议:', recommendations);
}
return result;
}
/**
* 获取当前配置
*/
getConfig(): PortEnvironmentConfig {
return { ...this.config };
}
/**
* 获取端口策略配置
*/
getPortStrategy(): PortStrategy {
return {
basePort: this.config.basePort,
portRange: [this.config.portRangeStart, this.config.portRangeEnd],
tenantOffset: this.config.tenantPortOffset,
environmentOffset: this.config.environmentPortOffset,
maxRetries: this.config.strictMode ? 10 : 50
};
}
/**
* 获取开发服务器配置
*/
getDevServerConfig(): {
host: string;
port?: number;
open: boolean;
cors: boolean;
https: boolean;
strictPort: boolean;
} {
return {
host: this.config.devHost,
open: this.config.openBrowser,
cors: this.config.corsEnabled,
https: this.config.httpsEnabled,
strictPort: this.config.strictMode
};
}
/**
* 获取环境信息
*/
getEnvironmentInfo(): {
current: Environment;
config: PortEnvironmentConfig;
validation: ConfigValidationResult;
recommendations: string[];
} {
const validation = this.validateConfiguration();
const recommendations: string[] = [];
// 基于环境生成建议
switch (this.environment) {
case 'development':
recommendations.push('开发环境:优先考虑便利性和调试体验');
recommendations.push('建议启用热重载和自动刷新功能');
break;
case 'test':
recommendations.push('测试环境:注重隔离性和可重复性');
recommendations.push('建议配置独立的端口范围避免冲突');
break;
case 'production':
recommendations.push('生产环境:优先考虑安全性和稳定性');
recommendations.push('建议使用固定端口和负载均衡');
break;
}
return {
current: this.environment,
config: this.config,
validation,
recommendations: [...validation.recommendations, ...recommendations]
};
}
/**
* 更新配置
*/
updateConfig(updates: Partial<PortEnvironmentConfig>): ConfigValidationResult {
this.config = { ...this.config, ...updates };
return this.validateConfiguration();
}
/**
* 重置为默认配置
*/
resetToDefaults(): void {
this.config = this.loadConfiguration();
console.log('🔄 端口配置已重置为默认值');
}
/**
* 导出配置
*/
exportConfig(): string {
const configLines = [
'# 智能端口管理配置',
`VITE_PORT_STRATEGY=${this.config.strategy}`,
`VITE_BASE_PORT=${this.config.basePort}`,
`VITE_PORT_RANGE_START=${this.config.portRangeStart}`,
`VITE_PORT_RANGE_END=${this.config.portRangeEnd}`,
`VITE_TENANT_PORT_OFFSET=${this.config.tenantPortOffset}`,
`VITE_ENVIRONMENT_PORT_OFFSET=${this.config.environmentPortOffset}`,
`VITE_PORT_AUTO_DETECT=${this.config.autoDetect}`,
`VITE_PORT_STRICT_MODE=${this.config.strictMode}`,
`VITE_PORT_CACHE_ENABLED=${this.config.cacheEnabled}`,
`VITE_PORT_CACHE_EXPIRY=${this.config.cacheExpiry}`,
'',
'# 开发服务器配置',
`VITE_DEV_HOST=${this.config.devHost}`,
`VITE_DEV_OPEN_BROWSER=${this.config.openBrowser}`,
`VITE_DEV_CORS_ENABLED=${this.config.corsEnabled}`,
`VITE_DEV_HTTPS_ENABLED=${this.config.httpsEnabled}`
];
return configLines.join('\n');
}
/**
* 获取配置摘要
*/
getConfigSummary(): {
environment: Environment;
strategy: string;
portRange: string;
features: string[];
status: 'healthy' | 'warning' | 'error';
} {
const validation = this.validateConfiguration();
const features: string[] = [];
if (this.config.autoDetect) features.push('自动检测');
if (this.config.cacheEnabled) features.push('缓存启用');
if (this.config.strictMode) features.push('严格模式');
if (this.config.httpsEnabled) features.push('HTTPS');
if (this.config.corsEnabled) features.push('CORS');
let status: 'healthy' | 'warning' | 'error' = 'healthy';
if (validation.errors.length > 0) {
status = 'error';
} else if (validation.warnings.length > 0) {
status = 'warning';
}
return {
environment: this.environment,
strategy: this.config.strategy,
portRange: `${this.config.portRangeStart}-${this.config.portRangeEnd}`,
features,
status
};
}
}
// 导出默认实例
export const portConfigManager = new PortConfigManager();