Files
lucky_shop/docs/i18n-rules.md
ZF sun 5f41febd70 chore(i18n): 清理死代码 + 遗留 lang 文件 + 旧工具
## 删除的死代码脚本
- scripts/i18n_class_c.py (脚本自承'新架构下永远输出 0',纯防御性)
- scripts/full_migrate_i18n.py (其产出违反 CLAUDE.md 1.2 中文 key 铁律,已标 DEPRECATED)
- scripts/__pycache__/ (Python 缓存)

## 删除的旧 per-page lang 文件
- lang/zh-cn/<page>/<file>.js (140 个)
- lang/en-us/<page>/<file>.js (139 个)
- 共 279 个文件,运行时不再加载,0 个 key 被 .vue 调用(经 diagnose_keys.py 验证)

## 删除的备份和迁移表
- lang/_backup/ (git 已跟踪原文件)
- lang/_migration_map.json / lang/_migration-map.json (运行时不用)

## 删除的中间产物 JSON
- docs/i18n-rename-*.json (smart_rename 中间产物,已用完)
- docs/i18n-ambiguous.json / i18n-audit.json / i18n-call-rewrite.log /
  i18n-clean-dead.log / i18n-file-texts.json / i18n-page-titles.json /
  i18n-vue-extract.json (前一会话残留,无引用方)
- docs/i18n-{naming,shadow,strict}-audit.json (脚本会自动重新生成)

## 删除的 modular lang 文件
- lang/zh-cn/*.js / lang/en-us/*.js (20 个模块文件,内容是上一会话产生的死代码)
- lang/zh-cn/index.js / lang/en-us/index.js (聚合入口)
- lang/DEPRECATED.md (已不再相关)

## 删除的不成熟脚本
- scripts/check_perpage.py (诊断用,已完成)
- scripts/diagnose_keys.py (诊断用,已完成)
- scripts/smart_rename_i18n.py (v1-v3 都 bug,未修完)

## 现状
- lang/ 现在只有 zh-cn.js + en-us.js (单文件,运行时实际加载)
- 这两个文件已被 smart_rename 部分修复: camelCase → snake_case (8 个 key)
- 命名违规从 8236 降到 3505 (剩余都在单文件,可独立 commit 修复)
- 1362 个 orphan () 调用仍存在,详见 docs/i18n-handoff.md
2026-06-25 10:48:15 +08:00

5.0 KiB
Raw Blame History

i18n 改造铁律(AI 必须遵守)

本文档给 Claude / 其他 AI 在做 i18n 改造时作为强制约束。 违反任何一条都会导致运行时崩溃或被 CI 拦截。

8 条铁律

1. 禁止在一次 commit 里"先加 i18n 再回退硬编码"

  • 每次 commit 的目标必须可逆、可单独 cherry-pick
  • 不允许"完成 A 但中途又撤掉 A"
  • 历史教训:commit f258987 一刀切删掉前 9 个 commit 的 i18n 工作,全部归零

2. 禁止重复定义 key

  • 新增 key 前必须 grep "<新 key 路径>" lang/en-us.js lang/zh-cn.js
  • 已存在就复用,不允许再加一份
  • 校验:python scripts/i18n_check.py 必须 exit 0
  • 历史教训:commit 47098bd 把 saveSuccess / yuan / searchResultCount 在 common/member/article 三处定义各一次

3. 禁止改 CSS / 模板结构 / 与本次任务无关的代码

  • i18n 改造只允许动 $lang(...) 表达式内的字符串和 data()/methods 里被赋值的 lang key
  • 不允许改 <style>、不允许重新排版 <template> 结构、不允许动行缩进
  • 不允许夹带修复"顺手发现的其他 bug"
  • 历史教训:commit f258987 改了 pages_order/detail.vue 的 view 嵌套结构

4. 禁止改写业务文案语义

  • diff 里如果出现"原值→新值"的语义变化(不只是替换占位符),commit message 必须列出**"语义变更"**段
  • 例外:明确是 P0 翻译 bug 修复时(如修 swap、补未翻译的 en-us)允许
  • 历史教训:commit f258987 把"配送员电话"改成"外卖电话"、把"最高可减 N 元"丢了"最高"二字

5. 禁止把 '+ '{{ $lang(...) }}' 这种字面模板写到 JS 字符串里

  • JS 字符串里写的 '...' 是字面量,不是 Vue 模板插值
  • 错误写法:
    title: '订单 {{ $lang(\'order.title\') }}'  // ❌ 运行时显示字面 "{{ $lang(...) }}"
    
  • 正确写法:
    title: this.$lang('order.title')  // ✅
    
  • 历史教训:commit cb81aad 在 pages_promotion/fenxiao/level.vue:221 写出 + '{{ $lang(...) }}' 字面,线上 bug

6. lang 包只在 lang/en-us.js + lang/zh-cn.js 两份文件里改

  • 旧的 lang/en-us/** 与 lang/zh-cn/** 281 个文件已删除(详见 lang/DEPRECATED.md,可用 git restore 恢复)
  • 不允许重建分散目录、不允许往里加 key
  • 改两份文件必须同步:先 zh-cn,后 en-us,两侧文案必须语义对齐

7. 每个 commit 前必须跑 python scripts/i18n_check.py

  • 该命令跑 i18n_audit.py + i18n_strict_audit.py + i18n_class_c.py 三项
  • 任一检查返回非 0 必须先修复再 commit
  • Windows 等价:scripts\i18n_check.bat;bash 等价:./scripts/i18n_check.sh
  • 也可 npm run i18n:check(前提:装了 npm 依赖)

8. en-us 端禁止把英文单词当翻译

  • 错误写法:
    // ❌ en-us 端只写了英文单词,没有翻译
    waitpay: 'Waitpay'
    activist: 'Activist'
    
  • 正确写法(必须给完整短语):
    // ✅
    member.waitPay: 'Pending Payment'
    member.activist: 'After-sales'
    

命名空间规则(详见 docs/i18n-taxonomy.md)

  • 所有 key 必须以业务命名空间开头(goods.* / member.* / order.* 等)
  • 扁平无前缀 key 一律重命名:save → <namespace>.save、login → <namespace>.loginButton
  • 命名空间清单见 docs/i18n-taxonomy.md

运行时的硬卡点

common/js/lang.js 的 detectShadowing() 在 merge 之前检测 page module 是否覆盖 common 已有 key:

if (pageLang 定义了 commonLang 已有的 key) {
    throw new Error('[i18n] page module overrides common key "..."');
}

任何 i18n 改造如果触发此 throw,必须改 key 名字而不是覆盖。

占位符语法(当前唯一支持)

  • 位置风格:{0}、{1}、{2}
  • 例:discountDesc: '专享{0}折' → 调用 $lang('discountDesc', '9') 得 '专享9折'
  • 命名风格 {name} 不支持
  • %s/%d 不支持

违规检测

# 一键跑全部审计
python scripts/i18n_check.py

# 分项跑
python scripts/i18n_check.py basic    # 基础:孤儿 key / 死 key / 覆盖率
python scripts/i18n_check.py strict   # 严格:同 key 不同翻译 / 跨模块同名异义 / 大小写幽灵 / module 内自冲突
python scripts/i18n_check.py shadow   # 覆盖:page 覆盖 common

# Windows / bash 入口
scripts\i18n_check.bat
./scripts/i18n_check.sh

# npm scripts 等价(需要装依赖)
npm run i18n:check
npm run i18n:audit
npm run i18n:strict

历史教训回顾

# (在 lang/<locale>.js 加一个 page 风格的同名 key,启动 dev 应该 throw)
# 当前架构下 page 永远是 {},detectShadowing 是防御性的

违反以上任意一条会导致:

  • dev/prod 运行时 throw 阻断(detectShadowing)
  • python scripts/i18n_check.py 非 0 退出(本地手动跑)
  • webpack emit 钩子阻断生产构建(vue.config.js#I18nGuardPlugin)

历史教训的完整复盘见 docs/i18n-history-review.md(可选,AI 改造前可读)。