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

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 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 模块结合讲解


目录
相关文章
|
4月前
|
JavaScript 前端开发
JavaScript基础知识-流程控制之while循环
这篇文章介绍了JavaScript中的while循环和do...while循环的基础知识,并通过一个实际案例演示了如何使用while循环计算投资增长到特定金额所需的年数。
72 2
JavaScript基础知识-流程控制之while循环
|
2月前
|
监控 JavaScript 算法
深度剖析 Vue.js 响应式原理:从数据劫持到视图更新的全流程详解
本文深入解析Vue.js的响应式机制,从数据劫持到视图更新的全过程,详细讲解了其实现原理和运作流程。
|
7月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的销售项目流程化管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的销售项目流程化管理系统附带文章源码部署视频讲解等
79 3
|
4月前
|
JavaScript 前端开发
JavaScript基础知识-流程控制之for循环
这篇文章讲解了JavaScript中的for循环的基础知识,并通过一个实例演示了如何使用for循环来找出所有的三位水仙花数。
67 6
JavaScript基础知识-流程控制之for循环
|
4月前
|
JavaScript 前端开发
js_Ipv4以及ipv4段正则校验
几种JavaScript正则表达式,用于校验IPv4地址的有效性,包括支持CIDR表示法的变体。
112 4
|
5月前
|
前端开发 JavaScript 数据安全/隐私保护
前端JS正则校验密码之3种实现方式
这篇文章展示了三种使用JavaScript正则表达式来校验密码的方法,密码需要满足包含大写字母、小写字母、数字及特殊字符,并在8到16位之间,同时提供了示例代码和实现效果。
188 1
前端JS正则校验密码之3种实现方式
|
5月前
|
大数据 数据处理 分布式计算
JSF 逆袭大数据江湖!看前端框架如何挑战数据处理极限?揭秘这场技术与勇气的较量!
【8月更文挑战第31天】在信息爆炸时代,大数据已成为企业和政府决策的关键。JavaServer Faces(JSF)作为标准的 Java Web 框架,如何与大数据技术结合,高效处理大规模数据集?本文探讨大数据的挑战与机遇,介绍 JSF 与 Hadoop、Apache Spark 等技术的融合,展示其实现高效数据存储和处理的潜力,并提供示例代码,助您构建强大的大数据系统。
72 0
|
5月前
|
JavaScript 安全 数据安全/隐私保护
深入Node.js与Express:从表单接收到数据验证的完整指南——实战技巧揭秘后端开发中的表单处理流程
【8月更文挑战第31天】在Web开发中,处理表单数据至关重要。本文通过实例详细讲解了如何利用Node.js与Express框架接收和验证表单数据。首先,搭建环境并初始化一个简单的Express应用;接着,演示如何接收用户注册表单中的`username`和`email`字段;最后,引入`joi`模块进行数据验证,确保数据安全准确。掌握这些技能有助于开发者构建更安全、友好的Web应用。随着Node.js和Express的不断进步,未来将有更多高级功能值得期待。
151 0
|
5月前
|
JavaScript 前端开发 API
解锁前端开发新境界:Vue.js携手Webpack,打造高效构建流程,你的项目值得拥有!
【8月更文挑战第30天】随着前端技术的发展,模块化与组件化趋势愈发显著。Vue.js 以其简洁的 API 和灵活的组件系统,深受开发者喜爱;Webpack 则凭借强大的模块打包能力成为前端工程化的基石。两者结合,不仅简化了组件编写与引用,还通过模块热替换、代码分割等功能大幅提升开发效率。本文将通过具体示例,展示如何利用 Vue.js 和 Webpack 构建高效、有序的前端开发环境。从安装配置到实际应用,逐步解析这一组合的优势所在。
58 0
|
6月前
|
前端开发 NoSQL 数据库
部署常用的流程,可以用后端,连接宝塔,将IP地址修改好,本地只要连接好了,在本地上前后端跑起来,前端能够跑起来,改好了config.js资料,后端修改好数据库和连接redis,本地上跑成功了,再改
部署常用的流程,可以用后端,连接宝塔,将IP地址修改好,本地只要连接好了,在本地上前后端跑起来,前端能够跑起来,改好了config.js资料,后端修改好数据库和连接redis,本地上跑成功了,再改

热门文章

最新文章