import path from 'path';
import { type PluginOption, type ResolvedConfig } from 'vite';
import { type ConfigRoute } from '../typings.d';
import fs from 'fs';
import type { MicroAppConfig } from '../microAppRouter';
export default function vitePluginCubeFront() {
const virtualModuleNamePrefix = 'cube';
const virtualModuleIdPrefix = 'virtual:cube-front-';
const resolvedVirtualModuleIdPrefix = '\0' + virtualModuleIdPrefix;
// 虚拟模块名称常量
const appName = 'app';
const microAppsName = 'micro-apps';
const configName = 'config';
/** 配置信息 */
let config: ResolvedConfig & { routes: ConfigRoute[]; };
/** 包含路由信息的字符串代码 */
let routesStr: string | undefined;
const viteCubeApp: PluginOption = {
name: `vite:${virtualModuleNamePrefix}-${appName}`,
enforce: 'post',
config: (_config, _m) => {
return {
// resolve: {
// alias: {
// 'cube-front': path.resolve(__dirname, './'),
// },
// },
};
},
configResolved: (_config) => {
// console.log('configResolved--------------------', config)
},
resolveId(id: string) {
if (id === virtualModuleIdPrefix + appName) {
return resolvedVirtualModuleIdPrefix + appName;
}
},
load(id: string) {
if (id === resolvedVirtualModuleIdPrefix + appName) {
return `
export const msg = "from virtual module"
export { default as App } from 'cube-front/core/App.vue'
`;
}
},
transform(code: string, _id: string) {
return code;
},
transformIndexHtml(html: string) {
return html;
},
};
// 新增应用配置插件
const viteCubeAppNames: PluginOption = {
name: `vite:${virtualModuleNamePrefix}-${microAppsName}`,
enforce: 'post',
configResolved: (cfg) => {
config = cfg as ResolvedConfig & { routes: ConfigRoute[]; };
},
resolveId(id: string) {
if (id === virtualModuleIdPrefix + microAppsName) {
return resolvedVirtualModuleIdPrefix + microAppsName;
}
},
load(id: string) {
if (id === resolvedVirtualModuleIdPrefix + microAppsName) {
try {
// 读取microAppConfig.json文件
const configPath = path.resolve(config.root, 'configs/microAppConfig.json');
const microAppConfigs = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as Array<MicroAppConfig>;
// 构建应用配置代码
const microAppConfigsStrList = microAppConfigs.map((app) => {
return {
name: app.name,
prefix: app.prefix,
module: `() => import('${app.packageName || app.name}')`
};
});
let code = `
const microAppConfigs = ${JSON.stringify(microAppConfigsStrList)}
export default microAppConfigs
`;
code = code.replace(/"(\(\)\s+=>\s+import\([^\)]+\))"/g, '$1'); // 去掉属性名的引号
return code;
} catch (error) {
console.error('Failed to load microAppConfig.json', error);
return `
const microAppConfigs = []
export default microAppConfigs
`;
}
}
},
};
// 配置虚拟模块插件
const viteCubeConfig: PluginOption = {
name: `vite:${virtualModuleNamePrefix}-${configName}`,
enforce: 'post',
configResolved: (cfg) => {
config = cfg as ResolvedConfig & { routes: ConfigRoute[]; };
},
resolveId(id: string) {
if (id === virtualModuleIdPrefix + configName) {
return resolvedVirtualModuleIdPrefix + configName;
}
},
load(id: string) {
if (id === resolvedVirtualModuleIdPrefix + configName) {
try {
const env = config.mode || 'dev';
const configsPath = path.resolve(config.root, 'configs');
// 查找所有配置文件
const configFiles: Record<string, string> = {};
// 查找通用配置文件 config.ts
const generalConfigPath = path.resolve(configsPath, 'config.ts');
if (fs.existsSync(generalConfigPath)) {
try {
const content = fs.readFileSync(generalConfigPath, 'utf-8');
const configMatch = content.match(/export\s+const\s+(\w+)\s*:\s*[^=]*=\s*({[\s\S]*?});/);
if (configMatch) {
configFiles.general = configMatch[2];
}
} catch (error) {
console.warn(`无法读取配置文件 config.ts:`, error);
throw new Error(`配置文件 config.ts 不存在或无法读取`);
}
}
// 查找环境特定配置文件 config.${env}.ts
const envConfigPath = path.resolve(configsPath, `config.${env}.ts`);
if (fs.existsSync(envConfigPath)) {
try {
const content = fs.readFileSync(envConfigPath, 'utf-8');
const configMatch = content.match(/export\s+const\s+(\w+)\s*:\s*[^=]*=\s*({[\s\S]*?});/);
if (configMatch) {
configFiles[env] = configMatch[2];
}
} catch (error) {
console.warn(`无法读取环境配置文件 config.${env}.ts:`, error);
throw new Error(`环境配置文件 config.${env}.ts 不存在或无法读取`);
}
}
return `
// 导出配置对象和当前环境
export const configData = ${JSON.stringify(configFiles)};
export const currentEnv = '${env}';
export default { configData, currentEnv };
`;
} catch (error) {
console.error('Failed to load config', error);
return `
export const configData = {};
export const currentEnv = 'dev';
export default { configData, currentEnv };
`;
}
}
},
};
return [viteCubeApp, viteCubeAppNames, viteCubeConfig];
}
|