Files
wwjcloud-nest-v1/scripts/route-normalization-simple.js
wanwu 6eb9ea687d feat: 初始化项目代码
- 迁移 NestJS 项目结构
- 添加 uniappx 前端代码
- 配置数据库连接
- 添加核心业务模块
2026-04-02 21:25:02 +08:00

243 lines
7.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* NestJS vs Java 路由规范化对比脚本(简化版)
* 使用内置模块,解决参数风格差异、空子路径等问题
*/
const fs = require('fs');
const path = require('path');
// 路由规范化函数
function normalizeRoute(route) {
return route
.replace(/:([^/]+)/g, '{$1}') // :param -> {param}
.replace(/\/$/g, '') // 移除尾部斜杠
.replace(/^\/$/, ''); // 处理根路径
}
// 查找所有控制器文件
function findControllers(dir, extension, controllers = []) {
try {
const items = fs.readdirSync(dir);
for (const item of items) {
const fullPath = path.join(dir, item);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
findControllers(fullPath, extension, controllers);
} else if (item.endsWith(extension)) {
controllers.push(fullPath);
}
}
} catch (error) {
console.warn(`警告: 无法访问目录 ${dir}: ${error.message}`);
}
return controllers;
}
// 提取NestJS路由信息
function extractNestJSRoutes(controllerPath) {
try {
const content = fs.readFileSync(controllerPath, 'utf8');
const routes = [];
// 提取类级Controller路径
const controllerMatch = content.match(/@Controller\(["'`]([^"'`]+)["'`]\)/);
const basePath = controllerMatch ? controllerMatch[1] : '';
if (!basePath) return routes;
// 提取方法级路由 - 改进正则
const methodPattern = /@(Get|Post|Put|Delete|Patch)\((["'`]([^"'`]*)["'`])?\)[\s\S]*?(async\s+)?(\w+)\s*\(/g;
let match;
while ((match = methodPattern.exec(content)) !== null) {
const method = match[1].toUpperCase();
const subPath = match[3] || '';
const fullPath = normalizeRoute(path.posix.join(basePath, subPath));
routes.push({
method,
path: fullPath,
basePath,
subPath,
file: path.basename(controllerPath)
});
}
return routes;
} catch (error) {
console.warn(`警告: 无法读取文件 ${controllerPath}: ${error.message}`);
return [];
}
}
// 提取Java路由信息
function extractJavaRoutes(controllerPath) {
try {
const content = fs.readFileSync(controllerPath, 'utf8');
const routes = [];
// 提取类级RequestMapping路径
const classMappingMatch = content.match(/@RequestMapping\(["'`]([^"'`]+)["'`]\)/);
const basePath = classMappingMatch ? classMappingMatch[1] : '';
if (!basePath) return routes;
// 提取方法级路由 - 改进正则
const methodPattern = /@(GetMapping|PostMapping|PutMapping|DeleteMapping|RequestMapping)\((["'`]([^"'`]*)["'`])?\)[\s\S]*?(\w+)\s*\(/g;
let match;
while ((match = methodPattern.exec(content)) !== null) {
const annotation = match[1];
const subPath = match[3] || '';
let method = 'GET';
if (annotation === 'PostMapping') method = 'POST';
else if (annotation === 'PutMapping') method = 'PUT';
else if (annotation === 'DeleteMapping') method = 'DELETE';
const fullPath = normalizeRoute(path.posix.join(basePath, subPath));
routes.push({
method,
path: fullPath,
basePath,
subPath,
file: path.basename(controllerPath)
});
}
return routes;
} catch (error) {
console.warn(`警告: 无法读取文件 ${controllerPath}: ${error.message}`);
return [];
}
}
// 主对比函数
function compareRoutes(nestDir, javaDir) {
console.log('🔍 正在扫描NestJS控制器...');
const nestControllers = findControllers(nestDir, '.controller.ts');
console.log(`✅ 找到 ${nestControllers.length} 个NestJS控制器`);
console.log('🔍 正在扫描Java控制器...');
const javaControllers = findControllers(javaDir, 'Controller.java');
console.log(`✅ 找到 ${javaControllers.length} 个Java控制器`);
const nestRoutes = [];
const javaRoutes = [];
// 提取NestJS路由
nestControllers.forEach(file => {
const routes = extractNestJSRoutes(file);
nestRoutes.push(...routes);
});
// 提取Java路由
javaControllers.forEach(file => {
const routes = extractJavaRoutes(file);
javaRoutes.push(...routes);
});
console.log(`\n📊 NestJS路由总数: ${nestRoutes.length}`);
console.log(`📊 Java路由总数: ${javaRoutes.length}`);
// 对比分析
const comparison = {
total: {
nest: nestRoutes.length,
java: javaRoutes.length
},
matches: [],
missingInNest: [],
missingInJava: [],
nestRoutes: nestRoutes,
javaRoutes: javaRoutes
};
// 标准化路由键用于对比
const getRouteKey = (route) => `${route.method}:${route.path}`;
const nestRouteMap = new Map(nestRoutes.map(r => [getRouteKey(r), r]));
const javaRouteMap = new Map(javaRoutes.map(r => [getRouteKey(r), r]));
// 查找匹配项
for (const [key, nestRoute] of nestRouteMap) {
if (javaRouteMap.has(key)) {
comparison.matches.push({
route: key,
nestFile: nestRoute.file,
javaFile: javaRouteMap.get(key).file
});
} else {
comparison.missingInJava.push(nestRoute);
}
}
// 查找Java中缺失的项
for (const [key, javaRoute] of javaRouteMap) {
if (!nestRouteMap.has(key)) {
comparison.missingInNest.push(javaRoute);
}
}
return comparison;
}
// 执行对比
console.log('🚀 NestJS vs Java 路由规范化对比开始...\n');
const nestDir = '/Users/wanwu/Documents/wanwujie/wwjcloud-nsetjs/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers';
const javaDir = '/Users/wanwu/Documents/wanwujie/wwjcloud-nsetjs/niucloud-java/niucloud-core/src/main/java/com/niu/core/controller';
try {
const result = compareRoutes(nestDir, javaDir);
console.log('\n📊 对比结果:');
console.log(`✅ 匹配路由: ${result.matches.length}`);
console.log(`❌ NestJS缺失: ${result.missingInNest.length}`);
console.log(`⚠️ Java缺失: ${result.missingInJava.length}`);
console.log(`📈 覆盖率: ${((comparison.matches.length / comparison.total.java) * 100).toFixed(1)}%`);
// 详细分析缺失情况
if (result.missingInNest.length > 0) {
console.log('\n🔍 NestJS缺失路由详情按模块分组');
const missingByModule = {};
result.missingInNest.forEach(route => {
const module = route.path.split('/')[1] || 'root';
if (!missingByModule[module]) missingByModule[module] = [];
missingByModule[module].push(route);
});
Object.keys(missingByModule).sort().forEach(module => {
console.log(`\n ${module}:`);
missingByModule[module].forEach(route => {
console.log(` ${route.method} ${route.path} (${route.file})`);
});
});
}
// 生成修复建议
if (result.missingInNest.length > 0) {
console.log('\n🔧 修复建议:');
console.log('1. 检查是否存在路由风格差异(:param vs {param}');
console.log('2. 验证空子路径是否正确处理(@Post("")');
console.log('3. 确认路径前缀是否统一adminapi vs api');
console.log('4. 检查模块分组逻辑是否一致');
}
console.log('\n✅ 对比完成!');
// 保存详细结果到文件
const outputFile = '/Users/wanwu/Documents/wanwujie/wwjcloud-nsetjs/route-comparison-result.json';
fs.writeFileSync(outputFile, JSON.stringify(result, null, 2));
console.log(`\n📄 详细结果已保存到: ${outputFile}`);
} catch (error) {
console.error('❌ 对比过程中发生错误:', error.message);
process.exit(1);
}