Bpmn.js 进阶指南之Lint流程校验(三)

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: Bpmn.js 进阶指南之Lint流程校验(三)

前言


在之前的文章中已经把 bpmn.js 的执行原理和模块扩展方式都做了一些简单介绍,对 RendererRules 等常用功能也进行了说明。这个时候基本上已经可以满足大部分情况下的需求场景,但是也有小伙伴反应产品有新需求,需要在前端对流程完整性进行校验。


之前的两节已经讲了 bpmn.js 的校验模块如何使用的问题,以及 bpmn-js-bpmnlint 包的核心模块和校验方法。本小节主要将一下 bpmnlintLinter 模块如何根据配置文件进行校验的。


整体流程


第一节已经说过,bpmnlint 内部预设了有十几个校验规则,在 bpmn.js 中使用时可以通过配置 linting.bpmnlint 来配置 rules 使用规则。在触发校验的时候,是通过初始化一个 Linter 实例并调用 linter.lint() 来执行流程校验的。


这里对这几个参数做一下简单说明:


const modeler = new BpmnModeler({
   container: 'xxx',
   //...
   linting: {
     active: true, // 是否在实例化之后就开启流程校验
     bpmnlint: {
       config: {
         resolver, // 解析器
         config: {
           rules: {}  // 规则配置对象
         }
       }
     }
   }
 })


new Modeler 过程中会也会实例化对应的其他 additionalModule 实例,这里就会实例化一个 Linting


1.1 new Linting


该构造函数就是实现界面错误信息显示,控制校验开关等功能的模块,依赖的 config 配置包含 activebpmnlint 两个字段,并将 bpmnlint 保存到 this._linterConfig 中;并提供一个方法 setLinterConfig(linterConfig) 用来修改该配置。


而当规则配置改变或者流程图发生改变时,就会触发 Linting.lint() 来校验当前流程。


1.2 Linting.lint()


该方法逻辑很简单,即实例化一个 Linter 并执行校验。


Linting.prototype.lint = function() {
   var definitions = this._bpmnjs.getDefinitions();
   var linter = new bpmnlint.Linter(this._linterConfig);
   return linter.lint(definitions);
 };


其中,this._bpmnjs 指代 modeler 实例,bpmnlint.Linter 则是 bpmnlint 中的 Linter 模块。


1.3 new Linter


function Linter(options = {}) {
   const { config,  resolver } = options;
   this.config = config;
   this.resolver = resolver;
   this.cachedRules = {};
   this.cachedConfigs = {};
 }


这个过程很简单,就是保存传入的 options 参数,也就是上面的 linting._linterConfig 配置。因为每次校验时都会重新实例化一个 linter,所以可以通过 linting.setLinterConfig 重新配置规则,实现动态化配置。


1.4 linter.lint


这一步则是最关键的部分,会解析 linter.config 中的规则配置,并依次校验流程是否符合。


Linter.prototype.lint = function(moddleRoot, config) {
   config = config || this.config;
   return this.resolveRules(config).then((ruleDefinitions) => {
     const allReports = {};
     ruleDefinitions.forEach((ruleDefinition) => {
       const { name } = ruleDefinition;
       const reports = this.applyRule(moddleRoot, ruleDefinition);
       if (reports.length) {
         allReports[name] = reports;
       }
     });
     return allReports;
   });
 };


这里在实际执行过程中只有第一个参数。


resolveRules 规则配置处理


Linter.prototype.resolveRules = function(config) {
   // resolveConfiguredRules: 解析 extends 继承关系,并合并配置
   return this.resolveConfiguredRules(config).then((rulesConfig) => {
     // 根据合并后的规则配置对象,解析为正式格式的配置项数组
     const parsedRules = Object.entries(rulesConfig).map(([ name, value ]) => {
       const { category, config } = this.parseRuleValue(value);
       return { name, category, config };
     });
     // 筛选出没有被关闭的规则
     const enabledRules = parsedRules.filter(definition => definition.category !== 'off');
     // 遍历可用规则配置,从 cachedRules 中读取到对应的规则校验函数
     const loaders = enabledRules.map((definition) => {
       const {  name, config } = definition;
       return this.resolveRule(name, config).then(function(rule) {
         return { ...definition, rule };
       });
     });
     return Promise.all(loaders);
   });
 };


applyRule 校验流程


上文解析完规则配置之后,就会遍历配置调用 applyRule 来检查流程。这个过程其实也很简单,就是根据规则函数中的 check 方法来检查传入的这个流程图根节点,并将检查结果返回出来


Linter.prototype.applyRule = function applyRule(moddleRoot, ruleDefinition) {
   const { config, rule,  category, name } = ruleDefinition;
   try {
     const reports = testRule({ moddleRoot, rule, config });
     return reports.map(function(report) {
       return { ...report, category  };
     });
   } catch (e) {
     console.error('rule <' + name + '> failed with error: ', e);
     return [
       {  message: 'Rule error: ' + e.message, category: 'error' }
     ];
   }
 };


这里的 testRule 就是一个校验方法,内部会实例化一个 Reporter 对象,对校验结果进行格式化输出。


校验结果


假设我们有这样一个流程图:


网络异常,图片无法展示
|


这个图按照默认的规则来看,包含以下三个类型的错误:


  1. 没有开始节点


  1. 没有结束节点


  1. 流程节点没有被连接(也就是没有关联到一个流程上)


所以 bpmnlint 的校验结果也是如此,按照不同的规则配置分为不同的错误信息,并作为一个对象输出。


网络异常,图片无法展示
|


但是这个结果不能直接给用户提示,所以 bpmn-js-bpmnlintLinting 模块对这些信息进行了解析,并分别为错误元素创建不同的 overlays 图层来显示错误信息。


错误信息格式化与图层创建等,后续与 Overlays 模块结合讲解


目录
相关文章
|
7月前
|
搜索推荐 Shell
bpmn-js打造最强flowable流程设计器
在企业系统中,流程引擎至关重要。Flowable虽强大,但默认设计器功能有限。本文基于 bpmn-js 打造增强版 Flowable 设计器,支持丰富自定义属性与后端联动。bpmn-js 优势明显:原生支持 BPMN 2.0、可扩展性强、社区活跃。节点涵盖多种事件、任务、网关等,满足复杂业务需求。示例效果可见在线预览。
|
JavaScript 前端开发
JavaScript基础知识-流程控制之while循环
这篇文章介绍了JavaScript中的while循环和do...while循环的基础知识,并通过一个实际案例演示了如何使用while循环计算投资增长到特定金额所需的年数。
212 2
JavaScript基础知识-流程控制之while循环
|
10月前
|
JavaScript 前端开发
JavaWeb JavaScript ③ JS的流程控制和函数
通过本文的详细介绍,您可以深入理解JavaScript的流程控制和函数的使用,进而编写出高效、可维护的代码。
222 32
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的销售项目流程化管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的销售项目流程化管理系统附带文章源码部署视频讲解等
168 3
|
监控 JavaScript 算法
深度剖析 Vue.js 响应式原理:从数据劫持到视图更新的全流程详解
本文深入解析Vue.js的响应式机制,从数据劫持到视图更新的全过程,详细讲解了其实现原理和运作流程。
|
JavaScript 前端开发
JavaScript基础知识-流程控制之for循环
这篇文章讲解了JavaScript中的for循环的基础知识,并通过一个实例演示了如何使用for循环来找出所有的三位水仙花数。
170 6
JavaScript基础知识-流程控制之for循环
|
前端开发 JavaScript 数据安全/隐私保护
前端JS正则校验密码之3种实现方式
这篇文章展示了三种使用JavaScript正则表达式来校验密码的方法,密码需要满足包含大写字母、小写字母、数字及特殊字符,并在8到16位之间,同时提供了示例代码和实现效果。
541 1
前端JS正则校验密码之3种实现方式
|
JavaScript 前端开发
js_Ipv4以及ipv4段正则校验
几种JavaScript正则表达式,用于校验IPv4地址的有效性,包括支持CIDR表示法的变体。
314 4
|
大数据 数据处理 分布式计算
JSF 逆袭大数据江湖!看前端框架如何挑战数据处理极限?揭秘这场技术与勇气的较量!
【8月更文挑战第31天】在信息爆炸时代,大数据已成为企业和政府决策的关键。JavaServer Faces(JSF)作为标准的 Java Web 框架,如何与大数据技术结合,高效处理大规模数据集?本文探讨大数据的挑战与机遇,介绍 JSF 与 Hadoop、Apache Spark 等技术的融合,展示其实现高效数据存储和处理的潜力,并提供示例代码,助您构建强大的大数据系统。
157 0
|
JavaScript 安全 数据安全/隐私保护
深入Node.js与Express:从表单接收到数据验证的完整指南——实战技巧揭秘后端开发中的表单处理流程
【8月更文挑战第31天】在Web开发中,处理表单数据至关重要。本文通过实例详细讲解了如何利用Node.js与Express框架接收和验证表单数据。首先,搭建环境并初始化一个简单的Express应用;接着,演示如何接收用户注册表单中的`username`和`email`字段;最后,引入`joi`模块进行数据验证,确保数据安全准确。掌握这些技能有助于开发者构建更安全、友好的Web应用。随着Node.js和Express的不断进步,未来将有更多高级功能值得期待。
363 0