基於Bpmn-js的流程設計器校驗實現

bpmnlint簡介

它根據一組已定義的規則來驗證您的圖表,並將其報告爲錯誤或警告。它能夠從命令行檢查您的BPMN圖,或者經過bpmn-js-bpmnlint將其集成到咱們的BPMN建模器中node

核心規則

庫的核心是用於檢測BPMN圖中某些模式的規則。每一個規則都是由一段代碼定義的,該代碼能夠檢測並報告從丟失標籤到檢測到特定的易於出錯的建模模式這一事實。webpack

爲了讓您更好地瞭解規則多是什麼,這是到今天爲止內置在庫中的規則列表git

規則名稱 描述
conditional-flows 報告缺乏條件的外向流。
end-event-required 報告缺乏的結束事件。
fake-join 報告實際上爲空的隱式鏈接。
label-required 報告缺乏的標籤。
no-complex-gateway 報告複雜的網關。
no-disconnected 報告未鏈接的元素。
no-gateway-join-fork 報告同時分叉和加入的網關。
no-implicit-split 報告隱式拆分。
no-inclusive-gateway 報告包含的網關。
single-blank-start-event 報告範圍中的多個空白開始事件。
single-event-definition 報告具備多個定義的事件。
start-event-required 報告缺乏的開始事件。

從零到bpmnlint

讓咱們對bpmnlint的配置和可擴展性有更好的瞭解。首先,簽出並運行bpmnlint-playground,這是一個專門設計用於模型驗證項目的項目。github

git clone git@github.com:bpmn-io/bpmnlint-playground.git

cd bpmnlint-playground

npm install
npm start
複製代碼

執行時,npm start將打開帶有瀏覽器應用程序的瀏覽器窗口,該應用程序已支持了lint支持。web

配置可用規則

一個.bpmnlintrc擺在當前工做目錄定義文件,它的規則來適用,以及是否將其看成錯誤或警告。操場上拿着一個.bpmnlintrc看起來像這樣的東西:正則表達式

{
  "extends": [
    "bpmnlint:recommended",
    "plugin:playground/recommended"
  ],
  "rules": {
    "playground/no-manual-task": "warn"
  }
}
複製代碼

extends塊告訴bpmnlint從兩個預約義的規則集繼承配置:bpmnlint:recommendedplayground/recommended,後者由遊樂場插件提供。npm

rules塊會覆蓋特定規則的報告。該示例將設置playground/no-manual-task爲警告(而不是錯誤)。咱們能夠選擇任何規則,例如內置規則,也能夠徹底將其關閉:json

{
  ...
  "rules": {
    ...
    "bpmnlint/label-required": "off"
  }
}
複製代碼

在運動場應用程序中,咱們能夠看到短絨棉再也不報告沒有標籤的開始事件。瀏覽器

建立自定義規則

自定義現有規則的報告很是有用,可是並不能知足每一個用例。有時,用戶或組織但願識別與他們的特定建模樣式相關的領域特定模式。bpmnlint經過容許您貢獻自定義規則和規則集來解決此問題。測試

例如,若是咱們要制定一個規則來強制每一個流節點的標籤中包含表情符號,該怎麼辦?讓咱們跳入「遊樂場」 plugin文件夾emoji-label-requiredrules/emoji-label-required.js文件中建立規則:

const {
  isAny
} = require('bpmnlint-utils');

const emojiRegex = require('emoji-regex');

/** * Detect and report missing emojis in element names. */
module.exports = function() {

  function check(node, reporter) {
    if (isAny(node, [
      'bpmn:FlowNode',
      'bpmn:SequenceFlow',
      'bpmn:Participant',
      'bpmn:Lane'
    ])) {

      const name = (node.name || '').trim();

      if (!emojiRegex().test(name)) {
        reporter.report(node.id, 'Element must have an emoji');
      }
    }
  }

  return {
    check
  };
};
複製代碼

該規則公開了check(node, reporter)僅在BPMN標籤缺乏表情符號時才報告的功能。該表情符正則表達式實用程序將執行咱們的檢查。咱們必須將其做爲依賴項安裝在插件目錄中,以使規則運行:

cd plugin
npm install emoji-regex
複製代碼

而後,咱們須要調整配置以使用該emoji-label-required規則。因爲這不是一個內置規則,所以咱們爲其添加前綴(在本例中爲playground):

{
  "rules": {
    ...
    "playground/emoji-label-required": "error"
  }
}
複製代碼

回到操場上的應用程序,短毛貓如今將報告沒有表情符號的標籤錯誤:

img
驗證標籤中表情符號的存在。

這就完成了咱們對bpmnlint可擴展性的快速瞭解。

查看包含表情符號標籤的「遊樂場」 分支,該分支包含此博客文章中描述的實現。要了解有關規則打包和測試的更多信息,請查看示例插件

以上是bpmn官方教程

第一種方案

1.下載依賴

在package.json中加入以下依賴

"bpmnlint": "^6.4.0",
"bpmn-js-bpmnlint": "^0.15.0",
"bpmnlint-loader": "^0.1.4",
"file-drops": "^0.4.0",
複製代碼

2.新建規則文件

在項目中新建.bpmnlintrc文件,並使用該extends塊從通用配置繼承:

{
  "extends": "bpmnlint:recommended"
}
複製代碼

使用rules塊添加或自定義規則:

{
  "extends": "bpmnlint:recommended",
  "rules": {
    "label-required": "off"
  }
}
複製代碼

3.在中配置加載程序webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.bpmnlintrc$/,
        use: [
          {
            loader: 'bpmnlint-loader',
          }
        ]
      }
    ]
  }
};
複製代碼

這將確保您的構建可使用bpmnlint配置文件

4.將linter集成到bpmn-js中

import lintModule from 'bpmn-js-bpmnlint';

import BpmnModeler from 'bpmn-js/lib/Modeler';

import bpmnlintConfig from './.bpmnlintrc';

var modeler = new BpmnModeler({
  linting: {
    bpmnlint: bpmnlintConfig
  },
  additionalModules: [
    lintModule
  ]
});
複製代碼

若是在項目運行報錯提示.bpmnlintrc沒法識別,可使用第二種解決辦法

第二種方案

在第一種方案的基礎上添加以下依賴:

npm i -g bpmnlint bpmnlint-pack-config
複製代碼

而後在命令行中執行:

bpmnlint-pack-config -c .bpmnlintrc -o packed-config.js -t es
複製代碼

生成packed-config.js文件

以後就是一樣的方式,將規則文件引入bpmn-js

import * as bpmnlintConfig from './packed-config';

var modeler = new BpmnModeler({
  linting: {
    bpmnlint: bpmnlintConfig
  },
  additionalModules: [
    lintModule
  ]
});
複製代碼

轉化成packed-config.js文件的好處就是能夠本身寫邏輯

好比我將規則翻譯成了中文;好比我加入了:若是畫布中拖入了用戶任務,用戶任務就必須有左右鏈接線,不能單獨存在畫布中。

可控制是否校驗

import fileDrop from 'file-drops';

var modeler = new BpmnModeler({
    linting: {
        bpmnlint: bpmnlintConfig,
        active: that.getUrlParam('linting')
    },
    additionalModules: [
        lintModule
    ],
});

modeler.on('linting.toggle', function(event) {
    const active = event.active;
    that.setUrlParam('linting', active);
});

const dndHandler = fileDrop('Drop BPMN Diagram here.', function(files) {
    this.bpmnModeler.importXML(files[0].contents);
});
document.querySelector('body').addEventListener('dragover', dndHandler);


// 流程校驗使用
setUrlParam = (name, value) => {

    var url = new URL(window.location.href);

    if (value) {
        url.searchParams.set(name, 1);
    } else {
        url.searchParams.delete(name);
    }

    window.history.replaceState({}, null, url.href);
}
// 流程校驗使用
getUrlParam = (name) => {
    var url = new URL(window.location.href);

    return url.searchParams.has(name);
}
複製代碼

主要代碼就是這部分,最終效果圖以下:

可參考項目:

相關文章
相關標籤/搜索