mirror of
https://github.com/Lydanne/spaceflow.git
synced 2026-03-11 19:52:45 +08:00
3.6 KiB
3.6 KiB
i18n 国际化
Spaceflow 基于 i18next 实现国际化,采用纯函数式设计,不依赖 NestJS DI。
语言检测优先级
- 环境变量
SPACEFLOW_LANG spaceflow.json中的lang字段- 系统 locale(
process.env.LANG/process.env.LC_ALL) - 回退到
zh-CN
核心 API
initI18n(lang?: string)
同步初始化 i18next。必须在 NestJS 模块加载前调用。
import { initI18n } from "@spaceflow/core";
initI18n(); // 自动检测语言
initI18n("en"); // 手动指定
t(key: string, options?: Record<string, unknown>)
全局翻译函数,装饰器和运行时均可使用。
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 的语言资源到指定命名空间。
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 公共语言包
core/src/locales/
├── zh-cn/
│ └── translation.json # 公共 key
└── en/
└── translation.json
Extension 语言包
cli/src/commands/<name>/locales/
├── zh-cn/
│ └── <name>.json
├── en/
│ └── <name>.json
└── index.ts # 导入并注册资源
Extension 中使用 i18n
1. 创建语言包文件
// locales/zh-cn/hello.json
{
"description": "打招呼命令",
"options.name": "名字",
"greeting": "你好,{{name}}!"
}
2. 注册语言资源
// 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. 在命令中使用
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 入口声明
export class HelloExtension implements SpaceflowExtension {
getMetadata(): SpaceflowExtensionMetadata {
return {
name: "hello",
commands: ["hello"],
locales: helloLocales, // 加载时自动注册
};
}
}
插值语法
使用 i18next 默认的 {{variable}} 语法:
t("hello:greeting", { name: "World" });
// → "你好,World!"
注意事项
- 同步初始化 —
initI18n()使用initSync,确保装饰器执行时语言包已加载 - 装饰器时机 —
@Command/@Option在 import 时执行,initI18n()必须在所有命令模块 import 之前调用 - Side-effect import — 每个 Extension 的
locales/index.ts在导入时立即调用addLocaleResources - key 不存在时 — i18next 默认返回 key 本身,不会报错