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.

223 lines
5.8 KiB

2 days ago
const { readFileSync, existsSync } = require('fs')
const { resolve } = require('path')
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
2 days ago
/**
* 路由分析模块
* 负责分析路由配置从import语句中提取模块信息
2 days ago
*/
class RouteAnalyzer {
constructor() {
this.routes = []
this.componentModuleMap = new Map() // 组件名 -> 模块名的映射
2 days ago
}
/**
* 分析路由配置
* @returns {Array} 路由数组
*/
analyzeRoutes() {
this.routes = []
this.componentModuleMap.clear()
2 days ago
try {
const routeConfigPath = resolve(__dirname, '../../src/renderer/router/index.js')
if (existsSync(routeConfigPath)) {
const routeContent = readFileSync(routeConfigPath, 'utf-8')
// 第一步:解析import语句,建立组件与模块的映射关系
this.parseImportStatements(routeContent)
// 第二步:解析路由配置,为每个路由添加模块信息
2 days ago
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
}
/**
* 解析路由配置为每个路由添加模块信息
2 days ago
* @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)
}
}
2 days ago
}
})
} catch (error) {
// 静默处理错误
2 days ago
}
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
}
2 days ago
/**
* 获取模块列表
* @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