const { readFileSync, existsSync } = require('fs') const { resolve } = require('path') const parser = require('@babel/parser') const traverse = require('@babel/traverse').default /** * 路由分析模块 * 负责分析路由配置,从import语句中提取模块信息 */ class RouteAnalyzer { constructor() { this.routes = [] this.componentModuleMap = new Map() // 组件名 -> 模块名的映射 } /** * 分析路由配置 * @returns {Array} 路由数组 */ analyzeRoutes() { this.routes = [] this.componentModuleMap.clear() try { const routeConfigPath = resolve(__dirname, '../../src/renderer/router/index.js') if (existsSync(routeConfigPath)) { const routeContent = readFileSync(routeConfigPath, 'utf-8') // 第一步:解析import语句,建立组件与模块的映射关系 this.parseImportStatements(routeContent) // 第二步:解析路由配置,为每个路由添加模块信息 this.routes = this.parseRouteConfig(routeContent) } } catch (error) { // 静默处理错误 } return this.routes } /** * 解析import语句,建立组件与模块的映射关系 * @param {string} routeContent - 路由配置内容 */ parseImportStatements(routeContent) { try { const ast = parser.parse(routeContent, { sourceType: 'module', plugins: ['jsx', 'typescript'] }) const self = this traverse(ast, { ImportDeclaration(path) { const source = path.node.source.value // 解析模块路径,提取模块名 const moduleName = self.extractModuleName(source) if (moduleName) { // 处理导入的组件 path.node.specifiers.forEach(spec => { let componentName = null if (spec.type === 'ImportDefaultSpecifier') { // 默认导入:import Component from '...' componentName = spec.local.name } else if (spec.type === 'ImportSpecifier') { // 命名导入:import { Component } from '...' componentName = spec.imported.name } if (componentName) { self.componentModuleMap.set(componentName, moduleName) } }) } } }) } catch (error) { // 静默处理错误 } } /** * 从import路径中提取模块名 * @param {string} importPath - import路径 * @returns {string|null} 模块名 */ extractModuleName(importPath) { // 匹配 @/modules/module-name 格式 const moduleMatch = importPath.match(/@\/modules\/([^\/]+)/) if (moduleMatch) { return moduleMatch[1] } return null } /** * 解析路由配置,为每个路由添加模块信息 * @param {string} routeContent - 路由配置内容 * @returns {Array} 路由数组 */ parseRouteConfig(routeContent) { const routes = [] try { const ast = parser.parse(routeContent, { sourceType: 'module', plugins: ['jsx', 'typescript'] }) const self = this traverse(ast, { ObjectExpression(path) { // 查找路由对象 if (self.isRouteObject(path)) { const route = self.extractRouteInfo(path) if (route) { routes.push(route) } } } }) } catch (error) { // 静默处理错误 } return routes } /** * 判断是否是路由对象 * @param {Object} path - AST路径 * @returns {boolean} 是否是路由对象 */ isRouteObject(path) { const properties = path.node.properties return properties.some(prop => prop.key && prop.key.name === 'path' && prop.value && prop.value.type === 'StringLiteral' ) } /** * 从路由对象中提取路由信息 * @param {Object} path - AST路径 * @returns {Object|null} 路由信息 */ extractRouteInfo(path) { const route = {} const properties = path.node.properties properties.forEach(prop => { if (prop.key && prop.value) { const key = prop.key.name const value = prop.value switch (key) { case 'path': if (value.type === 'StringLiteral') { route.path = value.value } break case 'component': if (value.type === 'Identifier') { route.component = value.name // 从组件名获取模块信息 const moduleName = this.componentModuleMap.get(value.name) if (moduleName) { route.module = moduleName } } break case 'name': if (value.type === 'StringLiteral') { route.name = value.value } break case 'description': if (value.type === 'StringLiteral') { route.description = value.value } break } } }) // 只有当path和component都存在时才返回路由信息 if (route.path && route.component) { return route } return null } /** * 获取模块列表 * @returns {Array} 模块目录列表 */ getModuleDirs() { const moduleDirs = [] try { const modulesPath = resolve(__dirname, '../../src/renderer/modules') if (existsSync(modulesPath)) { const dirs = require('fs').readdirSync(modulesPath, { withFileTypes: true }) dirs.forEach(dirent => { if (dirent.isDirectory()) { moduleDirs.push(dirent.name) } }) } } catch (error) { // 静默处理错误 } return moduleDirs } } module.exports = RouteAnalyzer