第 97 期 - Tango 低代码引擎沙箱能力剖析
摘要
本文主要讲述 Tango 低代码引擎的沙箱能力,阐述其采用 CodeSandbox 沙箱能力的原因、沙箱基本结构与工作流程、相关优化改造、如何接入 Tango 沙箱,还提及 Tango 的开源进展。
Tango 基本介绍
Tango 是用于构建低代码平台的框架,以源代码为中心,可执行和渲染前端视图,提供低代码可视化搭建能力,用户操作会转换为对源代码的修改,构建的工具或平台能实现源码进、源码出,与企业研发体系集成。
开源进展
Tango 设计器引擎已开源,可通过开源代码库(https://github.com/NetEase/tango)、文档地址(https://netease.github.io/tango-site/)、社区讨论组(https://github.com/NetEase/tango/discussions)了解进展。文档已更新,欢迎加入社区,有问题可通过 Github Issues 反馈。
为什么 Tango 需要沙箱
- 与传统方案对比:传统基于 DSL 的低代码方案需实现 DSL 语法与渲染器,Tango 是基于 AST 驱动的面向源码的低代码方案,写法更灵活,但面临支持源代码实时运行的挑战,且要考虑三方依赖加载与运行,所以需要独立沙箱。
- 调研其他方案:调研过 Sea.js 这类 AMD 加载方案,依赖固定,需预构建产物,不能灵活添加依赖;SystemJS 和 ViteSandbox 这类 ESM 方案,产物以 CommonJS 为主,缺少 ESM 产物,且 Tango 后续优化减少沙箱初始化时间,所以未采用。
- 采用 CodeSandbox 的原因:基于 CodeSandbox 的沙箱能力实现,优势在于提供完整、接近本地开发的运行时环境,支持直接拉取
npm
包并运行,借助Babel
转译新语法,模拟 CommonJS 运行环境,在浏览器直接运行源码,沙箱运行在iframe
内可隔离环境,避免污染全局变量。
Tango 沙箱的基本结构
- 沙箱前端组件:开箱即用,传入代码和配置即可渲染应用。
// 示例代码可能类似这样简单调用组件并传入参数
const sandboxComponent = new SandboxComponent({code: 'yourCode', config: 'yourConfig'});
sandboxComponent.render();
- 在线打包器:提供浏览器端构建能力,类似浏览器版本的
webpack
,最终是独立iframe
。 - 沙箱后端服务:预构建依赖资源,提供资源合并等服务,加速沙箱内部构建打包。
Tango 沙箱的工作流程
代码准备
平台引用沙箱组件,通过postMessage
传递代码给沙箱。
依赖初始化
- 轻量初始化:CodeSandbox 内部实现转译逻辑,初始化依赖时较轻松,只需获取
dependencies
里必要依赖,忽略devDependencies
和@types
开头的本地开发才用的依赖。 - 获取依赖的方案
- 默认远程在线打包方案:通过
dependency - packager
服务在线拉取依赖,解析URL
中的包名和版本号,在服务端执行yarn install
安装npm
包,解析依赖关系,返回被依赖文件。 - 兜底方案:从
unpkg/jsdelivr
等npm
包资源的CDN
获取依赖,当项目引入被排除资源时,沙箱前端请求此作为兜底,不过若缺失文件多,网络请求开销大,所以使用Service Worker
做资源缓存。
- 默认远程在线打包方案:通过
转译代码
- 转译流程开始:调用
compile()
方法转译,传入沙箱的参数除代码外,还有template
参数指定转译Preset
,Preset
类似webpack
配置文件。 - Manager 实例:
Preset
初始化后,初始化Manager
实例控制转译流程生命周期,按照前面方式初始化项目依赖,依赖变更时重新初始化Manager
实例。 - 模块转译:传入沙箱的代码传入
Manager
,实例化为TranspiledModule
,解析模块依赖关系,从入口模块开始,根据Preset
规则对每个模块递归调用Transpiler
转译,复杂Transpiler
如BabelTranspiler
会用Web Worker
队列提升效率。
执行代码
- 运行时环境模拟:沙箱运行时模拟
CommonJS
环境,如require
、module
、exports
、global
等方法和变量。 - 执行核心代码:核心代码将所有全局变量和方法整理,封装代码为立即执行函数,调用
eval()
执行并传入CommonJS
的方法和变量,若代码引用其他文件,require()
方法递归执行并返回产物。
沙箱的优化改造
Tango 上的应用是完整项目,对沙箱构建性能和加载速度要求高,具体优化细节可参考《云音乐低代码:基于 CodeSandbox 的沙箱性能优化》,修改后的代码在 GitHub 上可找到。
接入 Tango 沙箱
- 跨域兼容:沙箱在独立
iframe
且域名独立,与设计器跨域,将设计器平台与沙箱的document.domain
设为相同父域名,并添加Origin - Agent - Cluster:?0
的HTTP
响应头实现跨域通信。 - 封装 React 组件:封装
@music163/tango - sandbox
供设计器使用,分为IFrameProtocol
、PreviewManager
、Sandbox
三个部分。- IFrameProtocol:负责与沙箱通信,监听
message
事件接收沙箱消息获取生命周期,在iframe
内部调用postMessage()
向沙箱传递事件控制沙箱。 - PreviewManager:管理沙箱基本渲染,借助
IFrameProtocol
与沙箱通信,代码变化时向沙箱发送compile
消息触发构建和渲染。 - Sandbox:渲染沙箱的
React
组件,除挂载iframe
外,还有沙箱配置、注册事件监听函数、消息传递、路由管理等功能,props
变化时更新沙箱代码和iframe
路由等。
- IFrameProtocol:负责与沙箱通信,监听
总结
简单介绍 Tango 低代码引擎沙箱能力,分析 CodeSandbox 基本结构和工作流程,通过 CodeSandbox,Tango 实现可视化预览与搭建能力,提供便捷开发体验。Tango 已完成部分开源并发布RC
版本,今年将持续推进开源并优化文档,未来还会开源更多内部实践。
Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有