/** * JSON 排序脚本 * 对 locale JSON 文件按 key 字母顺序排序 * * 使用方法: * node scripts/sort-json.cjs # 排序所有 locale 文件 * node scripts/sort-json.cjs src/locales/en.json # 排序指定文件 * node scripts/sort-json.cjs --check # 检查是否已排序(不修改) */ const fs = require('fs') const path = require('path') // 配置 const LOCALES_DIR = path.join(__dirname, '../src/locales') const LOCALE_FILES = ['en.json', 'zh-cn.json'] /** * 读取并解析 JSON 文件 */ function readJSONFile(filePath) { try { const content = fs.readFileSync(filePath, 'utf-8') return JSON.parse(content) } catch (error) { console.error(`❌ 读取文件失败: ${filePath}`) console.error(error.message) return null } } /** * 按 key 排序 JSON 对象 */ function sortJSON(obj) { const sorted = {} const keys = Object.keys(obj).sort((a, b) => a.localeCompare(b, 'zh-CN')) for (const key of keys) { sorted[key] = obj[key] } return sorted } /** * 检查 JSON 是否已排序 */ function isJSONSorted(obj) { const keys = Object.keys(obj) const sortedKeys = [...keys].sort((a, b) => a.localeCompare(b, 'zh-CN')) return keys.every((key, index) => key === sortedKeys[index]) } /** * 保存 JSON 文件 */ function saveJSONFile(filePath, data) { const content = JSON.stringify(data, null, 2) + '\n' fs.writeFileSync(filePath, content, 'utf-8') } /** * 处理单个文件 */ function processFile(filePath, checkOnly = false) { const fileName = path.basename(filePath) if (!fs.existsSync(filePath)) { console.log(`⚠️ 文件不存在: ${fileName}`) return false } const data = readJSONFile(filePath) if (!data) return false const keyCount = Object.keys(data).length if (isJSONSorted(data)) { console.log(`✅ ${fileName} (${keyCount} keys) - 已排序`) return true } if (checkOnly) { console.log(`❌ ${fileName} (${keyCount} keys) - 未排序`) return false } const sorted = sortJSON(data) saveJSONFile(filePath, sorted) console.log(`✅ ${fileName} (${keyCount} keys) - 已排序并保存`) return true } /** * 处理所有 locale 文件 */ function processAllFiles(checkOnly = false) { console.log('\n📦 处理 locale 文件...\n') let allSorted = true for (const file of LOCALE_FILES) { const filePath = path.join(LOCALES_DIR, file) const result = processFile(filePath, checkOnly) if (!result) allSorted = false } console.log('') if (checkOnly && !allSorted) { console.log('💡 运行 "pnpm run i18n" 来排序文件\n') process.exit(1) } return allSorted } // 主逻辑 const args = process.argv.slice(2) const checkOnly = args.includes('--check') const targetFile = args.find((arg) => arg.endsWith('.json')) if (targetFile) { // 处理指定文件 const filePath = path.isAbsolute(targetFile) ? targetFile : path.join(process.cwd(), targetFile) processFile(filePath, checkOnly) } else { // 处理所有文件 processAllFiles(checkOnly) }