FlowGram.AI - Demo Free Layout
自由布局最佳实践 demo
安装
npx @flowgram.ai/create-app@latest free-layout
项目概览
核心技术栈
- 前端框架: React 18 + TypeScript
- 构建工具: Rsbuild (基于 Rspack 的现代构建工具)
- 样式方案: Less + Styled Components + CSS Variables
- UI 组件库: Semi Design (@douyinfe/semi-ui)
- 状态管理: 基于 Flowgram 自研的编辑器框架
- 依赖注入: Inversify
核心依赖包
- @flowgram.ai/free-layout-editor: 自由布局编辑器核心依赖
- @flowgram.ai/free-snap-plugin: 自动对齐及辅助线插件
- @flowgram.ai/free-lines-plugin: 连线渲染插件
- @flowgram.ai/free-node-panel-plugin: 节点添加面板渲染插件
- @flowgram.ai/minimap-plugin: 缩略图插件
- @flowgram.ai/free-container-plugin: 子画布插件
- @flowgram.ai/free-group-plugin: 分组插件
- @flowgram.ai/form-materials: 表单物料
- @flowgram.ai/runtime-interface: 运行时接口
- @flowgram.ai/runtime-js: js 运行时模块
代码说明
目录结构
src/
├── app.tsx # 应用入口文件
├── editor.tsx # 编辑器主组件
├── initial-data.ts # 初始化数据配置
├── assets/ # 静态资源
├── components/ # 组件库
│ ├── index.ts
│ ├── add-node/ # 添加节点组件
│ ├── base-node/ # 基础节点组件
│ ├── comment/ # 注释组件
│ ├── group/ # 分组组件
│ ├── line-add-button/ # 连线添加按钮
│ ├── node-menu/ # 节点菜单
│ ├── node-panel/ # 节点添加面板
│ ├── selector-box-popover/ # 选择框弹窗
│ ├── sidebar/ # 侧边栏
│ ├── testrun/ # 测试运行组件
│ │ ├── hooks/ # 测试运行钩子
│ │ ├── node-status-bar/ # 节点状态栏
│ │ ├── testrun-button/ # 测试运行按钮
│ │ ├── testrun-form/ # 测试运行表单
│ │ ├── testrun-json-input/ # JSON输入组件
│ │ └── testrun-panel/ # 测试运行面板
│ └── tools/ # 工具组件
├── context/ # React Context
│ ├── node-render-context.ts # 当前渲染节点 Context
│ ├── sidebar-context # 侧边栏 Context
├── form-components/ # 表单组件库
│ ├── form-content/ # 表单内容
│ ├── form-header/ # 表单头部
│ ├── form-inputs/ # 表单输入
│ └── form-item/ # 表单项
│ └── feedback.tsx # 表单校验错误渲染
├── hooks/
│ ├── index.ts
│ ├── use-editor-props.tsx # 编辑器属性钩子
│ ├── use-is-sidebar.ts # 侧边栏状态钩子
│ ├── use-node-render-context.ts # 节点渲染上下文钩子
│ └── use-port-click.ts # 端口点击钩子
├── nodes/ # 节点定义
│ ├── index.ts
│ ├── constants.ts # 节点常量定义
│ ├── default-form-meta.ts # 默认表单元数据
│ ├── block-end/ # 块结束节点
│ ├── block-start/ # 块开始节点
│ ├── break/ # 中断节点
│ ├── code/ # 代码节点
│ ├── comment/ # 注释节点
│ ├── condition/ # 条件节点
│ ├── continue/ # 继续节点
│ ├── end/ # 结束节点
│ ├── group/ # 分组节点
│ ├── http/ # HTTP节点
│ ├── llm/ # LLM节点
│ ├── loop/ # 循环节点
│ ├── start/ # 开始节点
│ └── variable/ # 变量节点
├── plugins/ # 插件系统
│ ├── index.ts
│ ├── context-menu-plugin/ # 右键菜单插件
│ ├── runtime-plugin/ # 运行时插件
│ │ ├── client/ # 客户端
│ │ │ ├── browser-client/ # 浏览器客户端
│ │ │ └── server-client/ # 服务器客户端
│ │ └── runtime-service/ # 运行时服务
│ └── variable-panel-plugin/ # 变量面板插件
│ └── components/ # 变量面板组件
├── services/ # 服务层
│ ├── index.ts
│ └── custom-service.ts # 自定义服务
├── shortcuts/ # 快捷键系统
│ ├── index.ts
│ ├── constants.ts # 快捷键常量
│ ├── shortcuts.ts # 快捷键定义
│ ├── type.ts # 类型定义
│ ├── collapse/ # 折叠快捷键
│ ├── copy/ # 复制快捷键
│ ├── delete/ # 删除快捷键
│ ├── expand/ # 展开快捷键
│ ├── paste/ # 粘贴快捷键
│ ├── select-all/ # 全选快捷键
│ ├── zoom-in/ # 放大快捷键
│ └── zoom-out/ # 缩小快捷键
├── styles/ # 样式文件
├── typings/ # 类型定义
│ ├── index.ts
│ ├── json-schema.ts # JSON Schema类型
│ └── node.ts # 节点类型定义
└── utils/ # 工具函数
├── index.ts
└── on-drag-line-end.ts # 拖拽连线结束处理
关键目录功能说明
1. /components - 组件库
- base-node: 所有节点的基础渲染组件
- testrun: 完整的测试运行功能模块,包含状态栏、表单、面板等
- sidebar: 侧边栏组件,提供工具和属性面板
- node-panel: 节点添加面板,支持拖拽添加新节点
2. /nodes - 节点系统
每个节点类型都有独立的目录,包含:
- 节点注册信息 (
index.ts)
- 表单元数据定义 (
form-meta.ts)
- 节点特定的组件和逻辑
3. /plugins - 插件系统
- runtime-plugin: 支持浏览器和服务器两种运行模式
- context-menu-plugin: 右键菜单功能
- variable-panel-plugin: 变量管理面板
4. /shortcuts - 快捷键系统
完整的快捷键支持,包括:
- 基础操作:复制、粘贴、删除、全选
- 视图操作:放大、缩小、折叠、展开
- 每个快捷键都有独立的实现模块
应用架构设计
核心设计模式
1. 插件化架构 (Plugin Architecture)
应用采用高度模块化的插件系统,每个功能都作为独立插件存在:
plugins: () => [
createFreeLinesPlugin({ renderInsideLine: LineAddButton }),
createMinimapPlugin({ }),
createFreeSnapPlugin({ }),
createFreeNodePanelPlugin({ renderer: NodePanel }),
createContainerNodePlugin({}),
createFreeGroupPlugin({ groupNodeRender: GroupNodeRender }),
createContextMenuPlugin({}),
createRuntimePlugin({ mode: 'browser' }),
createVariablePanelPlugin({})
]
2. 节点注册系统 (Node Registry Pattern)
通过注册表模式管理不同类型的工作流节点:
export const nodeRegistries: FlowNodeRegistry[] = [
ConditionNodeRegistry,
StartNodeRegistry,
EndNodeRegistry,
LLMNodeRegistry,
LoopNodeRegistry,
CommentNodeRegistry,
HTTPNodeRegistry,
CodeNodeRegistry,
];
3. 依赖注入模式 (Dependency Injection)
使用 Inversify 框架实现服务的依赖注入:
onBind: ({ bind }) => {
bind(CustomService).toSelf().inSingletonScope();
}
核心功能分析
1. 编辑器配置系统
useEditorProps 是整个编辑器的配置中心,包含:
export function useEditorProps(
initialData: FlowDocumentJSON,
nodeRegistries: FlowNodeRegistry[]
): FreeLayoutProps {
return useMemo<FreeLayoutProps>(() => ({
background: true,
readonly: false,
initialData,
nodeRegistries,
playground: { preventGlobalGesture: true },
nodeEngine: { enable: true },
variableEngine: { enable: true },
history: { enable: true, enableChangeNode: true },
canAddLine: (ctx, fromPort, toPort) => { },
canDeleteLine: (ctx, line) => { },
canDeleteNode: (ctx, node) => { },
canDropToNode: (ctx, params) => { },
plugins: () => [],
onContentChange: debounce((ctx, event) => { }, 1000),
onInit: (ctx) => { },
onAllLayersRendered: (ctx) => { }
}), []);
}
2. 节点类型系统
应用支持多种工作流节点类型:
export enum WorkflowNodeType {
Start = 'start',
End = 'end',
LLM = 'llm',
HTTP = 'http',
Code = 'code',
Variable = 'variable',
Condition = 'condition',
Loop = 'loop',
BlockStart = 'block-start',
BlockEnd = 'block-end',
Comment = 'comment',
Continue = 'continue',
Break = 'break',
}
每个节点都遵循统一的注册模式:
export const StartNodeRegistry: FlowNodeRegistry = {
type: WorkflowNodeType.Start,
meta: {
isStart: true,
deleteDisable: true,
copyDisable: true,
nodePanelVisible: false,
defaultPorts: [{ type: 'output' }],
size: { width: 360, height: 211 }
},
info: {
icon: iconStart,
description: '工作流的起始节点,用于设置启动工作流所需的信息。'
},
formMeta,
canAdd() { return false; }
};
3. 插件化架构
应用的功能通过插件系统实现模块化:
核心插件列表
- FreeLinesPlugin - 连线渲染和交互
- MinimapPlugin - 缩略图导航
- FreeSnapPlugin - 自动对齐和辅助线
- FreeNodePanelPlugin - 节点添加面板
- ContainerNodePlugin - 容器节点(如循环节点)
- FreeGroupPlugin - 节点分组功能
- ContextMenuPlugin - 右键菜单
- RuntimePlugin - 工作流运行时
- VariablePanelPlugin - 变量管理面板
4. 运行时系统
应用支持两种运行模式:
createRuntimePlugin({
mode: 'browser',
})
设计理念与架构优势
1. 高度模块化
- 插件化架构: 每个功能都是独立插件,易于扩展和维护
- 节点注册系统: 新节点类型可以轻松添加,无需修改核心代码
- 组件化设计: UI组件高度复用,职责清晰
2. 类型安全
- 完整的TypeScript支持: 从配置到运行时的全链路类型保护
- JSON Schema集成: 节点数据结构通过Schema验证
- 强类型的插件接口: 插件开发有明确的类型约束
3. 用户体验优化
- 实时预览: 支持工作流的实时运行和调试
- 丰富的交互: 拖拽、缩放、对齐、快捷键等完整的编辑体验
- 可视化反馈: 缩略图、状态指示、连线动画等视觉反馈
4. 扩展性设计
- 开放的插件系统: 第三方可以轻松开发自定义插件
- 灵活的节点系统: 支持自定义节点类型和表单配置
- 多运行时支持: 浏览器和服务器双模式运行
5. 性能优化
- 按需加载: 组件和插件支持按需加载
- 防抖处理: 自动保存等高频操作的性能优化
技术亮点
1. 自研编辑器框架
基于 @flowgram.ai/free-layout-editor 自研框架,提供:
- 自由布局的画布系统
- 完整的撤销/重做功能
- 节点和连线的生命周期管理
- 变量引擎和表达式系统
2. 先进的构建配置
使用 Rsbuild 作为构建工具:
export default defineConfig({
plugins: [pluginReact(), pluginLess()],
source: {
entry: { index: './src/app.tsx' },
decorators: { version: 'legacy' }
},
tools: {
rspack: {
ignoreWarnings: [/Critical dependency/]
}
}
});
3. 国际化支持
内置多语言支持:
i18n: {
locale: navigator.language,
languages: {
'zh-CN': {
'Never Remind': '不再提示',
'Hold {{key}} to drag node out': '按住 {{key}} 可以将节点拖出',
},
'en-US': {},
}
}