You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

172 lines
4.9 KiB

const { resolve } = require('path')
const { existsSync, statSync } = require('fs')
const ApiCollector = require('./modules/api-collector')
const TriggerAnalyzer = require('./modules/trigger-analyzer')
const FileGenerator = require('./modules/file-generator')
const RouteAnalyzer = require('./modules/route-analyzer')
/**
* 模块化路由映射插件
* 收集直接映射关系
*/
function routeMappingPlugin() {
// 检查是否在静默模式下运行
const isSilentMode = process.env.ROUTE_MAPPING_SILENT === 'true' || process.argv.includes('--silent')
// 日志函数
const log = (message) => {
if (!isSilentMode) {
console.log(message)
}
}
return {
name: 'route-mapping-phase1',
// 防重复生成机制
_lastGenerationTime: 0,
_generationInProgress: false,
_generationCooldown: 10000, // 10秒冷却时间
_maxGenerationsPerMinute: 3, // 每分钟最多生成3次
_generationCount: 0,
_generationWindowStart: 0,
// 初始化模块
_apiCollector: new ApiCollector(),
_triggerAnalyzer: new TriggerAnalyzer(),
_fileGenerator: new FileGenerator(),
_routeAnalyzer: new RouteAnalyzer(),
// Webpack插件接口
apply(compiler) {
const self = this
// 在编译开始前就生成映射文件
compiler.hooks.beforeCompile.tapAsync('RouteMappingPlugin', (params, callback) => {
if (self._shouldSkipGeneration()) {
callback()
return
}
try {
self.collectDirectMappings()
callback()
} catch (error) {
callback(error)
}
})
// 备用钩子,确保在beforeRun时也执行
compiler.hooks.beforeRun.tapAsync('RouteMappingPlugin', (compilation, callback) => {
if (self._shouldSkipGeneration()) {
callback()
return
}
try {
self.collectDirectMappings()
callback()
} catch (error) {
callback(error)
}
})
},
// Vite插件接口
buildStart() {
this.collectDirectMappings()
},
// 在开发模式下也执行
configureServer(server) {
if (this._shouldSkipGeneration()) {
return
}
this.collectDirectMappings()
},
// 检查是否应该跳过生成
_shouldSkipGeneration() {
const now = Date.now()
// 如果正在生成中,跳过
if (this._generationInProgress) {
return true
}
// 如果在冷却期内,跳过
if (now - this._lastGenerationTime < this._generationCooldown) {
return true
}
// 检查每分钟生成次数限制
if (now - this._generationWindowStart > 60000) {
// 重置计数窗口
this._generationCount = 0
this._generationWindowStart = now
}
if (this._generationCount >= this._maxGenerationsPerMinute) {
return true
}
return false
},
// 检查是否需要重新生成文件 - 优化版本:每次都生成
_shouldRegenerateFile() {
// 为了优化调试,每次都重新生成文件
return true
},
// 收集直接映射关系 - 优化版本:简化逻辑
collectDirectMappings() {
try {
// 设置生成中标志
this._generationInProgress = true
// 检查文件是否需要重新生成
if (!this._shouldRegenerateFile()) {
return
}
// 第三步第一小步:启用API收集功能
// 1. 分析路由配置
const routes = this._routeAnalyzer.analyzeRoutes()
// 2. 收集API信息(第一层)
const moduleDirs = this._routeAnalyzer.getModuleDirs()
const apiMappings = this._apiCollector.collectApiMappings(moduleDirs)
// 生成包含路由和API信息的文件
this._fileGenerator.generateRouteApiMappingFile(routes, apiMappings)
// 重置生成中标志并更新时间戳
this._generationInProgress = false
this._lastGenerationTime = Date.now()
this._generationCount++
if (this._generationCount === 1) {
this._generationWindowStart = this._lastGenerationTime
}
// TODO: 后续步骤将在优化过程中逐步添加
// 3. 关联页面与API(第三层)
// const enhancedApiMappings = this._triggerAnalyzer.findTriggerSourcesForApiMappings(apiMappings)
// 4. 优化API映射
// const optimizedApiMappings = this._fileGenerator.optimizeApiMappings(enhancedApiMappings)
// 5. 生成最终映射文件
// this._fileGenerator.generateMappingFile(routes, optimizedApiMappings)
} catch (error) {
this._generationInProgress = false
throw error
}
}
}
}
module.exports = routeMappingPlugin