mirror of
https://github.com/Lydanne/spaceflow.git
synced 2026-03-11 19:52:45 +08:00
chore: 初始化仓库
This commit is contained in:
156
docs/advanced/i18n.md
Normal file
156
docs/advanced/i18n.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# i18n 国际化
|
||||
|
||||
Spaceflow 基于 [i18next](https://www.i18next.com/) 实现国际化,采用纯函数式设计,不依赖 NestJS DI。
|
||||
|
||||
## 语言检测优先级
|
||||
|
||||
1. 环境变量 `SPACEFLOW_LANG`
|
||||
2. `spaceflow.json` 中的 `lang` 字段
|
||||
3. 系统 locale(`process.env.LANG` / `process.env.LC_ALL`)
|
||||
4. 回退到 `zh-CN`
|
||||
|
||||
## 核心 API
|
||||
|
||||
### `initI18n(lang?: string)`
|
||||
|
||||
同步初始化 i18next。必须在 NestJS 模块加载前调用。
|
||||
|
||||
```typescript
|
||||
import { initI18n } from "@spaceflow/core";
|
||||
|
||||
initI18n(); // 自动检测语言
|
||||
initI18n("en"); // 手动指定
|
||||
```
|
||||
|
||||
### `t(key: string, options?: Record<string, unknown>)`
|
||||
|
||||
全局翻译函数,装饰器和运行时均可使用。
|
||||
|
||||
```typescript
|
||||
import { t } from "@spaceflow/core";
|
||||
|
||||
// 公共 key(默认命名空间)
|
||||
t("common.executionFailed", { error: msg });
|
||||
|
||||
// Extension 命名空间(用 : 分隔)
|
||||
t("build:description");
|
||||
t("review:options.dryRun");
|
||||
```
|
||||
|
||||
### `addLocaleResources(ns: string, resources: Record<string, Record<string, string>>)`
|
||||
|
||||
注册 Extension 的语言资源到指定命名空间。
|
||||
|
||||
```typescript
|
||||
import { addLocaleResources } from "@spaceflow/core";
|
||||
|
||||
addLocaleResources("hello", {
|
||||
"zh-CN": { description: "打招呼命令" },
|
||||
en: { description: "Say hello" },
|
||||
});
|
||||
```
|
||||
|
||||
## 命名空间规则
|
||||
|
||||
| 类型 | 命名空间 | 示例 |
|
||||
|------|----------|------|
|
||||
| 公共 key | 默认(`translation`) | `common.*`, `config.*`, `extensionLoader.*` |
|
||||
| 内部 Extension | Extension 名称 | `build:`, `dev:`, `commit:`, `install:` 等 |
|
||||
| 外部 Extension | Extension 名称 | `review:`, `publish:`, `ci-scripts:` 等 |
|
||||
|
||||
## 语言包结构
|
||||
|
||||
### core 公共语言包
|
||||
|
||||
```text
|
||||
core/src/locales/
|
||||
├── zh-cn/
|
||||
│ └── translation.json # 公共 key
|
||||
└── en/
|
||||
└── translation.json
|
||||
```
|
||||
|
||||
### Extension 语言包
|
||||
|
||||
```text
|
||||
cli/src/commands/<name>/locales/
|
||||
├── zh-cn/
|
||||
│ └── <name>.json
|
||||
├── en/
|
||||
│ └── <name>.json
|
||||
└── index.ts # 导入并注册资源
|
||||
```
|
||||
|
||||
## Extension 中使用 i18n
|
||||
|
||||
### 1. 创建语言包文件
|
||||
|
||||
```json
|
||||
// locales/zh-cn/hello.json
|
||||
{
|
||||
"description": "打招呼命令",
|
||||
"options.name": "名字",
|
||||
"greeting": "你好,{{name}}!"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 注册语言资源
|
||||
|
||||
```typescript
|
||||
// locales/index.ts
|
||||
import zhCN from "./zh-cn/hello.json";
|
||||
import en from "./en/hello.json";
|
||||
import { addLocaleResources } from "@spaceflow/core";
|
||||
|
||||
export const helloLocales = { "zh-CN": zhCN, en };
|
||||
|
||||
// Side-effect: 立即注册
|
||||
addLocaleResources("hello", helloLocales);
|
||||
```
|
||||
|
||||
### 3. 在命令中使用
|
||||
|
||||
```typescript
|
||||
import { t } from "@spaceflow/core";
|
||||
|
||||
// 必须在命令模块 import 之前导入 locales(side-effect)
|
||||
import "./locales";
|
||||
|
||||
@Command({
|
||||
name: "hello",
|
||||
description: t("hello:description"),
|
||||
})
|
||||
export class HelloCommand extends CommandRunner {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 在 Extension 入口声明
|
||||
|
||||
```typescript
|
||||
export class HelloExtension implements SpaceflowExtension {
|
||||
getMetadata(): SpaceflowExtensionMetadata {
|
||||
return {
|
||||
name: "hello",
|
||||
commands: ["hello"],
|
||||
locales: helloLocales, // 加载时自动注册
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 插值语法
|
||||
|
||||
使用 i18next 默认的 `{{variable}}` 语法:
|
||||
|
||||
```typescript
|
||||
t("hello:greeting", { name: "World" });
|
||||
// → "你好,World!"
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
- **同步初始化** — `initI18n()` 使用 `initSync`,确保装饰器执行时语言包已加载
|
||||
- **装饰器时机** — `@Command` / `@Option` 在 import 时执行,`initI18n()` 必须在所有命令模块 import 之前调用
|
||||
- **Side-effect import** — 每个 Extension 的 `locales/index.ts` 在导入时立即调用 `addLocaleResources`
|
||||
- **key 不存在时** — i18next 默认返回 key 本身,不会报错
|
||||
Reference in New Issue
Block a user