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

145 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 · 检测 / 校验命令
```bash
# 一键跑全部审计(基础 + 严格 + 覆盖)
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 里也定义了):
```bash
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`(除非紧急)