sort-json.cjs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /**
  2. * JSON 排序脚本
  3. * 对 locale JSON 文件按 key 字母顺序排序
  4. *
  5. * 使用方法:
  6. * node scripts/sort-json.cjs # 排序所有 locale 文件
  7. * node scripts/sort-json.cjs src/locales/en.json # 排序指定文件
  8. * node scripts/sort-json.cjs --check # 检查是否已排序(不修改)
  9. */
  10. const fs = require('fs')
  11. const path = require('path')
  12. // 配置
  13. const LOCALES_DIR = path.join(__dirname, '../src/locales')
  14. const LOCALE_FILES = ['en.json', 'zh-cn.json']
  15. /**
  16. * 读取并解析 JSON 文件
  17. */
  18. function readJSONFile(filePath) {
  19. try {
  20. const content = fs.readFileSync(filePath, 'utf-8')
  21. return JSON.parse(content)
  22. } catch (error) {
  23. console.error(`❌ 读取文件失败: ${filePath}`)
  24. console.error(error.message)
  25. return null
  26. }
  27. }
  28. /**
  29. * 按 key 排序 JSON 对象
  30. */
  31. function sortJSON(obj) {
  32. const sorted = {}
  33. const keys = Object.keys(obj).sort((a, b) => a.localeCompare(b, 'zh-CN'))
  34. for (const key of keys) {
  35. sorted[key] = obj[key]
  36. }
  37. return sorted
  38. }
  39. /**
  40. * 检查 JSON 是否已排序
  41. */
  42. function isJSONSorted(obj) {
  43. const keys = Object.keys(obj)
  44. const sortedKeys = [...keys].sort((a, b) => a.localeCompare(b, 'zh-CN'))
  45. return keys.every((key, index) => key === sortedKeys[index])
  46. }
  47. /**
  48. * 保存 JSON 文件
  49. */
  50. function saveJSONFile(filePath, data) {
  51. const content = JSON.stringify(data, null, 2) + '\n'
  52. fs.writeFileSync(filePath, content, 'utf-8')
  53. }
  54. /**
  55. * 处理单个文件
  56. */
  57. function processFile(filePath, checkOnly = false) {
  58. const fileName = path.basename(filePath)
  59. if (!fs.existsSync(filePath)) {
  60. console.log(`⚠️ 文件不存在: ${fileName}`)
  61. return false
  62. }
  63. const data = readJSONFile(filePath)
  64. if (!data) return false
  65. const keyCount = Object.keys(data).length
  66. if (isJSONSorted(data)) {
  67. console.log(`✅ ${fileName} (${keyCount} keys) - 已排序`)
  68. return true
  69. }
  70. if (checkOnly) {
  71. console.log(`❌ ${fileName} (${keyCount} keys) - 未排序`)
  72. return false
  73. }
  74. const sorted = sortJSON(data)
  75. saveJSONFile(filePath, sorted)
  76. console.log(`✅ ${fileName} (${keyCount} keys) - 已排序并保存`)
  77. return true
  78. }
  79. /**
  80. * 处理所有 locale 文件
  81. */
  82. function processAllFiles(checkOnly = false) {
  83. console.log('\n📦 处理 locale 文件...\n')
  84. let allSorted = true
  85. for (const file of LOCALE_FILES) {
  86. const filePath = path.join(LOCALES_DIR, file)
  87. const result = processFile(filePath, checkOnly)
  88. if (!result) allSorted = false
  89. }
  90. console.log('')
  91. if (checkOnly && !allSorted) {
  92. console.log('💡 运行 "pnpm run i18n" 来排序文件\n')
  93. process.exit(1)
  94. }
  95. return allSorted
  96. }
  97. // 主逻辑
  98. const args = process.argv.slice(2)
  99. const checkOnly = args.includes('--check')
  100. const targetFile = args.find((arg) => arg.endsWith('.json'))
  101. if (targetFile) {
  102. // 处理指定文件
  103. const filePath = path.isAbsolute(targetFile) ? targetFile : path.join(process.cwd(), targetFile)
  104. processFile(filePath, checkOnly)
  105. } else {
  106. // 处理所有文件
  107. processAllFiles(checkOnly)
  108. }