extract-i18n-json.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /**
  2. * 多语言文件 JS 转 JSON 工具
  3. *
  4. * 功能:将 src/assets/i18n/messages/*.js 文件转换为纯 JSON 格式
  5. * 目的:移除 JavaScript 语法(export default 和结尾的 ;),方便用于其他用途
  6. *
  7. * 使用方法:
  8. * node scripts/extract-i18n-json.js
  9. *
  10. * 输出:
  11. * scripts/output/i18n/zh.json - 中文翻译(纯JSON格式)
  12. * scripts/output/i18n/en.json - 英文翻译(纯JSON格式)
  13. */
  14. const fs = require('fs');
  15. const path = require('path');
  16. // 配置
  17. const CONFIG = {
  18. inputDir: path.join(__dirname, '../src/assets/i18n/messages'),
  19. outputDir: path.join(__dirname, 'output/i18n'),
  20. files: ['zh.js', 'en.js']
  21. };
  22. /**
  23. * 从 JS 文件提取 JSON 对象
  24. * @param {string} filePath - JS 文件路径
  25. * @returns {object} - 解析后的 JSON 对象
  26. */
  27. function extractJsonFromJs(filePath) {
  28. try {
  29. // 读取文件内容
  30. const content = fs.readFileSync(filePath, 'utf-8');
  31. // 移除 export default 语句和结尾的分号
  32. let jsonString = content
  33. .replace(/export\s+default\s+/g, '') // 移除 export default
  34. .trim(); // 去除首尾空白
  35. // 移除末尾的分号(如果存在)
  36. if (jsonString.endsWith(';')) {
  37. jsonString = jsonString.slice(0, -1);
  38. }
  39. // 使用 eval 解析对象(在受控环境中使用)
  40. // 注意:这里假设文件内容是可信的
  41. const jsonObj = eval('(' + jsonString + ')');
  42. return jsonObj;
  43. } catch (error) {
  44. console.error(`❌ 解析文件失败: ${filePath}`);
  45. console.error(error.message);
  46. throw error;
  47. }
  48. }
  49. /**
  50. * 确保目录存在
  51. * @param {string} dirPath - 目录路径
  52. */
  53. function ensureDirectoryExists(dirPath) {
  54. if (!fs.existsSync(dirPath)) {
  55. fs.mkdirSync(dirPath, { recursive: true });
  56. console.log(`📁 创建目录: ${dirPath}`);
  57. }
  58. }
  59. /**
  60. * 主函数
  61. */
  62. function main() {
  63. console.log('🚀 开始提取多语言 JSON...\n');
  64. // 确保输出目录存在
  65. ensureDirectoryExists(CONFIG.outputDir);
  66. let successCount = 0;
  67. let failCount = 0;
  68. // 处理每个文件
  69. CONFIG.files.forEach(filename => {
  70. try {
  71. const inputPath = path.join(CONFIG.inputDir, filename);
  72. const outputFilename = filename; // 保持 .js 扩展名
  73. const outputPath = path.join(CONFIG.outputDir, outputFilename);
  74. console.log(`📄 处理: ${filename}`);
  75. // 检查输入文件是否存在
  76. if (!fs.existsSync(inputPath)) {
  77. console.warn(`⚠️ 跳过: 文件不存在 ${inputPath}\n`);
  78. failCount++;
  79. return;
  80. }
  81. // 提取 JSON
  82. const jsonObj = extractJsonFromJs(inputPath);
  83. // 写入 JSON 文件(格式化输出,缩进2个空格)
  84. fs.writeFileSync(
  85. outputPath,
  86. JSON.stringify(jsonObj, null, 2),
  87. 'utf-8'
  88. );
  89. console.log(`✅ 成功: ${outputFilename} (${Object.keys(jsonObj).length} 条翻译)`);
  90. console.log(` 输出: ${outputPath}\n`);
  91. successCount++;
  92. } catch (error) {
  93. console.error(`❌ 失败: ${filename}\n`);
  94. failCount++;
  95. }
  96. });
  97. // 汇总
  98. console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
  99. console.log(`✨ 完成! 成功: ${successCount}, 失败: ${failCount}`);
  100. console.log(`📂 输出目录: ${CONFIG.outputDir}`);
  101. }
  102. // 执行
  103. main();