国际化支持
微应用模板内置了轻量级国际化(i18n)方案,支持多语言翻译、占位符替换、配置引用等。国际化功能已集成在 @sun-panel/micro-app SDK 中,组件基类(SunPanelWidgetElement / SunPanelPageElement)会在 onConnected 生命周期中自动初始化 i18n,开发者无需手动调用 initI18n。
需要满足条件:
- Sun-Panel 主版本升级到
v2.0.0-dev-14+ - 微应用模板升级到
v1.1.0+ - SDK模块 (@sun-panel/micro-app) 升级到
v1.0.18+ app.config.js下配置参数{appJsonVersion: '1.1'},1.1及以上
目录结构
your-app/
├── locales/ # 国际化语言文件(唯一翻译源)
│ ├── zh-CN.js # 中文语言包
│ └── en-US.js # 英文语言包
├── config/
│ └── app.config.js # 应用配置(声明语言文件列表)
└── ...快速开始
1. 配置应用信息
在 config/app.config.js 中,使用 $t:KEY 引用翻译键,并在 locales 对象中声明语言文件映射:
export default {
// 配置文件格式版本
// 1.1: appInfo 使用 $t: 引用,翻译文件在 locales/ 目录
appJsonVersion: '1.1',
// 应用信息(使用 $t: 变量引用翻译)
appInfo: {
appName: '$t:APP_NAME',
description: '$t:APP_DESCRIPTION',
networkDescription: '$t:NETWORK_DESCRIPTION',
},
// 语言文件映射(格式:{ 语言代码: 文件名 })
// 文件名相对于 locales/ 目录,支持多语言代码指向同一文件
locales: {
'zh-CN': 'zh-CN.json',
'en-US': 'en-US.json',
// 'zh-TW': 'zh-CN.json', // 示例:繁体中文可指向简体中文文件
},
// 默认语言(当主应用语言在微应用中不存在时,回退到此语言)
// 如果不设置,默认为 'en-US'
defaultLocale: 'en-US',
// ...其他配置
};提示
config/* 中的值使用 $t:翻译键名 格式引用。构建时,系统会自动解析这些引用并替换为对应语言的翻译文本。
2. 创建语言包文件
在 locales/ 目录下创建对应的语言包文件。文件名必须与 locales 对象中的值一致(去掉 .json 后缀,使用 .js 源文件):
// locales/zh-CN.js
export default {
APP_NAME: '你好世界',
APP_DESCRIPTION: 'Sun-Panel 演示微应用',
NETWORK_DESCRIPTION: '无需链接任何三方网站',
WIDGET_HELLO_NAME: '你好世界小部件',
WIDGET_HELLO_DESCRIPTION: '这是一个演示小部件',
GREETING: '你好, {name}!',
// ...更多翻译
};// locales/en-US.js
export default {
APP_NAME: 'Hello World',
APP_DESCRIPTION: 'Sun-Panel Demo Micro App',
NETWORK_DESCRIPTION: 'For demonstration purposes',
WIDGET_HELLO_NAME: 'Hello World Widget',
WIDGET_HELLO_DESCRIPTION: 'A demo widget',
GREETING: 'Hello, {name}!',
// ...更多翻译
};3. 在组件中使用
继承组件基类后,i18n 会在 onConnected 生命周期中自动初始化,开发者可以直接通过 this.t() 使用翻译:
// 在 widgetConfig.js 中
import { SunPanelWidgetElement } from '@sun-panel/micro-app';
class MyWidget extends SunPanelWidgetElement {
render() {
const config = {
name: this.t('WIDGET_HELLO_NAME'),
description: this.t('WIDGET_HELLO_DESCRIPTION'),
};
return config;
}
}无需手动调用 initI18n
组件基类 SunPanelWidgetElement / SunPanelPageElement 会在 onConnected 生命周期中自动完成 i18n 初始化,无需手动导入和调用 initI18n。直接使用 this.t() 即可。
在微应用的组件中使用
this.t(key, args?) - 翻译函数(推荐)
组件基类提供的实例方法,根据当前语言环境翻译指定的键,支持命名占位符替换。
参数:
key(string) - 翻译键名args(Record<string, any>) - 可选的命名占位符替换参数对象
返回值: 翻译后的字符串(未找到时返回键名本身)
示例:
// 组件内部使用
this.t('APP_NAME'); // => '你好世界'
this.t('GREETING', { name: '张三' }); // => '你好, 张三!'
this.t('WELCOME_USER_ROLE', { name: '李四', role: '管理员' }); // => '欢迎 李四,您是 管理员't(key, args?) - 翻译函数(独立导出)
根据当前语言环境翻译指定的键,支持命名占位符替换。
参数:
key(string) - 翻译键名args(Record<string, any>) - 可选的命名占位符替换参数对象
返回值: 翻译后的字符串(未找到时返回键名本身)
示例:
import { t } from '@sun-panel/micro-app';
// 基本翻译
t('APP_NAME'); // => '你好世界'
t('SETTINGS'); // => '设置'
// 带命名占位符的翻译
t('GREETING', { name: '张三' }); // => '你好, 张三!'
t('WELCOME_USER_ROLE', { name: '李四', role: '管理员' }); // => '欢迎 李四,您是 管理员'setLocale(locale) - 单独切换语言
此方案仅适用于,脱离主应用语言,单独手动动态切换当前语言环境,并重新初始化解析器。
参数:
locale(string) - 目标语言标识符,如'en-US'
示例:
import { setLocale } from '@sun-panel/micro-app';
// 组件代码
class WidgetConfig extends SunPanelPageElement {
// ...
// 语言切换处理
async handleLanguageChange(locale) {
try {
await setLocale(locale);
this.requestUpdate(); // 更新页面,重要!!!
console.log(`Language changed to: ${locale}`);
} catch (error) {
console.error('Failed to change language:', error);
}
}
// ...
}getLocale() - 获取当前语言
返回当前语言环境的标识符字符串。
返回值: string - 当前语言标识符
占位符
占位符使用 {name} 格式,name 为参数对象中的键名:
// locales/zh-CN.js
export default {
GREETING: '你好, {name}!',
WELCOME_USER_ROLE: '欢迎 {name},您是 {role}',
};
// locales/en-US.js
export default {
GREETING: 'Hello, {name}!',
WELCOME_USER_ROLE: 'Welcome {name}, you are {role}',
};t('GREETING', { name: '张三' }); // => '你好, 张三!'
t('WELCOME_USER_ROLE', { name: '李四', role: '管理员' }); // => '欢迎 李四,您是 管理员'如果占位符对应的参数缺失,占位符将原样保留(如 {name})。
语言回退机制
当翻译键在当前语言中未找到时,系统会按以下顺序回退查找:
- 完整语言代码 - 如
zh-CN - 语言短码 - 去掉地区后缀,如
zh - 默认语言 - 由
app.config.js中的defaultLocale字段指定,默认为'en-US'
// 假设当前语言为 zh-TW,但只有 zh-CN 和 en-US 的翻译
// 查找顺序:zh-TW → zh → en-US(假设 defaultLocale 为 'en-US')
t('SETTINGS'); // 如果 zh-TW 和 zh 都没有,会从 en-US 获取回退链示例
| 当前语言 (locale) | defaultLocale | 回退链 | 说明 |
|---|---|---|---|
zh-CN | en-US | ['zh-CN', 'zh', 'en-US'] | 中文回退到英文 |
en-US | en-US | ['en-US', 'en'] | 英文自身回退,defaultLocale 不重复 |
zh-CN | zh-CN | ['zh-CN', 'zh'] | defaultLocale 与当前语言相同时不重复 |
配置默认语言
在 config/app.config.js 中设置 defaultLocale 字段来指定默认回退语言:
export default {
// ...其他配置
// 语言文件映射
locales: {
'zh-CN': 'zh-CN.json',
'en-US': 'en-US.json',
},
// 默认语言(当主应用语言在微应用中不存在时,回退到此语言)
// 如果不设置,默认为 'en-US'
defaultLocale: 'en-US',
// ...其他配置
};工作原理
defaultLocale 的传递路径:
- 在
app.config.js中声明defaultLocale值 main.js在初始化 SDK 时读取该值并传入:initSDK({ defaultLocale: appConfig.defaultLocale || 'en-US' })- SDK 内部将其传递给 i18n 初始化:
initI18n({ locale, defaultLocale }) - 翻译查找时,
defaultLocale作为回退链的最终兜底,在所有回退之后
此外,SDK 在异步加载翻译文件时,会同时加载当前语言和 defaultLocale 的翻译文件,确保回退翻译数据可用。
注意事项:
defaultLocale的值必须是locales对象中已定义的语言代码之一- 建议设置为应用的主要支持语言(如中文应用可设为
'zh-CN') - 如果未设置,默认值为
'en-US'
如果所有回退语言中都没有该 key,则返回 key 本身(如 MISSING_KEY)。
构建流程
开发模式
开发模式下,locales/*.js 源文件通过 Vite 动态 import 直接加载:
locales/zh-CN.js → import() 动态加载 → i18n 实例生产构建
构建时,locales-generator.js 将 locales/*.js 编译为 JSON 格式,输出到 dist/locales/ 目录:
locales/zh-CN.js → locales-generator.js → dist/locales/zh-CN.json
locales/en-US.js → locales-generator.js → dist/locales/en-US.json生产模式下,i18n 通过 fetch 从 {staticPath}/locales/*.json 加载翻译文件。
最佳实践
1. 键名规范
翻译键不强制要求使用某种命名方法,按照个人习惯即可,暂时不支持嵌套翻译对象,请尽量不要在键名中使用 .。下面示例中使用的是 大写蛇形命名法(UPPER_SNAKE_CASE):
export default {
APP_NAME: '应用名称',
WIDGET_HELLO_NAME: '小部件名称',
SETTINGS_TITLE: '设置标题',
WIDGET_CONFIG_BUTTON_SAVE: '保存小部件',
};2. 文件命名
语言包文件名尽量要与 app.config.js 中 locales 对象的值对应:
| 语言 | 源文件 | locales 声明 |
|---|---|---|
| 简体中文 | locales/zh-CN.js | 'zh-CN': 'zh-CN.json' |
| 英语 | locales/en-US.js | 'en-US': 'en-US.json' |
| 繁体中文 | locales/zh-TW.js | 'zh-TW': 'zh-TW.json' |
3. 保持翻译同步
所有语言包文件应包含相同的键。新增翻译时,记得同步更新所有语言包文件。
4. 仅翻译文本
只翻译用户可见的文本内容,以下内容不要国际化:
- 配置键名(如
showLogo、textOption) - CSS 类名
- API 路径
- 数据节点标识
注意事项
- 翻译源位置:所有翻译应统一放在
locales/目录下,不要在src/目录下创建语言文件 - 不要直接修改构建产物:
dist/locales/是构建输出,修改会被覆盖 - 语言标识符格式:遵循 IETF BCP 47 标准(如
zh-CN、en-US)