
ReactRenderer 国际化实战lowcode-engine 中 locale 与 messages 的完整工作原理【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine在 lowcode-engine 的运行时渲染侧多语言支持完全由alilc/lowcode-react-renderer的ReactRenderer组件承接通过locale与messages两个属性传入语言标识和语料包即可在 Schema 中用this.i18n(key)表达式取到对应语言的文案。本文基于仓库中的官方 Demoi18n.md完整讲解国际化渲染的接入方式并深入 renderer-core 源码说明i18n、getLocale、setLocale三个 API 的注入时机、语料查找规则与缺失降级行为帮助你在搭建产物运行时正确落地多语言。一、国际化渲染的完整接入示例以下是 i18n.md 中的官方 Demo 代码仓库中可直接查看完整可运行的上下文文件import React, { PureComponent } from react; import ReactDOM from react-dom; import ReactRenderer from alilc/lowcode-react-renderer; import schema from ./schemas/i18n; import components from ./config/components/index; import utils from ./config/utils; import constants from ./config/constants; class Demo extends PureComponent { static displayName renderer-demo; render() { return ( div classNamedemo ReactRenderer key{schema.fileName} schema{schema} components{components} appHelper{{ utils, constants }} localezh-CN messages{{ hello: 你好, china: 中国 }} / /div ); } } ReactDOM.render(( Demo / ), mountNode);与国际化直接相关的配置有三处属性取值作用localezh-CN指定当前渲染使用的语言标识决定从语料包中取哪一份文案messages对象多语言语料包this.i18n(key)即在此对象中按 key 查值keyschema.fileName绑定在ReactRenderer上切换不同页面 Schema 时通过变更 key 强制重建渲染实例同时componentsdemo/config/components、utils、constantsdemo/config分别提供组件物料与全局上下文其中utils/constants可通过表达式中的this.utils/this.constants访问。二、对应的 Schemai18n 表达式的书写方式该 Demo 加载的页面 Schema 为 schemas/i18n.js其核心结构是export default { componentName: Page, fileName: i18n, props: {}, children: [{ componentName: Div, props: {}, children: [{ componentName: Text, props: { text: {{this.i18n(hello)}}, }, }, { componentName: Text, props: { text: {{this.i18n(china)}}, }, }], }], };可以看到国际化文案在 Schema 中以 JSExpression 形式书写text属性值为字符串{{this.i18n(hello)}}。渲染时引擎在解析组件 props 前会执行表达式解析this指向渲染器实例i18n调用被替换为实际文案字符串后再传入Text组件。因此 Schema 中不写死任何具体语言文案只保存语料 key语言切换的灵活度由运行时的localemessages决定。三、源码剖析i18n API 是如何注入到 this 上的ReactRenderer由 src/index.ts 通过rendererFactory()派生真正的渲染逻辑在 packages/renderer-core/src/renderer/base.tsx 的BaseRenderer中。在构造函数的初始化链__beforeInit → __init → __afterInit里__init会调用__initI18nAPIs()把三个国际化方法挂载到渲染器实例即表达式里的this上/** * init i18n apis * PRIVATE */ __initI18nAPIs () { this.i18n (key: string, values {}) { const { locale, messages } this.props; return getI18n(key, values, locale, messages); }; this.getLocale () this.props.locale; this.setLocale (loc: string) { const setLocaleFn this.appHelper?.utils?.i18n?.setLocale; if (!setLocaleFn || typeof setLocaleFn ! function) { logger.warn(initI18nAPIs Failed, i18n only works when appHelper.utils.i18n.setLocale() exists); return undefined; } return setLocaleFn(loc); }; };见 base.tsx 的__initI18nAPIs从源码可以明确三个 API 的行为边界this.i18n(key, values)把locale、messages取自当前渲染器 props委托给getI18n完成查表与格式化。第二个参数values用于文案模板中的变量占位如{name}, 你好配合{ name: x }。this.getLocale()只读返回当前localeprop供表达式或组件内做语言判断。this.setLocale(loc)本身不直接修改渲染器状态而是转发到appHelper.utils.i18n.setLocale。也就是说运行时动态切换语言需要宿主应用在appHelper.utils.i18n中提供setLocale实现通常是更新外部语料包并重新渲染否则该方法会打印警告并返回undefined。四、语料查找与格式化getI18n 的实现细节getI18n位于 packages/renderer-core/src/utils/common.ts/** * 用于处理国际化字符串 * param {*} key 语料标识 * param {*} values 字符串模版变量 * param {*} locale 国际化标识例如 zh-CN、en-US * param {*} messages 国际化语言包 */ export function getI18n(key: string, values {}, locale zh-CN, messages: Recordstring, any {}) { if (!messages || !messages[locale] || !messages[locale][key]) { return ; } const formater new IntlMessageFormat(messages[locale][key], locale); return formater.format(values); }三个关键点两级结构源码按messages[locale][key]查表即语料包需要按 locale 分层组织例如{ zh-CN: { hello: 你好 }, en-US: { hello: Hello } }。Demo 中传入的是扁平对象从当前实现看属于历史演示形态工程化接入时建议以源码实现的两级结构为准组织语料否则查表会落空。兜底语言locale参数默认值为zh-CN。当ReactRenderer未传locale时__initI18nAPIs会把undefined传入getI18n触发默认值即未配置 locale 时默认按中文渲染。缺失即空串locale 或 key 任一层缺失时返回空字符串而非 key 本身不会把语料标识直接暴露到界面上。模板变量查到的文案通过intl-messageformat的IntlMessageFormat按当前 locale 格式化支持 ICU 风格的参数插值这就是this.i18n(key, values)第二参数的底层支撑。另外在类型定义 packages/renderer-core/src/types/index.ts 中IRendererProps对这两个属性有明确注释locale为语言标识messages为多语言语料其配置规范指向《低代码搭建组件描述协议》中国际化多语言支持一节。五、Schema 中的 i18n 数据结构与降级解析除了{{this.i18n(key)}}表达式写法低代码协议还定义了结构化的 i18n 数据{ type: i18n, key, ... }。引擎对这类数据有多条解析路径类型判定packages/utils/src/check-types/is-i18n-data.ts 通过obj.type i18n判定是否为 i18n 数据。降级解释common.ts 的parseI18n会把 i18n 结构降级为一个 JSExpression 调用——this.i18n(key)再走统一的表达式解析通道。这意味着结构化 i18n 数据与手写表达式在运行时收敛到同一条查表链路。属性与子节点解析parseData在递归解析 Schema 数据时遇到 i18n 结构会调用parseI18nBaseRenderer.__parseProps中对 props 里的 i18n 数据也有专门的兼容处理handleI18nData取innerProps.use或当前getLocale()对应分支默认zh-CN用于兼容老平台设计态产出的 i18n 数据。六、locale 在渲染入口的传递链路locale并不只是喂给i18n查表它还会影响组件库层面的配置。在渲染入口 packages/renderer-core/src/renderer/renderer.tsx 中Renderer的render方法用ConfigProvider包裹真正的渲染组件createElement(ConfigProvider, { device: this.props.device, locale: this.props.locale, }, createElement(Comp, { __appHelper: appHelper, __components: allComponents, __schema: schema, __designMode: designMode, ...this.props, // locale、messages 等一并透传 }));对 React 运行时而言ReactRenderer通过adapter.setConfigProvider(ConfigProvider)见 src/index.ts把alifd/next的ConfigProvider注册为配置提供者。因此传入的locale一方面驱动ConfigProvider让底层 Fusion 组件Dialog、Form 等内置文案跟随语言切换另一方面经...this.props透传到BaseRenderer成为this.i18n的查表依据——业务文案与组件库文案在同一入口完成联动。七、落地要点小结表达式书写Schema 文案统一使用{{this.i18n(key)}}或在 Schema 中放置{ type: i18n, key }结构两者运行时等价。语料组织按messages[locale][key]两级结构组织语料包未传locale时默认走zh-CNkey 缺失时返回空串。变量文案带参数的文案用this.i18n(key, values)底层由IntlMessageFormat按 locale 格式化。语言切换运行时切换语言需通过appHelper.utils.i18n.setLocale由宿主承接并配合更新locale/messages后重新渲染ReactRenderer上的key可用来强制重建实例。组件库联动locale经ConfigProvider下传内置组件文案随语言自动切换无需额外处理。参考文件国际化 Demopackages/react-renderer/demo/i18n.md、packages/react-renderer/demo/schemas/i18n.js渲染器入口packages/react-renderer/src/index.tsi18n API 注入与属性解析packages/renderer-core/src/renderer/base.tsx查表与格式化实现packages/renderer-core/src/utils/common.tsprops 类型定义packages/renderer-core/src/types/index.tsi18n 类型判定packages/utils/src/check-types/is-i18n-data.ts【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考