init: 初始化 AssetX 项目仓库
包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、 antdesign(管理后台)、landingpage(营销落地页)、 数据库 SQL 和配置文件。
This commit is contained in:
163
landingpage/scripts/validate-colors.js
Executable file
163
landingpage/scripts/validate-colors.js
Executable file
@@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* 颜色验证脚本
|
||||
*
|
||||
* 检查组件文件中是否还有硬编码的十六进制颜色值
|
||||
* 用法: node scripts/validate-colors.js
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// 硬编码颜色的正则模式
|
||||
const hardcodedColorPatterns = [
|
||||
// Tailwind 类名中的十六进制颜色: bg-[#hex], text-[#hex], border-[#hex]
|
||||
/(bg|text|border|from|to|via)-\[#[0-9a-fA-F]{3,8}\]/g,
|
||||
|
||||
// 内联样式中的十六进制颜色
|
||||
/(?:background|color|border)(?:Color)?:\s*['"]?#[0-9a-fA-F]{3,8}/g,
|
||||
|
||||
// 对象样式中的十六进制颜色
|
||||
/['"](?:background|color|border)(?:Color)?['"]\s*:\s*['"]#[0-9a-fA-F]{3,8}/g,
|
||||
];
|
||||
|
||||
// 允许的例外情况(特殊设计需求)
|
||||
const allowedExceptions = [
|
||||
// rgba/hsla 透明度值(毛玻璃效果等)
|
||||
/rgba?\(/,
|
||||
/hsla?\(/,
|
||||
|
||||
// 渐变色(gradient-to-br from-green-400 to-emerald-500 等非硬编码)
|
||||
// 注意:这里不排除硬编码的渐变,会被上面的模式捕获
|
||||
];
|
||||
|
||||
// 需要检查的目录
|
||||
const componentsDir = path.join(__dirname, '../components');
|
||||
|
||||
// 收集结果
|
||||
const results = {
|
||||
files: [],
|
||||
totalViolations: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* 检查单个文件
|
||||
*/
|
||||
function checkFile(filePath) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
const violations = [];
|
||||
|
||||
// 按行分析
|
||||
const lines = content.split('\n');
|
||||
|
||||
lines.forEach((line, index) => {
|
||||
hardcodedColorPatterns.forEach(pattern => {
|
||||
const matches = line.match(pattern);
|
||||
if (matches) {
|
||||
// 检查是否是允许的例外
|
||||
const isException = allowedExceptions.some(exceptionPattern =>
|
||||
exceptionPattern.test(line)
|
||||
);
|
||||
|
||||
if (!isException) {
|
||||
matches.forEach(match => {
|
||||
violations.push({
|
||||
line: index + 1,
|
||||
content: line.trim(),
|
||||
match: match,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (violations.length > 0) {
|
||||
results.files.push({
|
||||
path: path.relative(process.cwd(), filePath),
|
||||
violations: violations,
|
||||
count: violations.length,
|
||||
});
|
||||
results.totalViolations += violations.length;
|
||||
}
|
||||
|
||||
return violations.length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归扫描目录
|
||||
*/
|
||||
function scanDirectory(dir) {
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
|
||||
entries.forEach(entry => {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
scanDirectory(fullPath);
|
||||
} else if (entry.isFile() && /\.(tsx|ts|jsx|js)$/.test(entry.name)) {
|
||||
checkFile(fullPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印结果
|
||||
*/
|
||||
function printResults() {
|
||||
console.log('\n='.repeat(80));
|
||||
console.log('🎨 设计系统颜色验证报告');
|
||||
console.log('='.repeat(80));
|
||||
console.log();
|
||||
|
||||
if (results.totalViolations === 0) {
|
||||
console.log('✅ 太棒了!没有发现硬编码颜色值。');
|
||||
console.log();
|
||||
console.log('所有组件都已成功迁移到设计系统!');
|
||||
} else {
|
||||
console.log(`⚠️ 发现 ${results.totalViolations} 处硬编码颜色值,分布在 ${results.files.length} 个文件中:`);
|
||||
console.log();
|
||||
|
||||
results.files.forEach(file => {
|
||||
console.log(`📄 ${file.path} (${file.count} 处问题)`);
|
||||
console.log('─'.repeat(80));
|
||||
|
||||
// 按行号分组相同的问题
|
||||
const lineMap = new Map();
|
||||
file.violations.forEach(v => {
|
||||
if (!lineMap.has(v.line)) {
|
||||
lineMap.set(v.line, []);
|
||||
}
|
||||
lineMap.get(v.line).push(v.match);
|
||||
});
|
||||
|
||||
lineMap.forEach((matches, lineNum) => {
|
||||
const firstViolation = file.violations.find(v => v.line === lineNum);
|
||||
console.log(` 行 ${lineNum}: ${firstViolation.content.substring(0, 100)}${firstViolation.content.length > 100 ? '...' : ''}`);
|
||||
matches.forEach(match => {
|
||||
console.log(` ↳ ${match}`);
|
||||
});
|
||||
});
|
||||
|
||||
console.log();
|
||||
});
|
||||
|
||||
console.log('='.repeat(80));
|
||||
console.log('💡 建议:');
|
||||
console.log(' • 将硬编码颜色替换为设计系统的 token (如 text-text-primary, bg-bg-base 等)');
|
||||
console.log(' • 检查是否有特殊设计需求需要保留硬编码');
|
||||
console.log(' • 参考 /styles/design-system.css 中定义的颜色变量');
|
||||
}
|
||||
|
||||
console.log('='.repeat(80));
|
||||
console.log();
|
||||
|
||||
// 退出码
|
||||
process.exit(results.totalViolations > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
// 执行扫描
|
||||
console.log('🔍 正在扫描组件文件...');
|
||||
scanDirectory(componentsDir);
|
||||
printResults();
|
||||
Reference in New Issue
Block a user