故事的开端非常简单:我需要为我们的项目绘制一张清晰的架构图,用来展示几个核心服务之间的调用关系。在尝试了多种工具后,我突发奇想,决定让 AI 来帮我生成一个初步的设计。
结果出乎意料地好!AI 生成的不仅是静态的图片,更给了我一个动态时序图的灵感——如果能让这张图“动起来”,岂不是能更直观地展示数据流和系统交互的过程?
这个想法让我兴奋不已。一个通用的、可交互的 React 时序图组件,这似乎是一个很酷的挑战。于是,@sharp9/react-sequence-diagram
的雏形就此诞生。
要实现一个功能完善的时序图组件,以下几个核心要素是必不可少的。
时序图的主体是各个参与者(例如服务、用户或系统)。我将参与者的定义抽象为一个简单的 Actor
接口,允许用户自定义名称、标签、颜色,甚至是图标。
export interface Actor {
name: string; // 名称,如 "UserService"
label: string; // 显示的标签,如 "用户服务"
color: string; // 背景颜色 (Tailwind CSS)
icon: React.ReactNode; // React 图标组件
}
在组件中,我们只需要传入一个 Actor
数组,组件就会自动渲染出所有的参与者,并为它们分配好位置。
时序图的灵魂在于消息的传递。我设计了一个 Step
接口来描述每一步交互:
export interface Step {
from: number; // 消息发送方 (Actor 的索引)
to: number; // 消息接收方 (Actor 的索引)
message: string; // 消息内容
type: "request" | "response"; // 消息类型
highlight?: boolean; // 是否高亮显示
}
通过一个 Step
数组,我们可以清晰地定义出整个流程。组件会根据这些步骤,在参与者之间画出对应的箭头和消息文本。
这是组件最核心的亮点。我利用 React 的 useState
和 useEffect
Hooks 来实现动画的播放。
currentStep
状态变量用于追踪当前播放到第几步,isPlaying
则控制动画的启停。setTimeout
来定时更新 currentStep
,从而驱动动画前进。当 isPlaying
状态改变或所有步骤播放完毕时,定时器会被相应地创建或销毁。React.useEffect(() => {
let interval;
if (isPlaying && currentStep < steps.length) {
interval = setTimeout(() => {
setCurrentStep(prev => prev + 1);
}, speed);
}
return () => clearTimeout(interval);
}, [isPlaying, currentStep, speed]);
此外,组件还提供了播放/暂停、重置以及速度调节(快速、正常、慢速)等控制功能,让用户可以按照自己的节奏来观察整个流程。
为了让组件能适应不同的应用场景,我添加了丰富的自定义 Props,例如:
title
和 subtitle
:为图表添加主副标题。width
和 height
:自由控制画布的尺寸。defaultSpeed
:设置默认的播放速度。将组件打包发布到 npm,是让它能够被更多人使用的关键一步。这个过程主要分为以下几个阶段:
首先,需要精心配置 package.json
文件。这是 npm 包的“身份证”。
main
、module
和 types
字段,分别指定 CommonJS、ESM 和 TypeScript 类型声明文件的入口。files
字段声明只将打包后的 dist
目录发布出去,避免包含不必要的源文件。react
和 react-dom
设置为 peerDependencies
,以避免与宿主项目产生版本冲突。我选择了 Vite
作为构建工具,因为它配置简单、速度快。
vite.config.ts
的 build.lib
选项,可以轻松地将 React 组件打包成库。vite-plugin-dts
插件在构建时自动生成 .d.ts
类型声明文件。package.json
中添加 build
脚本,一键执行 tsc
类型检查和 vite build
。手动发布流程繁琐且容易出错。因此,我利用 GitHub Actions 搭建了一套自动化流程。
ci.yml
工作流,在每次 push
或 pull_request
时自动执行代码检出、依赖安装、类型检查和构建,确保代码质量。publish.yml
工作流,当一个新版本 release
被创建时,它会自动执行所有测试和构建步骤,并最终将包发布到 npm registry。这里需要配置好 NPM_TOKEN
等 secrets。通过这套流程,从代码提交到 npm 包更新,整个过程都实现了自动化,极大地提升了开发效率。
从一个简单的 AI 作图灵感,到一个功能完整、发布在 npm 上的开源组件,这个过程充满了挑战和乐趣。它不仅解决了我最初的需求,也让我对组件化开发和工程化实践有了更深的理解。
如果你也对这个项目感兴趣,欢迎访问它的 npm 页面或 GitHub 仓库!