大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
高级前端进阶
今天给大家带来的主题是js2flowchart,即一个将JS 代码转化为可视化流程图的利器。以前我也有突发奇想,想要做一个类似的功能,但是因为种种原因一直没有完成。昨天在前端论坛闲逛,看到已经有人做出来了,觉得非常不错,特意分享给大家,希望大家有用。
话不多说,直接进入正题。
前言
js2flowchart 是一个开源库,接受任何 JS 代码并从中生成 SVG 流程图,支持在客户端和服务端工作。 js2flowchart 允许开发者轻松为上下文调整样式方案或从不同的抽象级别演示代码逻辑。 同时支持诸多特性,比如:高亮显示、解构整个代码块、按需自定义修饰符等。
下面是来自官网对 js2flowchart 的描述,不仅可用于设计自己的代码还能用于快速可视化、了解其他开发者的代码,看起来确实是不错,是不是迫不及待想要尝试下。
js2flowchart - a visualization library to convert any JavaScript code into beautiful SVG flowchart. Learn other’s code. Design your code. Refactor code. Document code. Explain code.
目前 js2flowchart 在 Github 上已经通过 MIT 协议开源,有超过6.8k的star、0.5k的fork、妥妥的一个优秀前端开源项目,值得大家持续关注。
1.js2flowchart 有什么用
js2flowchart 获取 JS 代码并返回 SVG 流程图,适用于客户端/服务器,同时支持 ES6。主要特点包括以下几个点:
- 支持定义抽象级别以仅渲染导入/导出、类/函数名称、函数依赖性以逐步学习/解释代码。
- 支持创建自己的抽象级别
- 表示生成器以生成 SVG 列表以达到不同的抽象级别
- 定义流树修饰符(flow tree modifiers)以映射众所周知的 API,例如 [].map、[].forEach、[].filter 到方案上的循环结构等。
- 销毁修饰符用方案中的一种形状替换代码块
- 支持自定义流树修改器
- 支持过滤器忽略一些代码节点,即日志行
- 焦点节点或整个代码逻辑分支以突出方案中的重要部分
- 模糊节点或整个代码逻辑分支以隐藏不太重要的东西
- 支持定义样式主题
- 支持创建自己的主题,更适合开发者自己的上下文颜色
- 自定义颜色和样式支持提供方便的 API 来更改特定样式而无需样板
js2flowchart 的典型用例包括:
- 通过流程图解释/记录代码
- 通过视觉理解学习别人的代码
- 为由有效的 JS 语法简单描述的任何过程创建流程图
2.使用 js2flowchart
通过 CLI 使用
js2flowchart 是一个从 JavaScript 代码生成漂亮的 SVG 流程图的工具。 需要首先安装相应的 NPM 包:
yarn add js2flowchart
// 或者
npm install js2flowchart
也可以使用 CLI 工具从本地 JS 文件简单地生成 SVG 文件,但是也需要首先安装:
yarn global add js2flowchart
// 在一个项目中可以运行下面代码
yarn add js2flowchart --dev
打开终端并导航到包含要可视化的 JS 文件的所需目录(例如“./my-project/main.js”)。运行如下命令:
js2flowchart main.js
或者将下面内容添加到 package.json 文件中:
{
"scripts": {
"js2flowchart": "js2flowchart"
}
}
然后运行(使用 npm 或 yarn):
yarn run js2flowchart main.js
执行脚本后观察日志 SVG 文件已创建:
./js2flowchart/main.js.svg。 SVG 文件将放置在 JS 文件附近的新目录 /js2flowchart 中。
通过 API 调用
js2flowchart 也支持通过 API 直接调用,比如下面是经典的二分搜索(Binary search)的代码功能:
const code = `function indexSearch(list, element) {
let currentIndex,
currentElement,
minIndex = 0,
maxIndex = list.length - 1;
while (minIndex <= maxIndex) {
currentIndex = Math.floor(minIndex + maxIndex) / 2;
currentElement = list[currentIndex];
if (currentElement === element) {
return currentIndex;
}
if (currentElement < element minindex='currentIndex' 1 if currentelement> element) {
maxIndex = currentIndex - 1;
}
}
return -1;
}`;
然后通过下面的方法进行转换:
const svg = js2flowchart.convertCodeToSvg(code);
生成的结果如下:
如果需要修改默认行为,可以将
js2flowchart.convertCodeToSvg 拆分为两个构建块:
- 流树构建 (flow tree building)
- 图格式化(shapes printing)
const { convertCodeToFlowTree, convertFlowTreeToSvg } = js2flowchart;
const flowTree = convertCodeToFlowTree(code);
const svg = convertFlowTreeToSvg(flowTree); //XML string
或者需要完全控制时手动创建主实例:
const { createFlowTreeBuilder, createSVGRender } = js2flowchart;
const flowTreeBuilder = createFlowTreeBuilder(),
svgRender = createSVGRender();
const flowTree = flowTreeBuilder.build(code),
shapesTree = svgRender.buildShapesTree(flowTree);
const svg = shapesTree.print(); //XML string
形状树编辑器
js2flowchart 有一个用于修改名为 ShapesTreeEditor 的形状树的子模块。它提供了以下接口:
- findShape
- applyShapeStyles
- blur
- focus
- blurShapeBranch
- focusShapeBranch
下面通过一个例子来学习它的用法。
const code = `
const doStuff = (stuff) => {
if (stuff) {
if (devFlag) {
log('perf start');
doRecursion();
log('perf end');
return;
}
doRecursion();
end();
} else {
throw new Error('No stuff!');
}
return null;
};
`;
比如想要“模糊”开发分支条件,因为它会干扰代码的可读性,可以通过下面的代码来完成:
const {
convertCodeToFlowTree,
createSVGRender,
createShapesTreeEditor,
} = js2flowchart;
const flowTree = convertCodeToFlowTree(code),
svgRender = createSVGRender();
shapesTree = svgRender.buildShapesTree(flowTree);
const shapesTreeEditor = createShapesTreeEditor(shapesTree);
// 模糊分支
shapesTreeEditor.blurShapeBranch((shape) => shape.getName() === '(devFlag)');
const svg = shapesTreeEditor.print();
此时生成的图如下:
流树修改器(Flow tree modifier)
有一个名为 FlowTreeModifier 用于修改流树的子模块,它允许开发者将单独定义的修饰符应用于现有的流树。比如开发者想更改树节点上的“名称”(标题),只需为此定义修饰符即可。
一起看一下 ES5 数组迭代器,例如 forEach、map 等,它们的行为就像一个循环,下面让我们将它们视为一个“循环”。
const code = `
function print(list) {
const newList = list.map(i => {
return i + 1;
});
newList.forEach(i => {
console.debug('iteration start');
console.log(i);
console.debug('iteration end');
});
}
`;
const {
createFlowTreeBuilder,
createFlowTreeModifier,
convertFlowTreeToSvg,
MODIFIER_PRESETS,
} = js2flowchart;
const flowTreeBuilder = createFlowTreeBuilder(),
flowTree = flowTreeBuilder.build(code);
const flowTreeModifier = createFlowTreeModifier();
flowTreeModifier.setModifier(MODIFIER_PRESETS.es5ArrayIterators);
flowTreeModifier.applyToFlowTree(flowTree);
const svg = convertFlowTreeToSvg(flowTree);
如您所见,两个迭代器都被作为循环处理,并且 forEach 也省略了函数回调,如下图:
3.本文总结
本文主要和大家介绍 js2flowchart,即一个将JS 代码转化为可视化流程图的利器。相信通过本文的阅读,大家对 js2flowchart 会有一个初步的了解。
因为篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!
参考资料
https://github.com/Bogdan-Lyashenko/js-code-to-svg-flowchart
https://www.npmjs.com/package/js2flowchart
https://codesandbox.io/examples/package/js2flowchart
https://jquery-plugins.net/js2flowchart-generating-svg-flowcharts-from-javascript-code
https://www.cssscript.com/svg-based-js-code-flowchart-generator-js2flowchart/