本文作者:溪岼
本文从应用角度动手,循序渐进的讲述 DrawIO 是什么,为什么要基于 DrawIO 进行二次开发以及 DrawIO 二次开发的外围技术细节并形象出了一套通用二开架构,因而文章内容较长,不同阶段的读者能够依据需要进行浏览。本文整体构造如下:
1 – DrawIO 二次开发需要背景 (一入 DrawIO 深似海)
2 – DrawIO 是什么以及应用办法简介 (揭开 DrawIO 的神秘面纱)
3 – DrawIO 二次开发的筹备阶段 (山重水复疑无路,老泪纵横的跑通 DrawIO 代码)
4 – DrawIO 二次开发的技术细节 (柳暗花明又一村,把握 DrawIO 外围二开代码)
5 – DrawIO 二次开发架构详解 (三省吾身,形象出通用的 DrawIO 开发架构)
背景
对于绘制各种图表,诸如流程图、原型图、拓扑图、UML 图以及思维导图等等,你是不是还在用微软性能宏大但必须下载客户端同时体积也很宏大的 Visio?抑或是你还在用 ProcessOn 免费版,十张图紧紧巴巴来回替换绘制,画完这张图下载下来删除再从新画另一张(当然如果你是氪金玩家,那么我只能说,大佬开心就好~)?在上述诸多问题的背景之下有了这篇文章,看完过后心愿不同读者可能失去相应播种。
- 单纯的应用人员,能够取得一个简略收费有限空间的高级绘图工具。
- 进阶的开发人员,能够为本人和团队非常简单疾速的搭建一个收费有限空间且功能强大的绘图工具。
- 高阶的二开人员(理解并尝试过 DrawIO 二开),能够把握一种新的二次开发模式,逐步成为捕鱼达人。
扯得这么高大上,弄的都有些不好意思了。从新论述一下起因就是目前笔者在云音乐次要负责的工作是晋升研发线效率,某天产品和后端同学提出了一个需要,大体上意思就是团队须要一个外部图表工具,这个图表工具能和现今公司工作流串联起来实现流程闭环,因为目前的工作模式就是产品 / 研发用 ProcessOn 或者其余绘图工具绘制图表后,截图 / 保留到本地而后再进行粘贴,因为 ProcessOn 有空间限度并且也不用所有人都开会员😂,因而还不如罗唆就外部搞一个了。
基于上述官网 / 非官方种种原因,笔者开始着手调研这个外部图表零碎的搭建,张望一圈之后最终确认技术选型 —— 以 DrawIO 为根底进行二次开发。
【留神】:本文前面对立将 二次开发 简称为 二开
目前来说这个绘图零碎的基本功能(绘制 / 存取等)曾经开发实现并内测应用中,并且笔者还为网站起了一个高端大气上档次的名字 —— Overmind-X Graph,一起来看看网站现阶段成果:
DrawIO 简介
既然是基于 DrawIO 进行二开,首先就来理解一下 DrawIO 到底是什么,跟着笔者视角先去 DrawIO 官网去看一圈,官网首页截图如下所示:
简要来说DrawIO 是一个反对绘制各种模式图表并且反对多地位存储能力的网站和工具。绘制图表的性能就不多说了,这也是 DrawIO 本身的外围性能,这里着重介绍一下 DrawIO 的多地位存储能力,通过 DrawIO 绘制的图表能够存在网络上的很多中央,比方:浏览器缓存、本机文件夹、近程存储(Github、Gitlab 和 Google Drive 等)。存储浏览器和本机文件夹很简略不做介绍,这里以 Github 为例简略解说一下通过 DrawIO 绘制的图表如何进行近程存储。
存储 DrawIO 到 Github 仓库
- 1 – 在 Github 新建一个仓库
这里笔者新建了一个名为 drawio-folder 的仓库,外面只有一个 README.md
文件,如下图所示:
- 2 – 绘图时抉择 GitHub 作为存储空间
而后从官网点击 Start 按钮进入绘图页面,第一次进入页面不出意外会呈现一个如下图所示抉择存储空间的选项,而后抉择 Github(其余近程存储原理一样)。
- 3 – 抉择对应的仓库而后绘制图片
点击抉择存储到 Github 仓库,而后抉择新建一个图表,命名之后点击新建 Create 按钮实现图表的创立。
- 4 – 受权选取存储仓库
图标创立胜利后,会呈现一个受权登录的弹窗,受权登录过后 DrawIO 就能获取到账户下的所有仓库信息,抉择方才创立的 drawio-folder 仓库,而后进行图表的绘制。
- 5 – 绘图结束保存文档
绘制过程中,每一次的保留操作,都会创立一条 commit message
,就相当于失常的仓库批改并提交,如下图所示:
当一次图表绘制实现并保留后,能够去 Github 仓库看看是否存储胜利。
能够看到,方才创立的图表曾经胜利存储到了 Github 仓库,十分的便捷,基本上就等于你曾经有了一个无限度的图表云盘一样。
至此置信大家应该曾经理解了 DrawIO 如何绘图以及它弱小的存储性能,在文章的结尾提到过,如果你是一个单纯的使用者,那么文章读到这里曾经足够了,你曾经领有了一个收费且弱小的绘图工具(不须要开明会员不须要注册也没有绘制数限度)以及很多类型的有限存储空间,相比还要免费的 Some Apps 它不香吗?
为什么要进行 DrawIO 二开
既然 DrawIO 自身曾经这么香了,为啥还要进行二开呢?在这简略总结几点为什么要进行二开或者可能须要进行二开的起因:
- 首先,对于一个团队来说须要的不仅仅是一个纯绘图工具,而是一个蕴含绘图性能的一体化治理平台,绘图只是其中最外围的局部,其余还有一些必不可少的性能。
- 其次,在一些非凡业务需要中,须要把图表和本身的业务联合起来以施展图表更大的能力或者基于业务进行非凡革新,这种场景的话二开就是必然的。
- 最初,就是所谓的逼格问题,直白点说就是能放到本人公司独立部署服务的,为啥放在里面?免费版万一有一天不收费了或者有限度了那就被动了。(尽管可能性极低,然而也要思考这种因素)
如果你或者你的团队也有下面几点起因,那么欢送持续往下看,接下来会介绍如何以 DrawIO 官网开源代码为根底进行简略的二次开发。
DrawIO 二开 —— 流程筹备
【留神】:本文次要针对前端开发者,然而在开发部署构建新版本的过程有很多依赖 Java 环境的内容,所以为了保障文章的连贯性,也会进行简略介绍,如果你曾经相熟相干环境配置,那么疏忽对应内容即可。
环境筹备
- 前端开发环境
这里就不多说啥了,其实 DrawIO 的开发还真就是齐全属于前端领域,所以各位前端同学如果遇到相似的需要,就迎难而上吧~
- 编译构建相干的环境 —— Java 和 Ant
对于 Java 和 Ant 两个环境的装置,这边以 MacOS 为例进行解说,其余零碎参考官网教程。
至于为啥要用到这俩,前面构建部署过程会介绍到,因为前端开发同学的电脑里大概率不会装置这俩,所以这里也简略讲一下装置步骤。
# jdk 下载地址
https://www.oracle.com/java/technologies/javase-jdk16-downloads.htmlt
# ant 下载地址
https://ant.apache.org/bindownload.cgi
对于 jdk 安装包下载完之后失常装置即可,测验是否装置胜利能够应用 javac
或者 java -version
命令来查看装置版本,之后将下载的 Ant 压缩包解压到 Applications 目录下,而后运行如下命令。
# 写入环境变量
sudo vim .bash_profile
# 这里留神,版本号和你本人下载的要对应上
export ANT_HOME=/Applications/apache-ant-1.9.16
export PATH=$ANT_HOME/bin:$PATH
# 退出并保留
:wq
# 让环境变量失效
source .bash_profile
# 查看版本
ant -V
装置实现之后能够在命令行验证是否装置胜利,如果命令行里呈现了如上图所示对应的 Java 和 Ant 版本信息,那么祝贺你 DrawIO 二开的根底环境曾经筹备实现,接下来就是正式进入 DrawIO 二开了。
DrawIO 源码
二开的开始,首先从 DrawIO 源码仓库 Clone 官网代码,在本地跑一下看看成果。老规矩 Clone 下来先浏览 package.json
文件,发现其中只有一个 start
命令。
"scripts": {"start": "electron ."}
理解前端的同学应该能晓得,此命令将会启动了一个 Electron 桌面利用,运行此命令过后不出意外的,一个桌面版 DrawIO 就出现在眼前了。
它的应用形式和下面文章里介绍的一样,然而问题来了!咱们最终目标是要进行 DrawIO 二开,难不成是基于 Electron 二开吗?尽管说也不是不行,然而那上手老本可就高了,预计会劝退一大波同学,不要慌,去官网仓库看看有没有其余办法。
功夫不负苦心人,如上图官网文档介绍了除了基于 Electron 部署利用外,DrawIO 还能以动态站的模式部署到 Github Pages,并且官网的站点地址点开后就更清晰了:https://jgraph.github.io/drawio/src/main/webapp/index.html
。从链接能够察看到其实 Github Pages 部署的站点就是 /src/main/webapp
这个文件夹,也就是 DrawIO 的动态站根目录,那么动态站的开发对于前端来说再相熟不过了,所以接下来所有的二开过程都是基于动态站的模式进行解说。
如果大家指标就是基于 Electron 构建桌面端利用,也能够对应的进行相应的二开,流程上和动态站的二开基本一致。开发模式的选型次要是通过剖析本人团队的业务诉求得出结论,因为网页类利用普适性比拟好并且没有那么多局限性,所以云音乐抉择的就是动态站的模式。
开发模式及预览
一个生疏的利用零碎或者框架怎么相熟最快,最简略的方法就是顺着入口文件一点一点的啃上来了,这与平时浏览源码的过程很相似,DrawIO 动态站的入口文件是 /src/main/webapp/index.html
,接下来从它动手,简略介绍一下如何在本地开发调试 DrawIO 代码。
- 第一步:新建
package.json
{
"name": "drawio-dev",
"version": "1.0.0",
"main": "src/main/webapp/index.html",
"scripts": {"start": "cd src/main/webapp && serve"},
"license": "MIT",
"dependencies": {"serve": "^12.0.0"}
}
首先,根目录新建一个 package.json
文件,而后键入如上内容,而后通过 yarn start
或者 npm run start
命令,就能很简略的在本地启动一个服务器,进行开发拜访,成果如下:
- 第二步:批改代码,开发模式预览
因为 DrawIO 我的项目的文件体系非常的宏大,这里不做过多介绍,次要给大家介绍一下二开过程中外围的一个文件目录 src/main/webapp/js/diagramly
,此文件夹内的文件是零碎运行最为外围的局部,二开的工作大部分也都是批改此文件夹的文件内容。
其中,src/main/webapp/js/diagramly/App.js
算是加载 DrawIO 的一个入口 js 文件,咱们在其中第一行键入一段代码:
很容易了解,就是 Alert 一个弹窗提醒测试一下代码是不是能失常执行,不过刷新页面之后会发现并没有看到这个弹窗,这是为什么呢?关上控制台找找起因:
发现加载的不是 app.js
而是 app.min.js
,看来默认加载的是生产版本的代码,那么如何执行开发代码进入开发模式呢?仔细阅读源码会发现,DrawIO 是通过辨认 url query 的 dev
参数来判断是不是开发模式(dev === 1
则为开发模式),那么加上这个参数再来试试:
到这里,笔者心田莫名呈现了几万头不出名的可恶动物,果然没有这么容易啊。没事,技术就是一个一直摸索的过程,心愿各位看官能和我一样不要放弃。
当然,看完本篇文章你们就曾经少走了 90% 的弯路,间接进行二开就能够了。
为啥会找不到文件呢?简略剖析一下,还是文件的指向问题:
在本地开发应该申请的是本地的资源文件,然而 Network 面板发现申请的资源地址并不对,废话不多说,再说下去可能大家心田也解体了,通过如下代码,把开发模式安顿明确。
// index.html 从 245 行开始
// Changes paths for local development environment
if (urlParams['dev'] == '1') {
...
// ====> 开发模式文件指向本地
if (location.hostname == 'localhost' || location.hostname == '127.0.0.1') {drawDevUrl = `http://${location.host}/`;
geBasePath = `http://${location.host}/js/grapheditor`;
mxBasePath = `http://${location.host}/mxgraph`;
mxForceIncludes = true;
}
// ====> 开发模式文件指向本地
mxscript(drawDevUrl + 'js/PreConfig.js');
mxscript(drawDevUrl + 'js/diagramly/Init.js');
mxscript(geBasePath + '/Init.js');
mxscript(mxBasePath + '/mxClient.js');
...
}
外围代码以及对应地位就在下面曾经给出了,批改过后间接刷新页面看一下成果:
能够看到,咱们心心念念的 Alert 弹窗曾经进去了,此时此刻,笔者曾经是老泪纵横了,到这里为止,DrawIO 二开的开发流程根本介绍实现,对于二开的更多细节如何去革新 DrawIO 就是各位依据本身团队的需要而定了。
构建生产版本
下面搞定了开发模式,实现了本地开发实时预览,然而最终公布的代码必定还是要用生产版本,后面也晓得了,生产版本应用的是诸如 app.min.js
这种压缩文件,那么如何把本地开发的代码打包编译为生产版本呢?这就要用到后面曾经装置好的 Java 和 Ant 环境了。
这里没有过多内容,非常简单的在 package.json
文件里减少如下代码即可:
{
"name": "drawio-dev",
"version": "1.0.0",
"main": "src/main/webapp/index.html",
"scripts": {
"start": "cd src/main/webapp && serve",
+ "build": "cd etc/build && ant"
},
"license": "MIT",
"dependencies": {"serve": "^12.0.0"}
}
减少完上述 build
命令之后运行一下,不出意外会呈现如下构建胜利的提醒:
而后再来拜访一下首页,这次不携带 dev=1
开发参数看看成果,如下图所示,十分完满的运行着新开发的生产版本,至此为止 DrawIO 的二开流程阶段,从开发预览到构件生产版本都曾经介绍实现。
部署
部署的话,其实就参考动态站部署就能够了,外围目录就是下面提到过的 src/main/webapp
。笔者在这里简略给各位提供几个部署思路:
- Github Pages(集体)
- Vercel(集体)
- Nginx(团队)
- Node Server(团队)
至于如何部署,各位依据本身或者团队理论状况进行抉择即可。
DrawIO 二开 —— 技术细节
笔者基于 DrawIO 开发的绘图管理系统在云音乐团队外部内测中,目前来说已实现的和正在开发中的功能集如下:
- [x] 根底图绘制性能
- [x] 基于云音乐外部服务的增删改查
- [x] 集体核心模块,治理本人的图表内容
- [x] 数据交互,图表与业务零碎进行数据交互,一键导入已创立的图表
- [] Todo – 鉴权性能,比方分享,指定权限的人能够进行相应操作
- [] Todo – 团队空间,一个团队能够治理一个图表的汇合
- [] Todo – 版本历史,反对查看最近几次的版本批改内容
- [] Todo – 自定义导入一些基于公司 / 集体比拟罕用的模板
因为本文还是偏技术向的文章,下面很多性能其实和 DrawIO 二开没啥太大的关系,都是一些基于业务的需要,所以不做过多细节介绍,笔者置信各位开发者 / 团队进行 DrawIO 二开的次要起因,80% 以上都是因为想要把内容保留到外部服务上,也就是说获取以后画板并依照肯定的模式保留在数据库里,这才是整个二开过程中最为外围的局部。这里以一个二开过程中的源码案例扩大讲一下 DrawIO 二开过程中的局部技术细节。
获取以后画板内容 —— getCurrentFile
那么如何获取以后画板内容呢?还是通过对 App.js
源码的浏览,我发现了如下这段代码:
App.prototype.save = function(name, done) {var file = this.getCurrentFile();
...
}
顾名思义,这段代码会在保留的时候执行,并且会获取到一个 file 文件对象,增加一个 log 后运行一下代码,看看成果:
能够看到,的确打印进去了一个 file 文件对象,对于对象外面的泛滥属性这里不一一阐明,只介绍一个最外围的 data
属性也就是文件数据,有了这个文件数据能做什么呢?别着急,接着往下看。
结构文件下载到本地
通过 getCurrentFile
咱们从画布获取到了以后正在绘制的图表数据,看内容是一段 xml 字符串,接下来就通过这个字符串反向结构一个文件下载下来,看看是不是和画布上的那个图表截然不同。此处通过 filesaver
将结构的文件数据进行下载,外围代码如下:
/**
* 结构文件下载到浏览器
**/
function download() {
const fileObj = {
title: 'luffyzh.drawio',
data: '<mxfile host="localhost"modified="2021-09-02T09:50:39.574Z"agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"etag="PyBU88KGLdBE5FU7fpPf"version="@DRAWIO-VERSION@"type="device"><diagram id="C5RBs43oDa-KdzZeNtuy"name="Page-1">7VhZc5swEP41PLbD4WDnsThx0tbNpE3aTB9lkIVqwVIhfOTXdzHCgPH4aOscnvjBo12WlbTft4dtOP1ofiVJEn6BgArDNoO54VwYtn3WNfE7VywKhduzCwWTPChUVqW4449UK/V7LOMBTRuGCkAonjSVPsQx9VVDR6SEWdNsDKK5a0IYbSnufCLa2gceqLDQ9uxupb+mnIXlzpZ7XjyJSGmsb5KGJIBZTeVcGk5fAqhiFc37VOSxK+Py8HHxIIYT9+rT1/Q3+e59vr/58a5wNjjkldUVJI3V/3WtsZwSkel46buqRRlACVkc0NyJaTheqCKBSwuXv6hSCw04yRSgCqQKgUFMxBAg0XZjiJU2s3KZxsGHHFiURwL8SaEacCH0Hihp+x5KqZIwWWGXO1gBkRsLMqLCI/6ELQ/aBwESH8UQ09xVgGTQd6kOd1lpvT1jqzFIIZM+3WLnaIoTyeg2f25hl5+vxlON3BWFiCq5QANJBVF82iQz0TnBVnYV7rjQ0B9AA6dFA5GNx4vHcAsbciRmIVf0LiHLkMywfjQZUkceL+cxQdJU47YD1sNgmVKp6HxrIMunrs5mXc56WpxVtcEqEz6s1YWOeaTQd1qh/4nl8i0J/yUJ3T2TsOxRO7NQk6Ukxt5JqT3dAsd7VSYwHqd4sHXqrDb8ezadtdh0Ay0y7cbjVdPtmcjUPYxL1ovnktvi0pBEiWG7AsPgjSSuWL5KRMYYkgXdxYYzaNeuEKJRlu5uFw2McwYNSMRFHq9rKqZUcZ9saCpEcIb7XvgIN5WbyYNb8pih5FbS/ZKsWH+P2Gy6zWazkuvdxtzQbXrH6jbdFqa3iF4BnW2KJb4n1vEdew2E8+du+b19ivSrLsFP3vHLarq75Vt7lmnNHvO9g58GgV7+FHC+10z5NgYch2H2qQ0C5QlrfPIyMWpPAqNMxstBADL1NglsmwTsTU3oSSeBshDWQP1GE8IRTHN4inPA+i//jvPcc0BZKZoQiDymtllk2IlhsD6LOdbxMECx+m+2KIXVH9zO5R8=</diagram></mxfile>'
}
const blob = new Blob([fileObj.data], {type: 'application/octet-stream'});
saveAs(blob, fileObj.title);
}
从代码和截图成果能够得出结论:通过 getCurrentFile
获取到图表外围数据 data,就能很容易的反向结构进去一个 .drawio 文件也就是绘图文件,并且和画布上的文件截然不同(感觉本人如同在说废话,当然截然不同了,数据都是一样的他不一样可就奇怪了)。
将保留的图表数据绘制到画布上 —— loadFile
下面的两步咱们确定了画布数据的获取以及数据是否能反向结构进去图表文件,由此确定了技术计划的可行性,然而其实还差最初一个环节 —— 加载图表数据到画布上,因为你的图表不仅仅能保留,还须要能持续编辑,因而把数据从文件里获取进去而后反向结构成图表数据并加载到画布上,这才实现了一个 DrawIO 二开的最小闭环。这里不做过多废话,外围 API — loadFile
,细节代码如下:
if (this.editor.isChromelessView()) {...}
/**
* 如果有 id,示意关上了一个存在的文档,进入编辑模式
*/
else if (urlParams['id']) {
const mockFile = {
title: 'luffyzh.drawio',
data: '<mxfile host="localhost"modified="2021-09-02T09:50:39.574Z"agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"etag="PyBU88KGLdBE5FU7fpPf"version="@DRAWIO-VERSION@"type="device"><diagram id="C5RBs43oDa-KdzZeNtuy"name="Page-1">7VhZc5swEP41PLbD4WDnsThx0tbNpE3aTB9lkIVqwVIhfOTXdzHCgPH4aOscnvjBo12WlbTft4dtOP1ofiVJEn6BgArDNoO54VwYtn3WNfE7VywKhduzCwWTPChUVqW4449UK/V7LOMBTRuGCkAonjSVPsQx9VVDR6SEWdNsDKK5a0IYbSnufCLa2gceqLDQ9uxupb+mnIXlzpZ7XjyJSGmsb5KGJIBZTeVcGk5fAqhiFc37VOSxK+Py8HHxIIYT9+rT1/Q3+e59vr/58a5wNjjkldUVJI3V/3WtsZwSkel46buqRRlACVkc0NyJaTheqCKBSwuXv6hSCw04yRSgCqQKgUFMxBAg0XZjiJU2s3KZxsGHHFiURwL8SaEacCH0Hihp+x5KqZIwWWGXO1gBkRsLMqLCI/6ELQ/aBwESH8UQ09xVgGTQd6kOd1lpvT1jqzFIIZM+3WLnaIoTyeg2f25hl5+vxlON3BWFiCq5QANJBVF82iQz0TnBVnYV7rjQ0B9AA6dFA5GNx4vHcAsbciRmIVf0LiHLkMywfjQZUkceL+cxQdJU47YD1sNgmVKp6HxrIMunrs5mXc56WpxVtcEqEz6s1YWOeaTQd1qh/4nl8i0J/yUJ3T2TsOxRO7NQk6Ukxt5JqT3dAsd7VSYwHqd4sHXqrDb8ezadtdh0Ay0y7cbjVdPtmcjUPYxL1ovnktvi0pBEiWG7AsPgjSSuWL5KRMYYkgXdxYYzaNeuEKJRlu5uFw2McwYNSMRFHq9rKqZUcZ9saCpEcIb7XvgIN5WbyYNb8pih5FbS/ZKsWH+P2Gy6zWazkuvdxtzQbXrH6jbdFqa3iF4BnW2KJb4n1vEdew2E8+du+b19ivSrLsFP3vHLarq75Vt7lmnNHvO9g58GgV7+FHC+10z5NgYch2H2qQ0C5QlrfPIyMWpPAqNMxstBADL1NglsmwTsTU3oSSeBshDWQP1GE8IRTHN4inPA+i//jvPcc0BZKZoQiDymtllk2IlhsD6LOdbxMECx+m+2KIXVH9zO5R8=</diagram></mxfile>'
}
const file = new LocalFile(this, mockFile.data, mockFile.title, this.mode);
this.loadFile(`-1`, true, file);
}
else if (!mxClient.IS_CHROMEAPP && (this.mode == null || force)) {...}
下面代码进入页面的时候会判断链接上是否携带参数 id
,如果携带那么就会结构一个简略的 DrawIO 文件数据对象,之后再通过 loadFile
这个办法把文件绘制到画布上,具体成果如下图所示:
基于此案例基本上就能把整个 DrawIO 二开的外围技术细节解说结束了,整个二开流程也能够很清晰的串联起来了,置信各位脑海中曾经有了本人的宏伟蓝图,那么就能够把想法付诸于理论了。
如果想理论拜访一下体验一下成果,笔者这边简略部署了一个个人版 DrawIO,大家能够通过如下链接进行拜访:
- 个人版 DrawIO
- DrawIO 文件下载
- DrawIO loadFile 加载文件
DrawIO 二开 —— 外围架构
后面讲了很多开发流程并附带踩坑细节,那么笔者除了帮大家踩坑之外,针对近期的 DrawIO 二开经验也进行了一些总结并且设计了一个 DrawIO 二开的开发架构,上面就简略介绍一下这个架构的设计过程。
其实 DrawIO 二开更多的是开发一个以绘图性能为外围的闭环零碎,因而除了根本的绘图性能外,如何奇妙的把 DrawIO 绘图性能整合到零碎里才是最为要害的局部,对于此我总结了三种架构模式:
架构一 —— 繁多动态站模式
繁多动态站模式 整体架构如上图所示,整个架构就是以 DrawIO 动态站目录 src/main/webapp
为根目录,依照最原始的动态站开发模式进行开发。其中入口文件是 index.html
,加载绘图相干的外围依赖 js
文件,实现绘制性能,其余性能页面和绘图页面也没什么耦合逻辑,就能够在工程目录里新建几个 html
文件,一个 html
文件对应一个性能,来进行我的项目的开发迭代。比方,首页就是 home.html + home.js
,列表页就是 list.html + list.js
等,所有开发都回归到最原始前端开发模式 — HTML + JavaScript + CSS
。
长处: 逻辑简略易懂,基于 DrawIO 源码仓库目录进行增量开发,易上手
毛病: 原始的开发模式带来的就是效率低下,原生开发模式没有应用风行的框架和打包工具,不太合乎古代的开发模式。
架构二 —— 双系统模式
基于第一种动态站架构模式分析能够得悉,该种模式其实不是很合乎现今前端的开发节奏,原始的形式效率低下是最为致命的,那么革新后就造成了第二种架构模式 —— 双系统模式。此模式下有两个零碎:DrawIO 绘图零碎和兄弟业务零碎,其实在整个零碎里,外围的绘图性能和其余的业务需要是能够齐全解藕的,那么就能够把与绘图无关的业务抽离进去独自造成一个零碎,并且这个零碎能够采纳古代的开发模式进行开发,并且兄弟零碎的架构选型也没有任何限度,想用什么开发就用什么开发。
长处: 双系统互相独立互不影响,兄弟业务零碎还能够用最新的框架和技术,晋升效率。
毛病: 开发迭代须要保护两个零碎,两个域名两套环境减少保护老本。
架构三 —— 非凡单零碎模式
由下面两种架构剖析得悉,架构一因为原始的开发模式导致开发复杂度回升,架构二通过解藕造成双系统晋升开发效率然而引入了保护双系统的额定老本导致治理复杂度回升。因而把两个架构的优缺点进行整合,最初造成了第三个架构 —— 非凡单零碎模式。这种架构联合了下面两个架构的长处,并且通过一些特地的计划晋升了 开发效率,架构图如下图所示:
上面着重解说一下这个非凡单零碎架构是如何解决下面提到的开发和治理复杂度问题的。
解决开发复杂度其实很简略,引入一个适合的现代化框架就能够了,在这里我引入的是 Next.js,为什么引入 Next.js 而不是其余的现代化框架呢?起因有如下三点:
- 首先,它是基于 React.js 的 SSR 框架,因而合乎古代框架晋升开发效率的要求。
- 其次,Next.js 自带很多个性能够帮忙解决治理复杂度,前面会讲到。
- 最初,笔者集体十分喜爱 Next.js,这个理由是最充沛的。
上面是整个架构的外围 package.json
文件的局部代码,其实没很多天花乱坠的简单操作,就是通过几个命令帮忙开发者把绘图零碎和业务零碎桥接起来造成一个内部看起来绝对对立的零碎,因为是基于古代模式桥接而成的非凡单零碎,因而开发部署就都十分的容易了。
{
"name": "overmind-x-graph",
"version": "0.1.0",
"author": "luffyZh <zhoudeyou@126.com>",
"keywords": ["drawio", "react", "next.js"],
"scripts": {
"start": "next dev",
"build": "next build",
"prod": "next start",
"drawio-dev": "cd drawio-project/src/main/webapp && serve",
"drawio-build": "source ~/.bash_profile && cd drawio-project/etc/build && ant",
"gen-drawio": "rm -rf public/drawio && cp -r drawio-project/src/main/webapp public/drawio",
"analyze": "ANALYZE=true next build",
...
},
...
}
脚本命令阐明
yarn drawio-dev
—— 开发模式调试 DrawIO 绘图零碎
这个命令就是帮忙开发者进入绘图零碎的开发模式,虽说把两个零碎桥接到一起,然而在开发的时候还是倡议把绘图零碎当成一个独立零碎去对待,并且在 DrawIO 二开过程中波及的改变绘图源码的局部都是在绘图零碎里实现的,所以 DrawIO 绘图零碎的开发模式十分重要。
yarn drawio-build
—— 编译 DrawIO 零碎
在 DrawIO 二开结束或者阶段性测试部署的时候,须要把开发环境批改的文件构建成生产环境的版本,此时应用此命令即可实现构建工作。
yarn gen-drawio
—— 同步最新绘图零碎到主零碎
如何桥接绘图零碎与业务零碎?就是通过这个命令来实现,绘图零碎被当做一个独自的子系统进行开发和编译,编译实现后只须要执行此命令把主零碎所需的绘图系统核心文件拿过去即可。
next.config.js
—— 主零碎配置文件,桥接子系统
const fs = require('fs');
const path = require('path');
...
module.exports = {
reactStrictMode: true,
// 重写 DrawIO 动态站地址,桥接奴才零碎
rewrites: async () => drawioPaths,};
那么主零碎是通过何种形式实现绘图零碎与业务零碎的桥接呢?答案就是通过 Next.js 的 Rewrites 个性,感兴趣的能够去查阅官网文档,正是因为这个个性才使得单零碎进行 DrawIO 二开变成了可能并且开发起来也十分便当,桥接双系统让整个工程对外造成一个独立残缺零碎 算是这个架构的外围之处。
这里多说一句,可能大家乍看之下不会感觉到啥,然而这个架构的最终敲定的确是笔者通过一直的开发尝试才敲定下来的,感兴趣的能够去跑一下代码去理论体验一下。另外抉择一个适宜你本人的框架就行了,不肯定非得是 Next.js,如果你是基于 Vue 的开发者,那么 Nuxt 是不是就在那里静静地等着你呢?本文只是提供一个思路,各位能够发散思路,毕竟本人摸索的过程才更有意思。
讲这么多其实都帮各位看官筹备好了,基于 架构三 搭建了一个脚手架 simple-drawio-starter,大家间接拿来进行业务逻辑的开发即可。
总结
DrawIO 功能强大的同时整个源码的文件体系结构也非常宏大简单,因而读起来还是颇费些功夫,从确立需要到浏览源码再到最初二开总结架构,一不小心就写成了万字长文,心愿本文能对那些有相似需要或者想要做一个相似工具的敌人提供一些帮忙,其实 DrawIO 的开发难点也就是在于相干的技术文档比拟少,社区大部分都是应用教程而不是二开教程,难以找到一个好的入门开发文档算是笔者写这篇文章的一个初衷,也是心愿大家能少走些弯路。
最初,非常感谢各位急躁地浏览完本篇文章,如果在 DrawIO 开发过程有更好的见解和思路欢送留言交换,不胜感激~
本文公布自 网易云音乐大前端团队,文章未经受权禁止任何模式的转载。咱们长年招收前端、iOS、Android,如果你筹备换工作,又恰好喜爱云音乐,那就退出咱们 grp.music-fe(at)corp.netease.com!