@aidps/canvas-flow
v1.2.0
Published
基于 X6 2.x 的 React 画布组件库
Maintainers
Readme
@aidps/canvas-flow
基于 X6 2.x 的 React 画布组件库,提供高度封装的画布组件、插件系统、菜单功能和函数封装能力。
特性
- 🌱 易于使用:提供更符合 React 习惯的组件化 API
- 🚀 统一状态管理:服务和画布数据统一管理
- 🧲 多画布支持:每个画布组件拥有独立的状态和实例
- 💯 开箱即用:内置大量画布组件和插件
- 🔒 只读模式:支持函数封装模式下的自动只读
- 📦 函数封装:支持将画布封装为可复用的函数
安装
npm install @aidps/canvas-flow
# 或
pnpm add @aidps/canvas-flow
# 或
yarn add @aidps/canvas-flow快速开始
基础用法
import React from 'react';
import { XFlow, XFlowGraph, SelectionPlugin, SnaplinePlugin } from '@aidps/canvas-flow';
const App = () => {
return (
<XFlow>
<XFlowGraph
config={{
grid: true,
panning: {
enabled: true,
},
}}
/>
<SelectionPlugin />
<SnaplinePlugin />
</XFlow>
);
};完整示例
import React from 'react';
import {
XFlow,
XFlowGraph,
SelectionPlugin,
SnaplinePlugin,
KeyboardPlugin,
ClipboardPlugin,
HistoryPlugin,
useXFlow,
} from '@aidps/canvas-flow';
const MyComponent = () => {
const { graph } = useXFlow();
const handleAddNode = () => {
if (graph) {
graph.addNode({
shape: 'rect',
x: 100,
y: 100,
width: 80,
height: 40,
label: 'Node',
});
}
};
return (
<div>
<button onClick={handleAddNode}>添加节点</button>
</div>
);
};
const App = () => {
return (
<div style={{ width: '100%', height: '600px' }}>
<XFlow
onReady={(graph) => {
console.log('画布已就绪', graph);
}}
>
<XFlowGraph
config={{
grid: true,
autoResize: true,
panning: {
enabled: true,
eventTypes: ['leftMouseDown'],
},
mousewheel: {
enabled: true,
modifiers: ['ctrl', 'meta'],
},
scaling: {
min: 0.8,
max: 3,
},
}}
/>
<SelectionPlugin rubberband showNodeSelectionBox />
<SnaplinePlugin sharp />
<KeyboardPlugin />
<ClipboardPlugin />
<HistoryPlugin />
<MyComponent />
</XFlow>
</div>
);
};API 文档
核心组件
XFlow
根组件,提供画布上下文。所有画布相关组件必须包裹在 XFlow 内部。
Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| children | React.ReactNode | - | 子组件 |
| onReady | (graph: Graph) => void | - | 画布就绪回调,返回 Graph 实例 |
| enableMenus | boolean | false | 是否启用菜单功能(节点和边的右键菜单) |
| showConfigPanel | boolean | true | 是否显示配置面板 |
| showOperatorMenu | boolean | true | 是否显示算子菜单 |
| showMinimap | boolean | true | 是否显示小地图 |
示例:
<XFlow
enableMenus={true}
onReady={(graph) => {
console.log('画布已就绪', graph);
}}
>
<XFlowGraph />
</XFlow>XFlowGraph
画布组件,封装 X6 Graph。自动支持函数封装模式的只读控制。
Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| config | Partial<GraphConfig> | - | 画布配置,参考 X6 GraphOptions |
| onReady | (graph: Graph) => void | - | 画布就绪回调 |
| onDestroy | () => void | - | 画布销毁回调 |
| className | string | - | 容器类名 |
| style | React.CSSProperties | - | 容器样式 |
| enableMenus | boolean | false | 是否启用菜单功能 |
配置项(config):
interface GraphConfig {
grid?: boolean | GridOptions; // 网格
autoResize?: boolean; // 自动调整大小
panning?: PanningOptions; // 平移配置
background?: BackgroundOptions; // 背景配置
mousewheel?: MouseWheelOptions; // 鼠标滚轮配置
scaling?: ScalingOptions; // 缩放配置
connecting?: ConnectingOptions; // 连线配置
translating?: TranslatingOptions; // 平移限制
interacting?: InteractingOptions; // 交互配置
}示例:
<XFlowGraph
config={{
grid: true,
autoResize: true,
panning: {
enabled: true,
eventTypes: ['leftMouseDown'],
},
mousewheel: {
enabled: true,
modifiers: ['ctrl', 'meta'],
},
}}
/>只读模式:
当使用 CanvasFunctionProvider 包裹并进入函数封装模式时,XFlowGraph 会自动进入只读模式:
- 禁止节点移动
- 禁止连线操作
- 禁止边的编辑
- 禁止端点移动
- 仍可点击节点查看配置
- 仍可平移和缩放画布
插件组件
SelectionPlugin
框选插件,支持框选多个节点。
Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| rubberband | boolean | false | 是否启用框选 |
| showNodeSelectionBox | boolean | false | 是否显示节点选择框 |
| modifiers | string[] | - | 触发框选的修饰键,如 ['ctrl', 'meta'] |
| strict | boolean | false | 是否严格模式(节点必须完全在框内) |
示例:
<SelectionPlugin
rubberband
showNodeSelectionBox
modifiers={['ctrl', 'meta']}
/>SnaplinePlugin
对齐线插件,拖拽节点时显示对齐线。
Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| sharp | boolean | false | 是否启用锐利对齐线 |
| resizing | boolean | false | 是否在调整大小时显示对齐线 |
| filter | string \| Function | - | 过滤节点 |
示例:
<SnaplinePlugin sharp />KeyboardPlugin
键盘快捷键插件。
功能:
Ctrl/Cmd + Z: 撤销Ctrl/Cmd + Shift + Z: 重做Ctrl/Cmd + A: 全选Backspace: 删除选中元素Ctrl/Cmd + 1: 放大Ctrl/Cmd + 2: 缩小
示例:
<KeyboardPlugin />ClipboardPlugin
剪贴板插件,支持复制粘贴。
示例:
<ClipboardPlugin />HistoryPlugin
历史记录插件,支持撤销/重做。
示例:
<HistoryPlugin />MinimapPlugin
小地图插件。
Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| width | number | 200 | 小地图宽度 |
| height | number | 150 | 小地图高度 |
| padding | number | 10 | 内边距 |
| simple | boolean | false | 是否使用简单模式 |
| style | React.CSSProperties | - | 容器样式 |
示例:
<MinimapPlugin
width={200}
height={150}
padding={10}
simple={false}
style={{
position: 'absolute',
bottom: 16,
right: 16,
}}
/>菜单组件
OperatorMenu
算子菜单组件,提供树状结构的算子菜单,支持拖拽功能。
Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| data | OperatorMenuItem[] | - | 菜单数据 |
| draggable | boolean \| { icon: boolean } | false | 是否可拖拽 |
| onDragStart | (e: DragEvent, node: OperatorMenuItem) => void | - | 拖拽开始回调 |
| showIcon | boolean | true | 是否显示图标 |
| showLine | boolean | true | 是否显示连接线 |
| enableSearch | boolean | true | 是否启用搜索 |
| searchPlaceholder | string | "搜索算子" | 搜索框占位符 |
| loading | boolean | false | 加载状态 |
| emptyText | string | "暂无算子数据" | 空数据提示 |
| onNodeClick | (e: React.MouseEvent, node: OperatorMenuItem) => void | - | 节点点击回调 |
| defaultExpandedKeys | React.Key[] | - | 默认展开的节点 |
示例:
import { OperatorMenu, OperatorMenuItem } from '@aidps/canvas-flow';
const menuData: OperatorMenuItem[] = [
{
id: '1',
pid: null,
label: '数据源',
children: [
{
id: '1-1',
pid: '1',
label: 'CSV读取',
shape: 'csv',
},
],
},
];
function App() {
const handleDragStart = (e: React.DragEvent, node: OperatorMenuItem) => {
// 处理拖拽逻辑
};
return (
<OperatorMenu
data={menuData}
draggable={{ icon: false }}
onDragStart={handleDragStart}
showIcon={true}
enableSearch={true}
/>
);
}NodeMenu / EdgeMenu
节点/边配置弹窗组件(Modal)。默认在节点/边点击时打开(需启用 enableMenus)。
右键上下文菜单
启用 enableMenus 后,画布会提供内置的右键上下文菜单:
- 节点右键:删除节点、克隆一份、居中到该节点、复制节点 JSON
- 边右键:删除边
- 画布空白右键:在此处新增节点、从缓存粘贴节点、撤销/重做、居中、放大/缩小
示例:
import { XFlow, XFlowGraph } from '@aidps/canvas-flow';
export default () => (
<XFlow enableMenus>
<XFlowGraph enableMenus />
</XFlow>
);NodeMenu Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| open | boolean | - | 是否打开 |
| onClose | () => void | - | 关闭回调 |
| node | Node \| null | - | 节点实例 |
| title | string | - | 菜单标题 |
| children | React.ReactNode | - | 菜单内容 |
EdgeMenu Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| open | boolean | - | 是否打开 |
| onClose | () => void | - | 关闭回调 |
| edge | Edge \| null | - | 边实例 |
| children | React.ReactNode | - | 菜单内容 |
示例:
import { NodeMenu, EdgeMenu, useMenu } from '@aidps/canvas-flow';
const CustomNodeMenu = () => {
const { nodeMenuOpen, selectedNode, closeNodeMenu } = useMenu();
return (
<NodeMenu
open={nodeMenuOpen}
onClose={closeNodeMenu}
node={selectedNode}
title={`节点配置: ${selectedNode?.getData()?.label || ''}`}
>
<Button>编辑节点</Button>
<Button>删除节点</Button>
</NodeMenu>
);
};画布函数封装
CanvasFunctionProvider
函数封装上下文提供者,用于管理函数封装状态。
示例:
import { CanvasFunctionProvider, FunctionModeToolbar } from '@aidps/canvas-flow';
function App() {
return (
<CanvasFunctionProvider>
<XFlow>
<FunctionModeToolbar />
<XFlowGraph />
</XFlow>
</CanvasFunctionProvider>
);
}FunctionModeToolbar
函数封装模式工具栏,用于切换参数选择模式。
Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| size | 'small' \| 'middle' \| 'large' | 'middle' | 按钮尺寸 |
| style | React.CSSProperties | - | 自定义样式 |
| className | string | - | 自定义类名 |
| entryType | 'node' \| 'function' \| 'both' | 'both' | 入口按钮显示控制 |
示例:
<FunctionModeToolbar size="small" />
<FunctionModeToolbar entryType="node" />
<FunctionModeToolbar entryType="function" />OutputPortsPanel
输出链接桩面板,显示所有节点的输出链接桩。
Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| title | string | "选择输出链接桩" | 面板标题 |
| embedded | boolean | false | 是否以嵌入模式显示 |
| style | React.CSSProperties | - | 自定义样式 |
| className | string | - | 自定义类名 |
示例:
<OutputPortsPanel embedded />FunctionSummaryModal
函数封装汇总弹窗,显示所有已选择的输入参数和输出链接桩。
Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| title | string | "画布函数封装" | 弹窗标题 |
| width | number \| string | 800 | 弹窗宽度 |
| onClose | () => void | - | 关闭回调 |
| onConfirm | (data: { inputs: SelectedParam[]; outputs: SelectedOutput[] }) => void | - | 确认回调 |
示例:
<FunctionSummaryModal
onConfirm={(data) => {
console.log('函数封装数据:', data);
}}
/>其他组件
CanvasPreview
画布预览组件,用于只读预览画布内容。
Props:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| data | GraphData | - | 画布数据 |
| width | number \| string | - | 预览宽度 |
| height | number \| string | - | 预览高度 |
| padding | number | 10 | 内边距 |
| style | React.CSSProperties | - | 自定义样式 |
示例:
<CanvasPreview
data={graphData}
width={300}
height={200}
padding={10}
/>Hooks 文档
useXFlow
获取画布上下文,包括 Graph 实例和选中节点。
返回值:
interface XFlowContextValue {
graph: Graph | null; // 画布实例
setGraph: (graph: Graph | null) => void;
selectedNode: Node | null; // 当前选中的节点
setSelectedNode: (node: Node | null) => void;
showConfigPanel: boolean; // 是否显示配置面板
setShowConfigPanel: (show: boolean) => void;
showOperatorMenu: boolean; // 是否显示算子菜单
setShowOperatorMenu: (show: boolean) => void;
showMinimap: boolean; // 是否显示小地图
setShowMinimap: (show: boolean) => void;
}示例:
import { useXFlow } from '@aidps/canvas-flow';
const MyComponent = () => {
const { graph, selectedNode } = useXFlow();
const handleAddNode = () => {
if (graph) {
graph.addNode({
shape: 'rect',
x: 100,
y: 100,
width: 80,
height: 40,
});
}
};
return (
<div>
<p>当前选中节点: {selectedNode?.id}</p>
<button onClick={handleAddNode}>添加节点</button>
</div>
);
};useGraph
获取画布实例的快捷 Hook。
返回值:
Graph | null示例:
import { useGraph } from '@aidps/canvas-flow';
const MyComponent = () => {
const graph = useGraph();
const handleCenter = () => {
if (graph) {
graph.centerContent();
}
};
return <button onClick={handleCenter}>居中</button>;
};useNode
获取当前选中节点的快捷 Hook。
返回值:
{
node: Node | null; // 节点实例
nodeData: { // 节点数据
node: Node;
data: any;
shape: string;
id: string;
position: { x: number; y: number };
size: { width: number; height: number };
} | null;
graph: Graph | null; // 画布实例
hasNode: boolean; // 是否有选中节点
}示例:
import { useNode } from '@aidps/canvas-flow';
const NodeInfo = () => {
const { node, nodeData, hasNode } = useNode();
if (!hasNode) {
return <div>请选择一个节点</div>;
}
return (
<div>
<p>节点ID: {nodeData?.id}</p>
<p>节点标签: {nodeData?.data?.label}</p>
<p>位置: ({nodeData?.position.x}, {nodeData?.position.y})</p>
</div>
);
};useMenu
获取菜单上下文,用于控制节点和边的右键菜单。
返回值:
interface MenuContextValue {
// 节点菜单
nodeMenuOpen: boolean; // 节点菜单是否打开
selectedNode: Node | null; // 当前选中的节点
openNodeMenu: (node: Node) => void; // 打开节点菜单
closeNodeMenu: () => void; // 关闭节点菜单
// 边菜单
edgeMenuOpen: boolean; // 边菜单是否打开
selectedEdge: Edge | null; // 当前选中的边
openEdgeMenu: (edge: Edge) => void; // 打开边菜单
closeEdgeMenu: () => void; // 关闭边菜单
// 通用
closeAllMenus: () => void; // 关闭所有菜单
}注意: 必须在 XFlow 组件设置 enableMenus={true} 时才能使用。
示例:
import { useMenu } from '@aidps/canvas-flow';
const CustomNodeMenu = () => {
const {
nodeMenuOpen,
selectedNode,
openNodeMenu,
closeNodeMenu
} = useMenu();
return (
<NodeMenu
open={nodeMenuOpen}
onClose={closeNodeMenu}
node={selectedNode}
>
<Button onClick={() => {
console.log('编辑节点:', selectedNode);
closeNodeMenu();
}}>
编辑节点
</Button>
</NodeMenu>
);
};useCanvasFunction
获取画布函数封装上下文,用于管理函数封装状态。
返回值:
interface CanvasFunctionContextValue {
// 模式控制
isSelectionMode: boolean; // 是否处于参数选择模式
setSelectionMode: (mode: boolean) => void; // 开启/关闭参数选择模式
toggleSelectionMode: () => void; // 切换参数选择模式
// 面板视图
panelView: 'node-config' | 'output-ports'; // 当前面板视图
setPanelView: (view: PanelViewType) => void; // 设置面板视图
// 输入参数
selectedParams: SelectedParam[]; // 已选择的输入参数列表
addParam: (param: SelectedParam) => void; // 添加输入参数
removeParam: (nodeId: string, fieldName: string) => void; // 移除输入参数
clearParams: () => void; // 清空所有输入参数
isParamSelected: (nodeId: string, fieldName: string) => boolean; // 检查参数是否已选择
// 输出链接桩
selectedOutputs: SelectedOutput[]; // 已选择的输出链接桩列表
addOutput: (output: SelectedOutput) => void; // 添加输出链接桩
removeOutput: (nodeId: string, portId: string) => void; // 移除输出链接桩
clearOutputs: () => void; // 清空所有输出链接桩
isOutputSelected: (nodeId: string, portId: string) => boolean; // 检查输出是否已选择
// 通用
clearAll: () => void; // 清空所有选择
showSummaryModal: boolean; // 是否显示汇总弹窗
setShowSummaryModal: (show: boolean) => void; // 设置汇总弹窗显示状态
getFunctionData: () => { // 获取函数封装数据
inputs: SelectedParam[];
outputs: SelectedOutput[];
};
}示例:
import { useCanvasFunction } from '@aidps/canvas-flow';
const MyComponent = () => {
const {
isSelectionMode,
toggleSelectionMode,
selectedParams,
selectedOutputs,
getFunctionData,
} = useCanvasFunction();
const handleExport = () => {
const data = getFunctionData();
console.log('函数封装数据:', data);
// 导出或保存数据
};
return (
<div>
<button onClick={toggleSelectionMode}>
{isSelectionMode ? '退出选择模式' : '进入选择模式'}
</button>
<p>已选择 {selectedParams.length} 个输入参数</p>
<p>已选择 {selectedOutputs.length} 个输出链接桩</p>
<button onClick={handleExport}>导出函数数据</button>
</div>
);
};useCanvasFunctionSafe
安全获取画布函数封装上下文,不会抛出错误(当 CanvasFunctionProvider 不存在时返回 null)。
返回值:
CanvasFunctionContextValue | null示例:
import { useCanvasFunctionSafe } from '@aidps/canvas-flow';
const MyComponent = () => {
const canvasFunction = useCanvasFunctionSafe();
// 安全使用,不会抛出错误
if (canvasFunction) {
return (
<div>
<p>选择模式: {canvasFunction.isSelectionMode ? '开启' : '关闭'}</p>
</div>
);
}
return <div>函数封装功能未启用</div>;
};工具函数
封装模式
模式概览
- 节点封装:对选中的子图进行封装,支持“参数 + 输入 + 输出”三类配置,适合把一段流程封成可复用模块。
- 函数封装:对选中的子图进行封装,但仅支持“参数 + 输出”,适合把内部参数作为函数入参,输出作为函数返回。
操作流程
- 进入封装模式:在工具栏点击“节点封装”或“函数封装”,第一步为“节点选择”
- 框选节点:在“节点选择”步骤直接拖拽框选(无需按修饰键)
- 配置步骤:点击“下一步”进入参数/输入/输出配置
- 参数:选择并可重命名需要透出的节点参数
- 输入:选择子图边界的输入端口(仅节点封装)
- 输出:选择子图边界的输出端口
- 返回修改:随时点击“上一步”返回节点选择增删参与封装节点,系统自动校验并清理失效项
- 完成预览:点击“查看选择”或“完成”查看当前汇总
相关组件
- FunctionModeToolbar:封装模式工具栏,提供“节点封装/函数封装”入口与上一步/下一步、查看选择、清空、完成等操作
- EncapsulationTabsPanel:封装步骤中显示“参数/输入/输出”三类面板
- EncapsulationSelection:封装模式下的框选配置,根据步骤自动启用/禁用
- FunctionEncapsulationBridge:桥接 X6 事件与封装状态,负责子图快照、边界端口计算与选择校验
使用示例
import { CanvasFunctionProvider, FunctionModeToolbar, XFlow, XFlowGraph } from '@aidps/canvas-flow';
export default () => (
<CanvasFunctionProvider>
<XFlow>
<FunctionModeToolbar />
<XFlowGraph />
</XFlow>
</CanvasFunctionProvider>
);行为与交互说明
- 框选:在“节点选择”步骤中启用 rubberband 框选,直接拖拽即可框选
- 只读:在参数/输入/输出步骤中画布进入只读,避免误操作导致选择丢失
- 校验:当子图结构或选择变化时,系统会自动清理不在子图或边界的已选项
- 汇总:支持查看当前选择的参数、输入、输出的列表
常用配置(内部)
封装模式入口支持如下配置:
type EnterEncapsulationModeOptions = {
focus?: 'nodes' | 'params' | 'inputs' | 'outputs';
preserveOutputs?: boolean;
enabledTabs?: Array<'params' | 'inputs' | 'outputs'>;
selection?: {
enabled?: boolean;
rubberband?: boolean;
modifiers?: null | Array<'alt'|'ctrl'|'meta'|'shift'>; // 设为 null 代表无需按键即可框选
eventTypes?: string[]; // 默认 ['leftMouseDown']
};
panningWhenSelecting?: 'disable' | { modifiers: string[] };
};提示:
- “节点选择”步骤默认
selection.modifiers = null,可直接拖拽框选 - 参数/输入/输出步骤禁用框选并进入只读交互,避免误点击
节点工厂工具
createNodeConfig
创建节点配置。
createNodeConfig(
graph: Graph,
nodeData: OperatorMenuItem,
point: { x: number; y: number },
count: number
): Node.MetadatacreateNodeForDrag
创建用于拖拽的节点。
createNodeForDrag(
graph: Graph,
nodeData: OperatorMenuItem,
point: { x: number; y: number },
count: number
): NodegetPortsFromInfo
从节点信息中提取端口配置。
getPortsFromInfo(
info: any,
isGroup?: boolean
): PortInfo[]端口类型工具
isPortTypeCompatible
检查两个端口类型是否兼容。
isPortTypeCompatible(sourceType: PortType, targetType: PortType): booleangetPortType
获取端口类型。
getPortType(port: Port): PortTypegetPortLabel
获取端口标签。
getPortLabel(port: Port): string类型定义
核心类型
// 画布配置
type GraphConfig = Partial<Graph.Options>;
// 算子菜单项
interface OperatorMenuItem {
id: string;
pid: string | null;
label: string;
shape?: string;
children?: OperatorMenuItem[];
[key: string]: any;
}
// 选中的参数
interface SelectedParam {
nodeId: string;
nodeName: string;
fieldName: string;
fieldLabel: string;
fieldType: string;
currentValue?: any;
nodeShape?: string;
}
// 选中的输出链接桩
interface SelectedOutput {
nodeId: string;
nodeName: string;
portId: string;
portLabel: string;
portType?: string;
nodeShape?: string;
}完整示例:函数封装
import React from 'react';
import {
XFlow,
XFlowGraph,
CanvasFunctionProvider,
FunctionModeToolbar,
FunctionSummaryModal,
useCanvasFunction,
} from '@aidps/canvas-flow';
const FunctionEncapsulationDemo = () => {
return (
<CanvasFunctionProvider>
<XFlow>
{/* 工具栏 - 切换函数封装模式 */}
<FunctionModeToolbar />
{/* 画布 - 自动支持只读模式 */}
<XFlowGraph
config={{
grid: true,
autoResize: true,
}}
/>
{/* 汇总弹窗 */}
<FunctionSummaryModal
onConfirm={(data) => {
console.log('函数封装数据:', data);
// 处理函数封装数据
}}
/>
</XFlow>
</CanvasFunctionProvider>
);
};开发
# 安装依赖
pnpm install
# 启动开发服务器(可视化查看组件效果)
pnpm dev
# 开发模式(监听文件变化,用于库开发)
pnpm dev:watch
# 构建组件库
pnpm build
# 构建预览界面
pnpm build:demo
# 预览构建结果(组件库)
pnpm preview
# 预览构建后的预览界面
pnpm preview:demo
# 清理构建产物
pnpm clean # 清理库构建产物
pnpm clean:demo # 清理预览界面构建产物
pnpm clean:all # 清理所有构建产物开发服务器
运行 pnpm dev 会启动 Vite 开发服务器,自动打开浏览器显示组件示例页面。
开发页面包含:
- 工具栏(添加节点、清空、居中、缩放等)
- 画布区域(可拖拽、缩放、框选)
- 信息面板(显示节点数、边数、缩放比例)
- 所有插件功能(框选、对齐线、快捷键、剪贴板、撤销重做)
- 函数封装功能演示
打包和发布
构建
构建组件库
# 构建生产版本
pnpm build构建产物:
dist/index.js- CommonJS 格式dist/index.esm.js- ES Module 格式dist/index.d.ts- TypeScript 类型声明
构建预览界面
构建开发示例页面(预览界面),用于独立部署和展示:
# 构建预览界面(会自动先构建组件库)
pnpm build:demo构建产物:
dist-demo/index.html- 预览界面入口dist-demo/assets/- 静态资源(JS、CSS 等)
预览构建后的界面:
pnpm preview:demo清理构建产物
# 清理库构建产物
pnpm clean
# 清理预览界面构建产物
pnpm clean:demo
# 清理所有构建产物
pnpm clean:all
### 发布到 npm
```bash
# 登录 npm(首次发布需要)
npm login
# 发布(会自动执行 prepublishOnly 脚本进行构建)
npm publish
# 发布到私有仓库
npm publish --registry=https://your-registry.com版本管理
# 更新版本号
npm version patch # 1.0.0 -> 1.0.1
npm version minor # 1.0.0 -> 1.1.0
npm version major # 1.0.0 -> 2.0.0
# 然后发布
npm publishLicense
MIT
