/* * @Author: 季万俊 * @Date: 2025-12-05 * @Description: 根据资源版本条件导入资源和组件 */ export default function createConditionalAssets(assetsVersion) { if (!assetsVersion) { return { name: 'vite-plugin-conditional-assets' } } // 确定需要排除的版本 const allVersions = ['wuhan', 'shiyan', 'suzhou'] const excludeVersions = allVersions.filter(v => v !== assetsVersion) console.log(`\n🎯 条件资源插件已启用`) console.log(` 当前版本: ${assetsVersion}`) console.log(` 排除版本: ${excludeVersions.join(', ')}\n`) return { name: 'vite-plugin-conditional-assets', enforce: 'pre', // 拦截模块解析 - 阻止不需要的组件被加载 resolveId(source, importer) { // 忽略样式文件和其他非组件文件 if (source.includes('.scss') || source.includes('.css') || source.includes('.sass') || source.includes('.less') || source.includes('?url') || source.includes('?raw')) { return null } // 检查是否是需要排除的 plan 组件 for (const excludeVersion of excludeVersions) { if (source.includes(`/plan/${excludeVersion}.vue`) || source.includes(`\\plan\\${excludeVersion}.vue`)) { console.log(` 🚫 阻止加载: plan/${excludeVersion}.vue`) // 返回虚拟模块 ID return '\0virtual:empty-component' } } return null }, // 加载虚拟模块 - 返回空组件 load(id) { if (id === '\0virtual:empty-component') { // 返回一个空的 Vue 组件 return ` export default { name: 'EmptyComponent', render() { return null } } ` } return null }, // 在构建时转换代码 transform(code, id) { // 只在构建模式且是 dashboard/index.vue 时处理 if (!id.includes('dashboard/index.vue')) { return null } // 检测当前导入的 plan 组件 const planImportRegex = /import\s+plan\s+from\s+['"]\.\.\/\.\.\/plan\/(wuhan|shiyan|suzhou)\.vue['"]/ const match = code.match(planImportRegex) if (match) { const currentPlanType = match[1] // 'wuhan' 或 'shiyan' // 如果导入的不是当前需要的版本,替换它 if (currentPlanType !== assetsVersion) { const newCode = code.replace( planImportRegex, `import plan from "../plan/${assetsVersion}.vue"` ) console.log(` 🔄 替换组件: plan/${currentPlanType}.vue → plan/${assetsVersion}.vue`) return { code: newCode, map: null } } else { console.log(` ✅ 组件已是目标版本: plan/${assetsVersion}.vue`) } } return null }, // 最后阶段:从打包结果中删除不需要版本的资源文件 generateBundle(options, bundle) { const removedFiles = [] const keptFiles = [] // 遍历所有打包的文件 Object.keys(bundle).forEach(fileName => { const fileInfo = bundle[fileName] // 检查是否是资源文件 if (fileInfo.type === 'asset') { // 检查各种可能的路径属性,用于判断文件来源 const pathsToCheck = [ fileInfo.facadeModuleId, fileInfo.name, fileInfo.originalFileName, fileInfo.preliminaryFileName, fileName, // 构建后的文件名 ].filter(p => p) // 过滤掉空值 let fileVersion = null // 文件所属的版本 let shouldRemove = false // 从路径中提取版本信息 for (const pathToCheck of pathsToCheck) { const pathStr = String(pathToCheck) // 检查路径中是否包含版本目录(如 /assets/wuhan/、/assets/shiyan/、/assets/suzhou/) for (const version of allVersions) { if (pathStr.includes(`/assets/${version}/`) || pathStr.includes(`\\assets\\${version}\\`) || pathStr.includes(`assets/${version}/`) || pathStr.includes(`assets\\${version}\\`)) { fileVersion = version break } } if (fileVersion) break } // 根据文件版本决定是否保留 if (fileVersion) { // 文件有明确的版本目录 if (fileVersion === assetsVersion) { // 当前版本的文件,保留 keptFiles.push({ fileName, version: fileVersion, reason: '当前版本资源' }) shouldRemove = false } else { // 其他版本的文件,删除 removedFiles.push({ fileName, version: fileVersion, reason: '其他版本资源' }) shouldRemove = true } } else { // 文件没有版本目录(如 /assets/icon/、/assets/beij/ 等公共资源),保留 keptFiles.push({ fileName, version: 'common', reason: '公共资源(无版本目录)' }) shouldRemove = false } if (shouldRemove) { delete bundle[fileName] } } }) if (removedFiles.length > 0) { console.log(`\n🗑️ 已从打包结果中移除 ${removedFiles.length} 个资源文件:`) removedFiles.forEach(({ fileName, version, reason }) => { console.log(` - ${fileName} (${version}版本, ${reason})`) }) } if (keptFiles.length > 0) { console.log(`\n✅ 保留的资源文件 (${keptFiles.length} 个):`) const versionGroups = {} keptFiles.forEach(({ fileName, version, reason }) => { if (!versionGroups[version]) { versionGroups[version] = [] } versionGroups[version].push({ fileName, reason }) }) Object.keys(versionGroups).forEach(version => { console.log(` ${version === 'common' ? '公共资源' : version + '版本'} (${versionGroups[version].length} 个)`) }) } console.log(`\n✅ 构建完成!只包含 ${assetsVersion} 版本的资源\n`) } } }