前端多语言翻译问题

49 阅读2分钟

1. 前言

多语言现在已经属于前端必备技能,但是在日常开发过程中经常会遇到语言定义混乱,翻译时部分语言缺失,那么有什么方法可以规避这类问题,提高我们的开发效率?

2. 核心目标

  • 统一管理:将不同语言的摘要集中在一个文件中。
  • 快速对比:直观比较各语言版本的关键信息是否一致。
  • 确保准确性:通过状态跟踪和责任人管理,保证翻译质量。
  • 支持决策:基于多语言信息提取全球趋势或区域差异。

3. 设计思想

  1. 使用excel集中多语言,
  2. 使用sheet页区分模块
  3. 使用列作为语言
  4. 使用行作为翻译内容
  5. 生成可执行的json文件

3. 实现

1. excel内容

  • commonsheet页
namezh-CNen-US
ok确定ok
  • messagesheet页
namezh-CNen-US
delete success删除成功Delete Success

2. 批处理脚本

  • 使用fs自带模块用于读取、写入文件
  • 使用xlsx解析excel

import { existsSync, writeFileSync, mkdirSync} from 'fs'
import {join} from 'path'
import XLSX from 'xlsx'
const rootPath = '';

// 配置
const excelFilePath = join(rootPath, '路径/文件名称'); // 你的 Excel 文件路径
const outputDir = join(rootPath, '路径'); // 输出目录

// 确保输出目录存在
if (!existsSync(outputDir)) {
  mkdirSync(outputDir);
}

// 读取 Excel
const workbook = XLSX.readFile(excelFilePath);
const sheetNames = workbook.SheetNames;

if (sheetNames.length === 0) {
  console.error('Excel 文件中没有工作表!');
  process.exit(1);
}

// 存储每种语言的所有翻译
const langData = {};

// 遍历每个 sheet
sheetNames.forEach(sheetName => {
  const worksheet = workbook.Sheets[sheetName];
  const data = XLSX.utils.sheet_to_json(worksheet, { header: 1 });

  if (data.length === 0) {
    console.warn(`⚠️  工作表 "${sheetName}" 为空,跳过...`);
    return;
  }

  const headers = data[0];
  const rows = data.slice(1);

  const nameIndex = headers.indexOf('name');
if (nameIndex === -1) {
    console.warn(`⚠️  工作表 "${sheetName}" 缺少 "name" 列,跳过...`);
    return;
  }

  // 获取语言列(排除 name)
  const langColumns = headers
    .map((header, index) => ({ header, index }))
    .filter(item => item.header !== 'name');

  if (langColumns.length === 0) {
    console.warn(`⚠️  工作表 "${sheetName}" 没有语言列,跳过...`);
    return;
  }

  // 初始化 langData 结构
  langColumns.forEach(({ header }) => {
    if (!langData[header]) {
      langData[header] = {};
    }
  });

  // 填充数据:使用命名空间 sheetName.key
  rows.forEach(row => {
    const key = row[nameIndex];
    if (!key) return;


   langColumns.forEach(({ header, index }) => {
      const value = row[index];
      if (value !== undefined && value !== '') {
        const namespacedKey = `${sheetName}.${key}`; // 使用sheet.key作为翻译词
        langData[header][namespacedKey] = value;
      }
    });
  });
  
  console.log(`✅ 处理完成 sheet: ${sheetName}`);
});

// 写入每种语言的 JSON 文件
Object.keys(langData).forEach(lang => {
  const filePath = join(outputDir, `${lang}.json`);

  // 可选:按 key 排序
  const sorted = Object.keys(langData[lang])
    .sort()
    .reduce((obj, key) => {
      obj[key] = langData[lang][key];
      return obj;
    }, {});

  writeFileSync(filePath, JSON.stringify(sorted, null, 2), 'utf-8');
  console.log(`✅ 生成: ${filePath}`);
});

console.log(`\n🎉 多语言 JSON 合并完成!共 ${Object.keys(langData).length} 种语言`);

3. 结果预览

  • zh-CN.json
{
    "message.delete success": "删除成功",
    "common.ok": "确定"
}
  • en-US.json
{
    "message.delete success": "删除成功",
    "common.ok": "确定"
}