革命性Web建模工具bpmn-js:如何用JavaScript轻松实现企业级BPMN 2.0工作流设计
你还在为复杂的工作流程设计工具感到头疼吗?还在为无法在Web环境中轻松编辑BPMN 2.0图表而烦恼吗?本文将带你全面了解bpmn-js——这款基于JavaScript的BPMN 2.0渲染工具包和Web建模器,让你在浏览器中就能轻松实现专业的工作流设计。读完本文,你将能够:
- 了解bpmn-js的核心功能和优势
- 掌握bpmn-js的安装和基本使用方法
- 学会如何在项目中集成bpmn-js
- 了解bpmn-js的高级特性和扩展方式
什么是bpmn-js?
bpmn-js是一个用于在Web浏览器中查看和编辑BPMN 2.0图表的JavaScript工具包。BPMN(Business Process Model and Notation,业务流程模型和符号)是一种国际标准的业务流程建模语言,用于以图形化方式表示业务流程。
bpmn-js的核心优势在于:
- 纯Web技术栈,无需安装桌面应用
- 轻量级设计,易于集成到现有Web应用中
- 高度可定制,支持丰富的扩展
- 完整支持BPMN 2.0规范
项目结构概览:
- 核心模块:lib/
- 渲染模块:lib/draw/
- 功能模块:lib/features/
- 测试用例:test/
- 官方文档:docs/
快速开始:安装与基本使用
环境准备
在开始使用bpmn-js之前,确保你的开发环境中已安装:
- Node.js (推荐v14+)
- npm (通常随Node.js一起安装)
- Git
安装方式
bpmn-js提供了多种安装方式,可根据你的项目需求选择:
1. 通过npm安装(推荐)
npm install bpmn-js
2. 直接引入预打包文件
你也可以从项目的发布页面下载预打包的文件,然后在HTML中直接引入:
<script src="bpmn-viewer.umd.min.js"></script>
3. 源码构建
如果你需要最新的开发版本,可以从源码构建:
# 克隆仓库
git clone https://gitcode.com/gh_mirrors/bp/bpmn-js.git
cd bpmn-js
# 安装依赖
npm install
# 构建项目
npm run all
详细的项目设置指南请参考:docs/project/SETUP.md
基本使用示例
以下是一个简单的HTML页面,演示如何使用bpmn-js查看BPMN图表:
<!DOCTYPE html>
<html>
<head>
<title>bpmn-js 快速演示</title>
<script src="https://cdn.jsdelivr.net/npm/bpmn-js@9.0.0/dist/bpmn-viewer.umd.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bpmn-js@9.0.0/dist/assets/bpmn-js.css">
<style>
#canvas {
width: 100%;
height: 600px;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<div id="canvas"></div>
<script>
// BPMN 2.0 XML示例
const xml = `
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd"
id="sample-diagram"
targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn2:process id="Process_1" isExecutable="false">
<bpmn2:startEvent id="StartEvent_1" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
<dc:Bounds x="173" y="102" width="36" height="36" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
`;
// 创建一个BPMN查看器实例
const viewer = new BpmnJS({
container: '#canvas'
});
// 导入并渲染BPMN XML
try {
const { warnings } = await viewer.importXML(xml);
if (warnings.length) {
console.warn('导入过程中发现警告:', warnings);
}
console.log('BPMN图表渲染成功!');
} catch (err) {
console.error('渲染BPMN图表时出错:', err);
}
</script>
</body>
</html>
动态附加/分离
bpmn-js支持动态地将查看器附加到页面元素或从页面元素分离:
// 创建一个BPMN查看器实例,不指定容器
const viewer = new BpmnJS();
// 将查看器附加到某个DOM元素
viewer.attachTo('#container');
// 从当前DOM元素分离查看器
viewer.detach();
核心组件与架构
bpmn-js采用模块化架构设计,主要由以下核心组件构成:
核心模块
-
Modeler(建模器):lib/Modeler.js 完整的BPMN建模工具,支持创建和编辑BPMN图表
-
Viewer(查看器):lib/Viewer.js 仅用于查看BPMN图表,不包含编辑功能
-
NavigatedViewer(导航查看器):lib/NavigatedViewer.js 带导航功能的查看器,支持缩放、平移等操作
功能模块
bpmn-js的丰富功能由各种特性模块提供,主要包括:
-
上下文菜单:lib/features/context-pad/ 提供元素上下文菜单,支持快速操作
-
调色板:lib/features/palette/ 提供工具栏,用于添加新元素
-
建模功能:lib/features/modeling/ 核心建模功能,如创建、移动、删除元素等
-
自动放置:lib/features/auto-place/ 智能放置新元素,自动连接流程
-
对齐元素:lib/features/align-elements/ 支持元素对齐功能,优化图表布局
渲染模块
-
BPMN渲染器:lib/draw/BpmnRenderer.js 负责将BPMN元素渲染到画布上
-
文本渲染器:lib/draw/TextRenderer.js 处理文本标签的渲染
-
路径映射:lib/draw/PathMap.js 定义BPMN元素的SVG路径
高级特性与应用场景
自定义样式
bpmn-js允许你自定义BPMN元素的外观,以匹配你的品牌风格或特定需求。可以通过CSS自定义各种元素的样式:
/* 自定义任务元素样式 */
.bpmn-icon-task {
fill: #3498db;
}
/* 自定义序列流样式 */
.bpmn-connection {
stroke: #2ecc71;
stroke-width: 2px;
}
/* 自定义开始事件样式 */
.bpmn-icon-start-event-none {
fill: #e74c3c;
}
事件监听
bpmn-js提供了丰富的事件系统,可以监听各种用户操作和内部状态变化:
// 监听元素被点击事件
viewer.on('element.click', function(event) {
const element = event.element;
console.log('元素被点击:', element);
});
// 监听图表导入完成事件
viewer.on('import.done', function(event) {
if (!event.error) {
console.log('图表导入成功');
} else {
console.error('图表导入失败:', event.error);
}
});
// 监听元素被移动事件
viewer.get('eventBus').on('element.moved', function(event) {
const element = event.element;
const newPosition = element.position;
console.log(`元素 ${element.id} 被移动到: x=${newPosition.x}, y=${newPosition.y}`);
});
与后端集成
在实际应用中,通常需要将bpmn-js与后端系统集成,实现BPMN图表的持久化存储和协作编辑。
以下是一个简单的示例,演示如何将编辑好的BPMN图表保存到后端:
// 获取当前图表的XML
async function saveDiagram() {
try {
const { xml } = await viewer.saveXML({ format: true });
// 发送XML到后端保存
const response = await fetch('/api/save-diagram', {
method: 'POST',
headers: {
'Content-Type': 'application/xml',
},
body: xml,
});
if (!response.ok) {
throw new Error('保存图表失败');
}
console.log('图表保存成功');
return await response.json();
} catch (err) {
console.error('保存图表时出错:', err);
throw err;
}
}
// 从后端加载图表
async function loadDiagram(diagramId) {
try {
const response = await fetch(`/api/diagrams/${diagramId}`);
if (!response.ok) {
throw new Error('加载图表失败');
}
const xml = await response.text();
await viewer.importXML(xml);
console.log('图表加载成功');
} catch (err) {
console.error('加载图表时出错:', err);
throw err;
}
}
扩展bpmn-js
bpmn-js设计为高度可扩展的,可以通过多种方式扩展其功能:
-
自定义规则:lib/features/rules/ 定义新的业务规则,控制元素间的连接和交互
-
自定义元素: 添加新的BPMN元素类型或自定义现有元素行为
-
自定义模块: 创建全新的功能模块,扩展bpmn-js的能力
开发与贡献
如果你对bpmn-js的开发感兴趣,或者想为项目贡献代码,可以按照以下步骤设置开发环境:
源码构建
# 克隆仓库
git clone https://gitcode.com/gh_mirrors/bp/bpmn-js.git
cd bpmn-js
# 安装依赖
npm install
# 运行开发服务器
npm start
这将启动一个本地开发服务器,通常在 http://localhost:9000,可以在浏览器中查看和测试bpmn-js。
运行测试
# 运行所有测试
npm run test
# 运行特定测试文件
npm run test -- --grep "some test pattern"
# 运行测试并生成覆盖率报告
npm run test:coverage
测试用例位于test/目录下,包含单元测试、集成测试和功能测试。
构建生产版本
# 构建生产版本
npm run build
构建结果将输出到dist目录。
实际应用案例
案例1:简单工作流编辑器
以下是一个完整的BPMN建模器实现,包含基本的编辑功能:
<!DOCTYPE html>
<html>
<head>
<title>bpmn-js 建模器示例</title>
<script src="https://cdn.jsdelivr.net/npm/bpmn-js@9.0.0/dist/bpmn-modeler.umd.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bpmn-js@9.0.0/dist/assets/bpmn-js.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bpmn-js@9.0.0/dist/assets/diagram-js.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bpmn-js@9.0.0/dist/assets/bpmn-font/css/bpmn.css">
<style>
body {
margin: 0;
font-family: Arial, sans-serif;
}
#app {
display: flex;
flex-direction: column;
height: 100vh;
}
#toolbar {
padding: 10px;
background-color: #f5f5f5;
border-bottom: 1px solid #ddd;
}
#canvas {
flex: 1;
width: 100%;
}
button {
padding: 8px 12px;
margin-right: 5px;
background-color: #3498db;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #2980b9;
}
</style>
</head>
<body>
<div id="app">
<div id="toolbar">
<button id="saveBtn">保存图表</button>
<button id="exportBtn">导出PNG</button>
</div>
<div id="canvas"></div>
</div>
<script>
// 创建建模器实例
const modeler = new BpmnJS({
container: '#canvas',
keyboard: {
bindTo: window
}
});
// 初始XML
const initialXml = `
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd"
id="sample-diagram"
targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn2:process id="Process_1" isExecutable="true">
<bpmn2:startEvent id="StartEvent_1" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
<dc:Bounds x="173" y="102" width="36" height="36" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
`;
// 初始化建模器
async function initModeler() {
try {
await modeler.importXML(initialXml);
console.log('建模器初始化成功');
// 使画布自适应
const canvas = modeler.get('canvas');
canvas.zoom('fit-viewport');
} catch (err) {
console.error('初始化建模器失败:', err);
}
}
// 保存图表
document.getElementById('saveBtn').addEventListener('click', async () => {
try {
const { xml } = await modeler.saveXML({ format: true });
console.log('BPMN XML:', xml);
// 这里可以将XML发送到后端保存
alert('图表已保存到控制台!');
} catch (err) {
console.error('保存图表失败:', err);
alert('保存图表失败: ' + err.message);
}
});
// 导出PNG
document.getElementById('exportBtn').addEventListener('click', async () => {
try {
const { svg } = await modeler.saveSVG();
const blob = new Blob([svg], { type: 'image/svg+xml' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'diagram.svg';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
} catch (err) {
console.error('导出SVG失败:', err);
alert('导出SVG失败: ' + err.message);
}
});
// 初始化应用
initModeler();
</script>
</body>
</html>
案例2:流程监控仪表板
bpmn-js不仅可以用于设计流程,还可以与实际运行的流程数据结合,实现流程监控功能:
// 模拟流程实例数据
const processInstances = [
{ id: 'pi-1', status: 'running', startedAt: '2023-07-01T10:00:00Z' },
{ id: 'pi-2', status: 'completed', startedAt: '2023-07-01T11:30:00Z', endedAt: '2023-07-01T12:45:00Z' },
{ id: 'pi-3', status: 'failed', startedAt: '2023-07-01T14:00:00Z', error: '数据库连接失败' }
];
// 在图表上显示流程实例状态
function highlightRunningInstances() {
const elementRegistry = modeler.get('elementRegistry');
const graphicsFactory = modeler.get('graphicsFactory');
// 高亮显示特定活动节点
const taskElement = elementRegistry.get('Task_1');
if (taskElement) {
const gfx = elementRegistry.getGraphics(taskElement);
const attrs = graphicsFactory.getShapePathMap().get('task');
// 添加高亮效果
const highlighter = modeler.get('highlighter');
highlighter.highlight(taskElement.id);
}
}
总结与展望
bpmn-js作为一款强大的Web端BPMN建模工具,为业务流程可视化和编辑提供了便捷的解决方案。其主要优势在于:
- Web原生:基于JavaScript和SVG,无需安装额外软件
- 易于集成:轻量级设计,可轻松嵌入各种Web应用
- 高度可扩展:模块化架构支持丰富的自定义和扩展
- 活跃社区:背后有活跃的开发团队和社区支持
随着业务流程数字化的深入,bpmn-js将在以下方面发挥越来越重要的作用:
- 低代码/无代码平台中的流程设计器
- 企业级应用中的工作流可视化
- 流程挖掘与分析工具
- 教学与培训中的流程展示
如果你想深入了解更多关于bpmn-js的内容,可以参考以下资源:
- 官方示例:test/fixtures/bpmn/
- API文档:可通过源码中的JSDoc生成
- 变更日志:CHANGELOG.md
无论是构建企业级工作流系统,还是开发简单的流程可视化工具,bpmn-js都是一个值得考虑的优秀选择。通过本文介绍的内容,你已经具备了开始使用bpmn-js的基础知识,接下来可以根据具体需求进一步探索其丰富的功能和扩展能力。
开始你的BPMN建模之旅吧!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



