前端国际化自动化方案从手工劳动到工程化实践当 Web 产品要进入国际市场时国际化i18n就成了基础需求。传统开发方式下支持多语言是个麻烦事——开发者得手动把中文换成 key再在 JSON 文件里一个个填翻译。今天聊聊怎么用工程化手段自动搞定这些事。一、手动处理 i18n 的三个坑没自动化工具时手动维护多语言配置总出这些问题漏译错译代码里新增的文案经常忘了同步到en.json这些文件上线后界面直接显示 key 名。开发效率低每改一句话都要切到 JSON 文件对齐思路老被打断。文件臃肿功能下线后对应的翻译 key 还留在文件里白白占空间。二、编译时自动提取方案核心思路是把提取和校验放进构建流程graph TD A[代码里写中文] -- B[静态扫描提取文案] B -- C[生成 key 对照表] C -- D{对比现有配置文件} D --|缺翻译| E[生成待翻译补丁] D --|有多余 key| F[清理无用配置] E -- G[调用翻译 API] G -- H[合并到主分支]具体实现分两步提取器用 AST 或正则抓代码里的t(文案)内容校验器在 CI 里比对提取的 key 和配置文件漏了就直接报错三、原生 Node.js 检测工具这里有个纯原生实现的扫描脚本只用fs和path能检查代码里用的 key 是否都在 JSON 里定义了const fs require(fs); const path require(path); class I18nGatekeeper { constructor(localesDir, sourceDir) { this.localesDir localesDir; this.sourceDir sourceDir; this.translationKeys new Set(); } scanSourceFiles(dir) { const list fs.readdirSync(dir); const i18nRegex /\$?t\(\s*[]([^])[]\s*\)/g; list.forEach(item { const fullPath path.join(dir, item); const stat fs.statSync(fullPath); if (stat.isDirectory() ![node_modules, dist].includes(item) !item.startsWith(.)) { this.scanSourceFiles(fullPath); } else if (stat.isFile() /\.(js|ts|vue|jsx|tsx)$/.test(item)) { try { const content fs.readFileSync(fullPath, utf8); let match; i18nRegex.lastIndex 0; while ((match i18nRegex.exec(content)) ! null) { this.translationKeys.add(match[1]); } } catch (e) { console.error(读取文件 ${fullPath} 失败: ${e.message}); } } }); } verifyLocales() { const localeFiles fs.readdirSync(this.localesDir).filter(f f.endsWith(.json)); let hasErrors false; localeFiles.forEach(file { const filePath path.join(this.localesDir, file); try { const localeData JSON.parse(fs.readFileSync(filePath, utf8)); const missingKeys []; this.translationKeys.forEach(key { if (!(key in localeData)) { missingKeys.push(key); } }); if (missingKeys.length 0) { hasErrors true; console.log(\n ${file} 缺失翻译:); missingKeys.forEach(k console.log( - ${k})); } } catch (err) { console.error(解析 ${file} 失败: ${err.message}); } }); return !hasErrors; } } // 测试代码实际使用时替换真实路径 if (require.main module) { const gatekeeper new I18nGatekeeper(./locales, ./src); gatekeeper.scanSourceFiles(./src); if (!gatekeeper.verifyLocales()) { console.log(\n❌ 发现翻译缺失CI 应拦截); process.exit(1); } }四、落地建议实际用这套方案时要注意所有新文案必须用t()包裹老代码逐步重构把扫描脚本集成到 CI漏翻译直接打回 PR可以对接 Crowdin 这类平台自动同步翻译五、小结做过国际化的都知道手动维护 JSON 文件有多痛苦。这套方案把提取、校验、翻译都自动化后确实能省不少事。不过要注意扫描规则得覆盖项目所有场景否则会有漏网之鱼。