最可控可审计的多语言方案是:统一用data-i18n标记+独立JSON语言包(./locales/下按BCP 47命名如zh.json、en-US.json)+localStorage记忆+Git分支/目录隔离,键名严格对齐、结构扁平,禁止混写逻辑或拆分模块,提交需带清晰语义前缀如docs(i18n): update zh.json "nav_settings"。

直接用 data-i18n 标记 + 独立 JSON 语言包 + localStorage 记忆 + Git 分支/目录隔离,是当前最可控、可审计、不依赖构建时生成的方案。硬编码文案、混写语言逻辑进 HTML 模板、或把多语言文件塞进同一 commit 而不做语义化提交,都会让协作和回滚变得危险。
怎么组织语言包文件结构才方便 Git 管理
每个语言一个独立 JSON 文件,统一放在 ./locales/ 目录下,命名严格遵循 BCP 47(如 zh.json、zh-HK.json、en-US.json),不要用 cn.json 或 english.json 这类非标准名。
- 所有语言包必须键名完全对齐、结构扁平;某语言暂未翻译也要保留键,设为空字符串:
"btn_submit": "" - 避免把语言包拆成模块(如
common.json+form.json)再合并——Git diff 会分散在多个文件,难以一眼看出某次翻译变更影响了哪些 UI 区域 - 不要把语言包放进
src/或dist/下的任意子目录;固定路径能减少 JS 加载逻辑里的拼接错误,也方便 CI 脚本校验缺失语言 - 在
.gitignore中排除./locales/*.json的自动格式化工具临时文件(如zh.json~),防止误提交
Git 提交时怎么写 message 才体现国际化变更意图
语言包修改不是“更新文案”,而是明确影响用户感知的变更。每次提交必须带上下文:谁改的、为什么改、影响哪些页面区域。
- 用
docs(i18n): update zh.json "nav_settings" and "error_network"这类 prefix + scope + action + key 的格式,比fix translation清晰得多 - 如果一次提交涉及多个语言文件,确保所有变更语义一致——比如
en.json改了"date_format",zh.json和ja.json必须同步更新,否则上线后日期字段会错乱 - 禁止在同一次 commit 里混入非 i18n 变更(如样式调整、JS 逻辑修改);分离关注点,否则
git bisect定位问题时会误判 - CI 流程中加一条检查:diff 中若出现
"btn_submit": "Submit"→"btn_submit": "提交"这类键值对变更,自动触发语言一致性扫描(比对其他语言文件是否含该键)
为什么不能把多语言 HTML 模板当代码分支管理
为每种语言建单独 HTML 文件(如 index.zh.html、index.en.html),再用 Git 分支维护,看似直观,实则破坏可维护性。
立即学习“前端免费学习笔记(深入)”;
- HTML 结构微调(如新增一个
<div class="banner">)需手动同步到所有分支,极易漏改,且 <code>git merge时冲突集中在模板本身,而非语义化文案 - 无法做跨语言的 diff:你没法快速看出
zh.json里"footer_copyright"是否比en.json少了年份变量 - SEO 和可访问性受损:不同语言 URL 对应不同 HTML 文件,但
lang属性可能没同步更新,屏幕阅读器读错语音,搜索引擎认为是重复内容 - 真正需要分支隔离的,是语言包本身的版本迭代(如 v1.2 → v1.3 翻译质量升级),而不是 HTML 结构——结构应始终唯一,靠 JS 动态注入文案
最易被忽略的点:语言包 JSON 文件的 Content-Type 响应头必须是 application/json,否则 fetch('./locales/zh.json') 在某些 CDN 或代理下会静默失败,Git 里看着文件存在,运行时却 fallback 到空字符串——这种问题不会出现在 diff 里,只能靠真实环境验证。



















