docs(AGENTS): update i18n section to reflect chrome.i18n migration
- Replace react-i18next docs with chrome.i18n API documentation - Update translation file paths from i18n/locales/ to public/_locales/ - Update test mock description for chromeI18n - Remove references to useLazyTranslation, vendor-i18n chunk, and snackbar Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -72,7 +72,7 @@ src/pages/FeatureName/
|
|||||||
|
|
||||||
- 页面入口组件统一命名为 `Index`,通过 `export default function Index()` 导出
|
- 页面入口组件统一命名为 `Index`,通过 `export default function Index()` 导出
|
||||||
- Hook 负责所有状态管理和业务逻辑,通过返回值暴露给页面
|
- Hook 负责所有状态管理和业务逻辑,通过返回值暴露给页面
|
||||||
- 子组件可以独立调用 `useI18n`、`useSnackbar` 等全局 Hook
|
- 子组件可以独立调用 `useI18n` 等全局 Hook
|
||||||
- 当 `index.tsx` 超过 150 行时,必须拆分为 UI + Hook 模式
|
- 当 `index.tsx` 超过 150 行时,必须拆分为 UI + Hook 模式
|
||||||
- 复杂页面可增加 `contexts/`、`hooks/`、`components/` 子目录
|
- 复杂页面可增加 `contexts/`、`hooks/`、`components/` 子目录
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ src/pages/FeatureName/
|
|||||||
|
|
||||||
**浏览器兼容**: 优先使用 `wxt/browser` 导出的 `browser` 对象,而非原生 `chrome` API。
|
**浏览器兼容**: 优先使用 `wxt/browser` 导出的 `browser` 对象,而非原生 `chrome` API。
|
||||||
|
|
||||||
**代码分割**: `wxt.config.ts` 通过 `manualChunksForHtmlOnly()` 自动分组依赖(vendor-react、vendor-i18n、vendor-qr 等),无需手动配置。
|
**代码分割**: `wxt.config.ts` 通过 `manualChunksForHtmlOnly()` 自动分组依赖(vendor-react、vendor-qr、vendor-dnd 等),无需手动配置。
|
||||||
|
|
||||||
## 测试环境
|
## 测试环境
|
||||||
|
|
||||||
@@ -100,35 +100,37 @@ src/pages/FeatureName/
|
|||||||
- 全局变量: `vitest/globals` (describe, it, expect 等无需导入)
|
- 全局变量: `vitest/globals` (describe, it, expect 等无需导入)
|
||||||
- Setup 文件: `vitest.setup.ts` 自动 mock:
|
- Setup 文件: `vitest.setup.ts` 自动 mock:
|
||||||
- `chrome.*` / `browser.*` API (storage, tabs, runtime, cookies 等)
|
- `chrome.*` / `browser.*` API (storage, tabs, runtime, cookies 等)
|
||||||
- `react-i18next` (返回 key 作为翻译)
|
- `@/utils/chromeI18n` (从 `public/_locales/zh/messages.json` 加载真实翻译)
|
||||||
- `@/utils/useLazyTranslation` (返回 `ns:key` 格式翻译)
|
|
||||||
- `window.matchMedia`
|
- `window.matchMedia`
|
||||||
- 测试文件命名: `__tests__/*.test.{ts,tsx}` 或 `*.test.{ts,tsx}`
|
- 测试文件命名: `__tests__/*.test.{ts,tsx}` 或 `*.test.{ts,tsx}`
|
||||||
- Mock 模式: 使用 `vi.mock()` 进行模块级 mock,避免在测试文件中重复 mock 代码
|
- Mock 模式: 使用 `vi.mock()` 进行模块级 mock,避免在测试文件中重复 mock 代码
|
||||||
- 测试工具: `@testing-library/react` + `@testing-library/user-event` 进行组件测试
|
- 测试工具: `@testing-library/react` + `@testing-library/user-event` 进行组件测试
|
||||||
|
|
||||||
## i18n
|
## i18n (chrome.i18n)
|
||||||
|
|
||||||
- 命名空间: `common` (默认), `features`
|
项目使用 Chrome 扩展标准的 `chrome.i18n` API 进行本地化,通过 `src/utils/chromeI18n.ts` 提供类型安全的 React Hook 包装。
|
||||||
- 翻译键格式: `namespace:key` (如 `features:timestamp.title`)
|
|
||||||
- 语言: `zh` (默认), `en`
|
- **翻译文件**: `public/_locales/{zh,en}/messages.json`(Chrome 扩展标准格式)
|
||||||
- 翻译文件结构:
|
- **默认语言**: `zh`(在 `wxt.config.ts` 的 `manifest.default_locale` 中配置)
|
||||||
- `i18n/locales/{zh,en}/common.json` - 全局通用翻译
|
- **使用方式**: `import { useI18n } from '@/utils/chromeI18n'`
|
||||||
- `i18n/locales/{zh,en}/features.json` - 功能模块标题和描述
|
- **翻译键格式**:
|
||||||
- `i18n/locales/{zh,en}/{功能名}.json` - 各功能独立翻译(如 timestamp.json, storageCleaner.json 等)
|
- 直接 key: `t('dashboard_title')` → 查找 `dashboard_title`
|
||||||
- 添加新翻译: 编辑 `i18n/locales/{zh,en}/{common,features}.json` 及对应功能独立 JSON
|
- 命名空间格式(兼容旧用法): `t('common:buttons.search')` → 查找 `common_buttons_search`
|
||||||
- 使用 `useLazyTranslation` hook 加载功能独立翻译,返回 `ns:key` 格式
|
- 带命名空间参数: `useI18n(['common', 'features'])`,会自动尝试 `common_key`、`features_key`
|
||||||
- 回退策略: 当翻译 key 在目标语言缺失时,回退到默认语言 `zh`;若默认语言也缺失,返回占位格式 `namespace:key` 并在开发模式下记录 warning
|
- **占位符支持**: `t('router_notFoundDescription', { entryPointType: 'popup' })`
|
||||||
|
- **Hook 返回值**: `{ t, i18n: { language, changeLanguage }, isLoaded }`
|
||||||
|
- **回退策略**: 当翻译 key 未命中时,返回 key 本身(开发模式下在控制台记录 warning)
|
||||||
|
- **限制**: `chrome.i18n` 无法动态切换语言,语言跟随浏览器设置,切换后需刷新页面
|
||||||
|
|
||||||
## 新功能开发清单
|
## 新功能开发清单
|
||||||
|
|
||||||
1. 在 `src/types/storage.d.ts` 添加 `PageType` 联合类型
|
1. 在 `src/types/storage.d.ts` 添加 `PageType` 联合类型
|
||||||
2. 在 `src/config/features.tsx` 的 `FEATURES` 数组添加配置(指定 key、翻译键、图标、三种渲染模式的组件)
|
2. 在 `src/config/features.tsx` 的 `FEATURES` 数组添加配置(指定 key、翻译键、图标、三种渲染模式的组件)
|
||||||
3. 在 `src/pages/` 创建页面组件 (懒加载):
|
3. 在 `src/pages/` 创建页面组件 (懒加载):
|
||||||
- `index.tsx` — UI 组件,使用 `useLazyTranslation` 获取翻译
|
- `index.tsx` — UI 组件,使用 `useI18n` 获取翻译
|
||||||
- `useFeatureName.ts` — 业务逻辑 Hook
|
- `useFeatureName.ts` — 业务逻辑 Hook
|
||||||
- `constants.ts` — 常量(可选)
|
- `constants.ts` — 常量(可选)
|
||||||
4. 在 `i18n/locales/{zh,en}/features.json` 添加翻译(复杂功能可新建独立 JSON)
|
4. 在 `public/_locales/zh/messages.json`(及 `en/messages.json`)添加翻译
|
||||||
5. 如需新权限,更新 `wxt.config.ts` 的 `manifest.permissions`
|
5. 如需新权限,更新 `wxt.config.ts` 的 `manifest.permissions`
|
||||||
6. 添加对应的单元测试
|
6. 添加对应的单元测试
|
||||||
|
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
# i18n/
|
|
||||||
|
|
||||||
国际化资源目录,管理多语言翻译和 i18next 初始化配置。
|
|
||||||
|
|
||||||
## 目录结构
|
|
||||||
|
|
||||||
```
|
|
||||||
i18n/
|
|
||||||
├── index.ts # i18next 初始化配置
|
|
||||||
└── locales/
|
|
||||||
├── zh/ # 中文翻译(默认语言)
|
|
||||||
│ ├── common.json # 通用文案
|
|
||||||
│ ├── features.json # 功能模块标题和描述
|
|
||||||
│ ├── timestamp.json # 时间戳工具翻译
|
|
||||||
│ ├── storageCleaner.json # 存储清理工具翻译
|
|
||||||
│ ├── qrCode.json # 二维码工具翻译
|
|
||||||
│ ├── textStatistics.json # 文本统计工具翻译
|
|
||||||
│ ├── jwt.json # JWT 工具翻译
|
|
||||||
│ ├── jsonDiff.json # JSON 差异工具翻译
|
|
||||||
│ ├── jsonFormat.json # JSON 格式化工具翻译
|
|
||||||
│ ├── base64Converter.json
|
|
||||||
│ ├── markdownToHtml.json
|
|
||||||
│ ├── htmlToMarkdown.json
|
|
||||||
│ └── rightClickRestorer.json
|
|
||||||
└── en/ # 英文翻译(结构同上)
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## index.ts
|
|
||||||
|
|
||||||
i18next 初始化配置:
|
|
||||||
|
|
||||||
- 同步加载 `common` 和 `features` 核心命名空间
|
|
||||||
- 自定义 `chromeStorage` 语言检测器,从 Chrome Storage 读取语言偏好
|
|
||||||
- `normalizeLanguage()` 将任意语言标识归一化为 `zh` 或 `en`
|
|
||||||
- 语言变更时同步更新 Day.js 本地化和 localStorage 快照
|
|
||||||
|
|
||||||
## 翻译键格式
|
|
||||||
|
|
||||||
- 命名空间:`common`(默认)、`features`、各功能独立命名空间
|
|
||||||
- 键格式:`namespace:key`(如 `features:timestamp.title`、`timestamp:unitMs`)
|
|
||||||
|
|
||||||
## 使用方式
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
// 页面组件 — 懒加载翻译
|
|
||||||
import { useLazyTranslation } from '@/utils/useLazyTranslation';
|
|
||||||
const { t } = useLazyTranslation('timestamp');
|
|
||||||
t('timestamp:title');
|
|
||||||
|
|
||||||
// 全局组件 — 直接使用
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
const { t } = useTranslation(['common', 'features']);
|
|
||||||
t('common:settings');
|
|
||||||
```
|
|
||||||
|
|
||||||
## 添加新翻译
|
|
||||||
|
|
||||||
1. 在 `locales/{zh,en}/features.json` 添加功能标题和描述
|
|
||||||
2. 创建 `locales/{zh,en}/{功能名}.json` 添加功能专属翻译
|
|
||||||
3. 在 `utils/useLazyTranslation.ts` 的 `localeModules` 中注册新命名空间
|
|
||||||
Reference in New Issue
Block a user