Skip to content

@lite-code/transcoder

低代码渲染视图引擎 —— 基于 sucrase 的运行时代码转译、变量解析与依赖注入。

概述

@lite-code/transcoder 是低代码平台的核心渲染引擎,负责将 JSON Schema 描述的页面模型转译为可执行的 React 组件。底层使用 sucrase 进行 TSX/JSX → ES5 的快速转译,并通过函数参数注入实现运行时模块系统。

为什么选 sucrase 而非 Babel

作为运行时转译引擎,包体积和执行速度是首要考量:

维度sucrase@babel/standalone
体积~30 KB (gzipped)~2.5 MB (minified)
速度极快,跳过完整 AST 构建,仅做类型移除 + JSX 转换完整语法分析 + 降级转换,较慢
产物兼容性不做语法降级,要求浏览器支持 const、箭头函数、class 等现代语法可降级至 ES5,兼容 IE11

权衡:低代码平台面向现代浏览器,不需要 ES5 降级;而页面每次渲染都会触发转译,体积小 + 速度快的收益远大于兼容老浏览器的需求。因此 sucrase 是更合适的选择。

核心能力

能力说明
代码转译基于 sucrase,支持 TypeScript + JSX + CJS 转换
依赖注入通过 new Function 参数列表注入 React、Shineout、状态管理等外部模块
变量绑定支持 bindVariables 声明式路径绑定,运行时覆盖 Schema 值
表达式标记<%...%> 标记机制,在 JSON 序列化中保留可执行表达式
响应式状态集成 @lite-code/reactive,提供 store / snapshot 驱动的状态管理
调试模式内置 Monaco Editor Playground,支持实时编辑预览

安装

bash
pnpm add @lite-code/transcoder

主要导出

组件

<Transcoder />

同步渲染组件,接收代码字符串并执行渲染。

tsx
import { Transcoder } from "@lite-code/transcoder";

<Transcoder
  code={esModuleString}
  stateCode={stateCode}
  lessCode={lessCode}
  require={{ axios, dayjs }}
/>;

<TranscoderAsync />

异步渲染组件,支持远程获取 Schema 后渲染。生产模式直接渲染,调试模式展示 Playground。

tsx
import { TranscoderAsync } from "@lite-code/transcoder";

<TranscoderAsync
  getSchema={async () => encodedJsonString}
  debug={false}
  require={{ axios }}
/>;

工具函数

getEs5Code(code, require?)

将 TSX/JSX/TS 代码字符串转译为可执行的 ES5 IIFE。

ts
import { getEs5Code } from "@lite-code/transcoder";

const es5 = getEs5Code(tsxCode, { dayjs: "dayjs", utils: "utils" });

excutecoder(code, require?)

转译并执行代码字符串,注入全局模块和自定义依赖,返回模块的 default 导出。

ts
import { excutecoder } from "@lite-code/transcoder";

const Component = excutecoder(code, { store, snap, axios });

getEsModuleString(state)

将 JSON Schema 对象转换为 export default {...} 格式的代码字符串,处理变量绑定和表达式解密。

ts
import { getEsModuleString } from "@lite-code/transcoder";

const code = getEsModuleString(schemaState);

getPureEsModuleString(state)

getEsModuleString,但会剔除内部字段(currentPageselectKeykeylessCodestateCode),用于生产输出。

encrypt(code) / decrypt(code)

表达式标记的编码/解码工具:

  • encrypt: 将 JS 表达式包裹为 "<% ... %>" 以便 JSON 序列化
  • decrypt: 将 "<% ... %>" 还原为原始 JS 表达式

cloneDeep(value)

深拷贝工具,自动跳过 React 元素(避免破坏 $$typeof 等内部属性)。

getBusinessFileCode(model)

根据模型生成业务代码文件映射(index.tsx + jsonSchema.json),用于代码导出场景。

架构设计

JSON Schema


getEsModuleString()        ← 变量绑定 + 表达式解密


getEs5Code()               ← sucrase 转译 (TSX → ES5 IIFE)


excutecoder()              ← new Function 执行 + 依赖注入


TranscoderRender           ← 组件映射 (Form / Crud)


React Component            ← 最终渲染输出

依赖注入机制

转译后的代码被包裹为 IIFE,外部模块作为函数参数注入:

js
((exports, React, Shineout, create, ...userRequire) => {
  // 转译后的 CJS 代码
  exports.default = Component;
})(exports, React, Shineout, create, ...userRequire);

这种方式避免了运行时 bundler 或 import map 的开销,同时保持模块隔离。

<%...%> 表达式标记

低代码 Schema 本质是 JSON,无法直接存储函数/表达式。通过 <%...%> 标记实现:

  1. 设计态:表达式以 <% onClick: () => {} %> 形式存储
  2. 序列化:encrypt 将其编码为安全字符串
  3. 执行态:decrypt 还原为原始 JS 表达式,嵌入代码字符串

支持的渲染类型

type组件
"Form"<ProForm />
"Crud"<ProCrud />

依赖

License

MIT