Files
lucky_shop/CLAUDE.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

6.9 KiB
Raw Blame History

CLAUDE.md —— 给 AI 看的项目守则

本文件是仓库根目录给 AI 助手的强制约束文档。做 i18n 改造前必须先读这份文件,违反任意一条都会导致运行时崩溃或被审计拦截。

0 · 项目身份

  • uni-app 商城前端(基于 Vue 2 + Webpack 5),多端编译(H5 / 微信小程序 / 鸿蒙元服务 / 支付宝 / 百度 / 头条)
  • 主语言:简体中文(zh-cn),辅:en-us
  • 构建入口:main.js + common/js/lang.js + lang/<locale>.js
  • 鸿蒙 / 快应用独立工程,与根目录无代码关系,跳过

1 · i18n 铁律(必读 · 违反会 throw / 拦截 / 阻断)

1.1 唯一权威 lang 源

  • 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,两侧 key 必须一一对应

1.2 命名空间强制

  • 所有 key 必须以业务命名空间开头(goods.* / member.* / order.* 等)
  • 扁平无前缀 key 一律重命名:save → <namespace>.save、login → <namespace>.loginButton
  • 命名空间清单:docs/i18n-taxonomy.md
  • 反例(禁止):save: '保存' / login: '登录' / title: '订单列表'
  • 正例:common.save: '保存' / login.button: '登录' / order.list.title: '订单列表'

1.3 禁止重复定义 key

  • 新增前必须 grep -r "<key>" lang/en-us.js lang/zh-cn.js
  • 已存在就复用,不允许再加一份
  • 当前架构下没有 page module 这种"分散文件",物理上不可能重复

1.4 运行时覆盖即 throw

  • common/js/lang.js 的 detectShadowing() 在 merge 前检测 page 是否覆盖 common 已有 key,直接 throw 阻断
  • 当前架构下 page 永远是空对象 {},detectShadowing 仅作防御保留
  • 任何 i18n 改造如果触发 throw,必须改 key 名字而不是覆盖
  • 这是 hard rule,dev/prod 一视同仁

1.5 其他铁律

  1. 禁止在一次 commit 里"先加 i18n 再回退硬编码"
  2. 禁止改 CSS / 模板结构 / 与本次任务无关的代码
  3. 禁止改写业务文案语义——diff 里"原值→新值"的语义变化必须 commit message 列"语义变更"段
  4. 禁止把 '+ '{{ $lang(...) }}' 这种字面模板写到 JS 字符串里(运行时会显示字面)
  5. 提交前必须跑 python scripts/i18n_check.py,全过才允许 commit
  6. en-us 端禁止把 Waitpay/Waitsend 这种首字母大写英文单词当翻译——必须给完整短语如 Pending Payment

2 · 改动 i18n 时的标准流程

1. 读 docs/i18n-taxonomy.md 确认 key 归属命名空间
2. grep "<新 key>" lang/en-us.js lang/zh-cn.js 确认无重复
3. 同步改 lang/en-us.js 与 lang/zh-cn.js(同 key 同结构)
4. 调用侧改 $lang('oldKey') 为 $lang('newKey')
5. 跑 python scripts/i18n_check.py 验证(基础+严格+覆盖 三项全过)
6. commit

3 · 命名空间快速参考

前缀 归属
common.* 全站通用
tabBar.* / customer.* tabBar / 客服
goods.* / cart.* / order.* / pay.* 商品 / 购物车 / 订单 / 支付
member.* 个人中心
coupon.* / point.* / hongbao.* 营销资产
fenxiao.* / merch.* 分销 / 商家后台
login.* / register.* / find.* 登录 / 注册 / 找回密码
article.* / topics.* / notice.* / help.* 内容
chat.* / ai_chat.* 客服 / AI
verification.* / recharge.* / diy.* 验证码 / 充值 / DIY
bargain.* / pintuan.* / groupbuy.* / seckill.* / combo.* / presale.* / bale.* 营销活动

完整清单见 docs/i18n-taxonomy.md。

4 · 占位符语法(唯一支持)

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

5 · 检测 / 校验命令

# 一键跑全部审计(基础 + 严格 + 覆盖)
python scripts/i18n_check.py

# Windows 等价入口
scripts\i18n_check.bat

# bash 等价入口
./scripts/i18n_check.sh

# 子命令
python scripts/i18n_check.py basic    # 只跑 i18n_audit.py
python scripts/i18n_check.py strict   # 只跑 i18n_strict_audit.py
python scripts/i18n_check.py shadow   # 只跑 i18n_class_c.py

# 应用调用侧改写(先用 dry-run 看 scope)
python scripts/i18n_rewrite_calls.py          # dry-run,不改文件
python scripts/i18n_rewrite_calls.py --apply  # 真正改写

# 清理死 key
python scripts/i18n_clean_dead.py             # dry-run
python scripts/i18n_clean_dead.py --apply     # 真删

等价 npm scripts(package.json 里也定义了):

npm run i18n:check      # 等价 python scripts/i18n_check.py
npm run i18n:audit      # 等价 python scripts/i18n_audit.py
npm run i18n:strict     # 等价 python scripts/i18n_check.py strict
npm run i18n:apply      # 等价 python scripts/i18n_rewrite_calls.py --apply
npm run i18n:merge      # 等价 python scripts/i18n_merge.py
npm run i18n:clean-dead # 等价 python scripts/i18n_clean_dead.py --apply

6 · 历史教训(避免再犯)

commit 错误类型 教训
f258987 把前 9 个 commit 的 i18n 一刀切删掉 "先加 i18n 再全删"是白做
750ed2d customerService.noServiceOffline + common.noCustomerService 同义不同 key 同义 key 必须合并
47098bd saveSuccess / yuan / searchResultCount 在 common/member/article 三处定义 同 key 三处重复=后续无法判断权威
cb81aad level.vue:221 写出 + '{{ $lang(...) }}' 字面字符串 JS 字符串里 {{ }} 不执行
e9483e2 删除 lang/zh-cn/agreement/contenr.js 没确认是否被引用 删除文件前先 grep 引用
b30ba91 this.$lang('order.noOrderInfo') 但同 commit 没添加 key 先加 key 再改调用点

完整复盘见 docs/i18n-rules.md 与各 docs/i18n-*-audit.json。

7 · 运行时的硬卡点

卡点 行为
common/js/lang.js#detectShadowing page 覆盖 common → throw(防御性保留,新架构下不会触发)
python scripts/i18n_check.py 跑全部审计,发现问题输出 docs/i18n-*-audit.json
vue.config.js#I18nGuardPlugin 生产构建 → 跑 class_c 审计 + 失败阻断(可 SKIP_I18N_GUARD=1 紧急绕过)

8 · 不要做的事(清单)

  • ❌ 不要重建 lang/en-us/ 或 lang/zh-cn/ 分散目录
  • ❌ 不要在 *.vue 里写 'login' 这种无前缀扁平 key(写成 common.login / login.button)
  • ❌ 不要在 main.js / common/js/lang.js 里加新逻辑绕过 throw
  • ❌ 不要删 lang/DEPRECATED.md 或 lang/_migration-map.json
  • ❌ 不要在生产构建里设 SKIP_I18N_GUARD=1(除非紧急)