国际化 (i18n)
概述
@bdky/aaas-pilot-kit 从 v1.1.2 开始支持国际化(i18n),基于 ICU MessageFormat 标准实现,内置支持 中文、英文、日文、韩文 4 种语言。
从 v1.1.2 开始,locale 成为语言配置的统一入口,同时控制:
- SDK UI 界面文本的语言
- ASR 语音识别和 TTS 语音合成的语言
只需设置 locale,无需分别配置 lang。
核心特性
- ICU MessageFormat 标准:使用
@messageformat/core实现,支持复数、性别、日期等高级格式化 - Source-as-Key 模式:中文作为 key,代码可读性更高
- 编译缓存优化:自动缓存编译结果,避免重复编译
- 自定义语言包:支持覆盖内置翻译或添加新语言
- 动态切换:运行时切换语言,立即生效
- 统一语言配置:
locale同时控制 UI 和语音服务语言
快速开始
1. 初始化时设置语言(最简配置)
只需设置 locale,界面和语音服务都会使用相同语言:
import {createAaaSPilotKit} from '@bdky/aaas-pilot-kit';
const kit = createAaaSPilotKit({
// ... 其他配置
locale: 'en', // 界面和语音都用英文
});
2. 使用 Language 枚举(推荐)
Language 枚举可用于 locale,提供更好的代码提示:
import {createAaaSPilotKit, Language} from '@bdky/aaas-pilot-kit';
const kit = createAaaSPilotKit({
// ... 其他配置
locale: Language.ENGLISH, // 等同于 'en'
});
3. 界面与语音使用不同语言
当需要界面和语音服务使用不同语言时,可通过 asr.config.lang 覆盖:
const kit = createAaaSPilotKit({
locale: 'zh', // 界面用中文
asr: {
provider: 'baidu',
config: {
lang: 'en' // 语音服务用英文
}
}
});
4. 运行时切换语言
// 切换到日文
kit.setLocale('ja');
// 获取当前语言
const currentLocale = kit.getLocale(); // 'ja'
// 支持链式调用
kit.setLocale('ko').start();
支持的语言
界面语言(i18n 内置)
| 语言代码 | 语言名称 | 状态 |
|---|---|---|
zh | 中文(简体) | 内置(默认) |
en | English | 内置 |
ja | 日本語 | 内置 |
ko | 한국어 | 内置 |
| 自定义 | 任意语言 | 通过 messages 参数 |
语音服务语言(ASR/TTS)
| 代码 | 语言 | Language 枚举 |
|---|---|---|
zh | 中文(普通话) | Language.CHINESE |
en | 英语 | Language.ENGLISH |
ja | 日语 | Language.JAPANESE |
ko | 韩语 | Language.KOREAN |
es | 西班牙语 | Language.SPANISH |
ru | 俄语 | Language.RUSSIAN |
vi | 越南语 | Language.VIETNAMESE |
de | 德语 | Language.GERMAN |
id | 印尼语 | Language.INDONESIAN |
th | 泰语 | Language.THAI |
API 参考
初始化配置
locale
类型: 'zh' | 'en' | 'ja' | 'ko' | string
默认值: 'zh'
描述: 设置 SDK 界面语言
createAaaSPilotKit({
locale: 'en', // 使用内置英文
});
messages
类型: Partial<I18nMessages>
描述: 自定义/覆盖翻译消息
查找优先级:
- 自定义
messages - 当前
locale对应的内置语言包 - 中文回退(
zh) - key 本身(中文原文)
createAaaSPilotKit({
locale: 'en',
messages: {
// 覆盖内置翻译
'网络连接错误': 'Custom network error message',
},
});
运行时 API
setLocale(locale: string)
描述: 动态切换 SDK 界面语言
返回值: IAaaSPilotKitController(支持链式调用)
生效时机: 立即生效,影响所有使用 i18n 的组件
// 切换到英文
kit.setLocale('en');
// 链式调用
kit.setLocale('ja').start();
getLocale()
描述: 获取当前 SDK 界面语言
返回值: string(当前语言代码)
const currentLocale = kit.getLocale(); // 'zh'
使用场景
场景 1: 根据浏览器语言自动适配
// 获取浏览器语言
const browserLang = navigator.language.split('-')[0]; // 'en', 'zh', 'ja', 'ko'
const kit = createAaaSPilotKit({
locale: ['zh', 'en', 'ja', 'ko'].includes(browserLang) ? browserLang : 'zh',
});
场景 2: 用户手动切换语言
// React 示例
function LanguageSwitcher() {
const kit = useAaaSPilotKit();
const handleLanguageChange = (lang: string) => {
kit.setLocale(lang);
};
return (
<select onChange={(e) => handleLanguageChange(e.target.value)}>
<option value="zh">中文</option>
<option value="en">English</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
</select>
);
}
场景 3: 添加自定义语言(法语示例)
import {zhMessages} from '@bdky/aaas-pilot-kit';
// 基于中文语言包翻译所有 key
const frMessages = {
'发生未知错误': 'Une erreur inconnue s\'est produite',
'网络连接错误': 'Erreur de connexion réseau',
'请求超时': 'Délai d\'attente de la requête',
// ... 翻译所有 key
};
const kit = createAaaSPilotKit({
locale: 'fr',
messages: frMessages,
});
场景 4: 覆盖部分内置翻译
const kit = createAaaSPilotKit({
locale: 'en',
messages: {
// 只覆盖需要自定义的消息
'ASR权限被拒绝': 'Microphone access denied. Please enable it in browser settings.',
},
});
导出的语言包
SDK 导出了所有内置语言包,供外部翻译参考:
import {
zhMessages, // 中文语言包
enMessages, // 英文语言包
jaMessages, // 日文语言包
koMessages, // 韩文语言包
} from '@bdky/aaas-pilot-kit';
// 查看所有可翻译的 key
console.log(Object.keys(zhMessages));
高级特性
ICU MessageFormat 插值
SDK 支持 ICU MessageFormat 标准的参数插值:
// 内置示例(中文)
'请求超时,已重试 {count} 次'
// 英文翻译
'Request timeout, retried {count} times'
// SDK 内部使用
i18n.t('请求超时,已重试 {count} 次', {count: 3});
// 输出: "请求超时,已重试 3 次"
编译缓存
SDK 自动缓存编译结果,避免重复编译:
- 缓存 key:
${locale}:${messageKey} - 切换语言时自动清空缓存
- 设置自定义消息时自动清空缓存
注意事项
-
t() 方法不对外暴露
t()方法仅供 SDK 内部使用,外部无法直接调用。SDK 会自动根据当前locale翻译所有内部消息。 -
语言切换立即生效 调用
setLocale()后,所有使用 i18n 的组件会立即使用新语言。 -
自定义语言包需完整翻译 如果添加新语言,建议基于
zhMessages翻译所有 key,否则未翻译的消息会回退到中文。 -
ICU 格式错误会回退 如果消息模板包含无效的 ICU 格式,SDK 会自动回退到简单插值(
{key}替换)。
从 v1.1.2 开始,locale 成为统一入口,同时控制界面语言和语音服务语言。
如需界面和语音使用不同语言,可通过 asr.config.lang 覆盖语音服务语言。
迁移指南
从 lang 迁移到 locale
// ❌ 旧写法(已废弃)
const kit = createAaaSPilotKit({
lang: 'en',
});
// ✅ 新写法
const kit = createAaaSPilotKit({
locale: 'en',
});
从 lang 迁移到 asr.config.lang
如果只需要设置语音服务语言而不影响界面:
// ❌ 旧写法(已废弃)
const kit = createAaaSPilotKit({
lang: 'en',
});
// ✅ 新写法(仅语音服务)
const kit = createAaaSPilotKit({
locale: 'zh', // 界面保持中文
asr: {
provider: 'baidu',
config: { lang: 'en' }
}
});
优先级规则
语音服务语言的最终取值遵循以下优先级:
asr.config.lang(如果配置了)- 从
locale自动推导 - 默认
'zh'
asr.config.lang > locale → 自动推导 > 默认 'zh'
边界情况
使用非内置 i18n 语言
当 locale 设置为语音服务支持但 i18n 不内置的语言时:
const kit = createAaaSPilotKit({
locale: Language.SPANISH, // 'es'
});
行为:
- 界面语言:fallback 到中文(i18n 不内置西班牙语)
- 语音服务:正常使用西班牙语
解决方案:通过 messages 参数提供自定义语言包:
const kit = createAaaSPilotKit({
locale: 'es',
messages: {
'发生未知错误': 'Error desconocido',
'网络连接错误': 'Error de conexión de red',
// ... 其他翻译
}
});
完整示例
import {createAaaSPilotKit, zhMessages} from '@bdky/aaas-pilot-kit';
// 1. 基于浏览器语言初始化
const browserLang = navigator.language.split('-')[0];
const supportedLangs = ['zh', 'en', 'ja', 'ko'];
const initialLocale = supportedLangs.includes(browserLang) ? browserLang : 'zh';
// 2. 创建 Kit 实例
const kit = createAaaSPilotKit({
// ... 其他配置
locale: initialLocale,
messages: {
// 可选:覆盖部分翻译
'ASR权限被拒绝': 'Custom permission denied message',
},
});
// 3. 运行时切换语言
document.getElementById('lang-zh')?.addEventListener('click', () => {
kit.setLocale('zh');
});
document.getElementById('lang-en')?.addEventListener('click', () => {
kit.setLocale('en');
});
// 4. 获取当前语言
console.log('Current locale:', kit.getLocale());