1. 前言
状态机的一大好处就是可以可视化状态,降低业务的理解成本和相互间的沟通成本。
目前 XState 官方提供的可视化工具已经做的很不错了,但用起来偏重,国内访问也比较慢。这边我再原基础上进行了优化,并增加了部分新功能,开发了 Viz-Lite 版。
2. Viz-Lite
Viz-Lite 可视化工具地址

主要有如下功能:
- 直接在右侧区域进行编写或粘贴 XState 状态机代码,右侧进行可视化。
- 可以在左侧可视化区域通过点击进行状态机执行。
- 可以在右侧事件面板中查看事件历史,且可以手动进行自定义事件发送。
- 可以通过
@xstate/inspect与页面中的状态机实时建立连接,可视化查看当前页面状态机细节。 - 可以将可视化出来的状态图进行图片导出。
- 可以切切亮/暗色。
等等。
3. Inspect 底层实现
Viz-Lite 可以实时与页面中的状态图建立数据连接,需要依赖 @xstate/inspect,且在页面、Inspect、Viz-Lite 建立有严格的依赖关系。
我大致梳理了一下三者的关系,如下的序列图所示:
类似于 HTTP 三次握手。
在 Viz-Lite 中建立连接主要依靠 @xstate/inspect 的 createWindowReceiver 方法。
Viz-Lite 向 页面状态机发送事件,可以使用 createWindowReceiver 返回值中的 send 方法,消息体中 type 必须是 xstate.event。
页面中状态机的变化,可以通过 createWindowReceiver 返回值中的 subscribe 方法进行订阅,包括 service.state 和 service.event。监听 service.stop 可以确定连接的断开。
4. 接入调试方法
安装 @xstate/inspect:
npm i -S @xstate/inspect
从上面的序列图中也可以看出,inspect 必须在 interpret() 之前执行,不然无法连接:

import { inspect } from '@xstate/inspect';inspect({url: 'https://apis.leping.fun/viz?inspect',iframe: false
});
url中指定 Viz-Lite 的地址https://apis.leping.fun/viz?inspect。iframe指定在哪里挂载 Viz-Lite。可以直接指定一个 DOM,也可以设置为false,浏览器会打开一个新页面。
注意:调试模式,必须在 Viz-Lite 的地址中加上
?inspect。如果想默认关闭右侧面板可以加上?inspect&panel=false。
然后在创建状态机服务时,指定 devTools 标志位就可以了:
import { interpret } from 'xstate';const service = interpret(someMachine, { devTools: true });
可以访问这个 地址 查看效果:

Github 代码地址
5. 快捷键
+ / -或者CMD + 滚轮上/下:缩放。CMD + Enter: 可视化当前代码。↑↓←→:平移视图。同时按住Shift,增大平移服毒。Shift + 1:适配到到窗口大小。
6. 配合 Redux DevTools 使用
从序列图中可以看到在开启 devTools: true 的时候,会判断是否有 __REDUX_DEVTOOLS_EXTENSION__,如果有的话也可以在 Redux DevTools 中查看事件信息,如下图所示:

⭐ 原文地址