拓冰建站拓冰建站
首页 / 资讯中心 / 正文

NocoBase RunJS JSX 语法指南:像写 React 组件一样编写 JS 区块与 JS 字段

NocoBase RunJS JSX 语法指南像写 React 组件一样编写 JS 区块与 JS 字段【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobaseRunJS 是 NocoBase 中用于JS 区块JSBlock、JS 字段JSField、JS 操作等场景的 JavaScript 执行环境代码运行在受限沙箱中并通过ctx上下文访问能力。本指南围绕 docs/docs/cn/runjs/jsx.md 展开讲解如何在 RunJS 中直接编写 JSX使用内置或外部 React/antd 组件渲染自定义 UI并通过源码印证其编译与加载原理。读完本文你将掌握 RunJS 的 JSX 编译规则、ctx.libs内置库用法、ctx.importAsync()外部依赖加载以及 Fragment、表达式、条件渲染、列表渲染等全套语法实践。RunJS 与 JSX先了解执行环境RunJS 是 NocoBase 面向无代码/低代码场景提供的脚本执行环境主要服务于 JS 区块、JS 字段、JS 操作三类能力。根据 docs/docs/cn/runjs/index.md它具备以下核心能力顶层异步支持 Top-levelawait无需包裹在 IIFE 中导入外部模块ESM 模块使用ctx.importAsync()推荐UMD/AMD 模块用ctx.requireAsync()容器内渲染通过ctx.render()将内容渲染到当前容器ctx.element全局变量window、document、navigator、ctx。在 JSX 场景下ctx.render()支持三种形式渲染 JSX 元素ctx.render(buttonButton/button)、渲染 DOM 节点document.createElement创建的节点、渲染 HTML 字符串。JSX 形式即本文主题——它让开发者在 RunJS 中像编写 React 组件一样组织 UI。编译说明JSX 如何在执行前被转换RunJS 对 JSX 的支持基于sucrase编译器JSX 会在代码执行前自动完成转换其规则如下使用 sucrase 转换 JSX 语法JSX 会被编译为ctx.libs.React.createElement和ctx.libs.React.Fragment调用无需import React直接书写 JSX 即可编译后自动引用ctx.libs.React当通过ctx.importAsync(reactx.x.x)加载外部 React 时JSX 会改为使用该外部实例的createElement。这意味着 RunJS 代码中不存在传统 React 项目的import React from react样板代码编译器已在底层把 JSX 与运行时绑定到ctx.libs.React。从源码结构看ctx.libs的统一命名空间由 packages/core/flow-engine/src/runjsLibs.ts 中setupRunJSLibs()建立其中通过ctx.defineProperty(libs, { value: libs })将 libs 挂载到上下文同时保留顶层别名如ctx.React/ctx.antd以兼容历史代码。使用内置 React 与组件RunJS 内置了 React 及常用 UI 库可直接通过ctx.libs使用无需importctx.libs.React— React 本体ctx.libs.ReactDOM— ReactDOM如需可配合createRoot使用ctx.libs.antd— Ant Design 组件ctx.libs.antdIcons— Ant Design 图标。一个最小示例const { Button } ctx.libs.antd; ctx.render(Button点击/Button);直接写 JSX 时无需解构 React只有在使用Hooks如useState、useEffect或Fragment.../时才需要从ctx.libs解构const { React } ctx.libs; const { useState } React; const Counter () { const [count, setCount] useState(0); return divCount: {count}/div; }; ctx.render(Counter /);从 runjsLibs.ts 的DEFAULT_RUNJS_LIBS可以看到除文档列出的 React、ReactDOM、antd、antdIcons 外内置库还包含dayjs、lodash、formulaformulajs/formulajs、mathmathjs且React、ReactDOM、antd、dayjs采用context级缓存随每个 ctx 实例解析而antdIcons、lodash、formula、math采用global级缓存全局复用一次解析结果。这些库均支持通过registerRunJSLib(name, loader, options)注册扩展见 runjsLibs.ts。注意内置的 React 与通过ctx.importAsync()导入的外部 React不能混用。若使用外部 UI 库React 也需从外部一并导入。使用外部 React 与组件通过ctx.importAsync()加载指定版本的 React 和 UI 库时JSX 会使用该 React 实例const React await ctx.importAsync(react19.2.4); const { Button } await ctx.importAsync(antd6.2.2?bundle); ctx.render(Button点击/Button);若 antd 依赖 react/react-dom可通过deps参数指定同一版本避免多 React 实例冲突const React await ctx.importAsync(react18.2.0); const { Button } await ctx.importAsync(antd5.29.3?bundledepsreact18.2.0,react-dom18.2.0); ctx.render(ButtonButton/Button);注意使用外部 React 时antd 等 UI 库也需通过ctx.importAsync()导入不要与ctx.libs.antd混用。这一“不可混用”约束在源码中有明确体现buildMixedReactHint()见 runjsLibs.ts专门检测外部 React 与内置 ReactDOM / antd 混用的情况并输出可操作的修复提示例如导入了外部 React 但仍在用内置 ReactDOM Root 时提示补充执行await ctx.importAsync(react-dom18.x/client)导入了外部 antd 但仍在用内置 React 时提示执行await ctx.importAsync(react18.x)导入了外部 React 但仍在用内置 antd 时提示切换为await ctx.importAsync(antd5.x)图标组件则导入ant-design/icons。当 Hooks 因多个 React 实例共存而抛出 Invalid hook call 或 dispatcher 为 null 的错误时isReactHooksDispatcherNullError()与buildReactDispatcherNullHint()见 runjsLibs.ts还会从堆栈中提取外部 React 版本号建议在读取ctx.libs.React/ 调用 Hooks 之前先用相同版本await ctx.importAsync(react版本)导入外部 React。这些提示由 RunJS 的 ErrorBoundary 捕获并输出见 runjsLibs.ts渲染错误会以带样式的 RunJS render error 面板呈现便于排查。JSX 语法要点RunJS 的 JSX 遵循 React 组件编写习惯但要注意其与模板语法的差异组件与 propsButton typeprimary文字/Button组件名首字母大写props 使用驼峰命名Fragment.../或React.Fragment.../React.Fragment使用 Fragment 时需解构const { React } ctx.libs表达式在 JSX 中用{表达式}插入变量或运算如{ctx.user.name}、{count 1}不要使用{{ }}模板语法那是模板引擎的写法不是 JSX条件渲染{flag span内容/span}或{flag ? A / : B /}列表渲染使用array.map()返回元素列表并为元素设置稳定key。完整示例——渲染一个列表const { React } ctx.libs; const items [a, b, c]; ctx.render( ul {items.map((item, i) ( li key{i}{item}/li ))} /ul );需要注意JSX 中的{表达式}与双大括号模板有本质区别前者是 JavaScript 表达式插值后者是 NocoBase 表单/变量模板template语法二者不能混用。编辑器侧的代码补全与诊断见 packages/core/client-v2/src/flow/components/code-editor/runjsCompletions.ts也会对ctx.libs成员、ctxAPI 给出提示帮助减少拼写错误。渲染与运行机制小结综合 docs/docs/cn/runjs/jsx.md 与源码实现RunJS 中 JSX 的完整链路可概括为脚本执行前sucrase 将 JSX 编译为ctx.libs.React.createElement/ctx.libs.React.Fragment首次访问ctx.libs.xxx时resolveRegisteredLibSync()按注册表懒加载对应库见 runjsLibs.tsctx.render(jsx)将元素渲染到当前容器ctx.element中若检测到外部 React / antd 混用会附加可读性极强的修复提示渲染异常由内置 ErrorBoundary 捕获展示 RunJS render error 面板方便在界面上直接定位问题。在实际使用中建议遵循优先使用ctx.libs内置 React/antd 满足常见 UI 需求需要特定版本或更丰富的依赖时统一改用ctx.importAsync()并从外部一并加载 React 与 UI 库同时用deps对齐 react/react-dom 版本避免多实例导致的 Hooks 崩溃。这样既能享受 JSX 的开发体验又能保持 RunJS 沙箱环境的稳定与可维护性。【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门