keep前端架构解析:React与TypeScript实现
架构概览
keep前端项目基于React 19与TypeScript构建,采用Next.js 15作为应用框架,结合Tailwind CSS与Tremor UI组件库打造现代化用户界面。项目采用领域驱动设计(DDD)思想,将代码按功能划分为实体(entities)、特性(features)、共享组件(shared)等模块,形成高内聚低耦合的架构体系。
技术栈选型
| 技术 | 版本 | 用途 |
|---|---|---|
| React | 19.0.0 | UI渲染核心 |
| TypeScript | 5.7.0 | 类型安全保障 |
| Next.js | 15.3.4 | 服务端渲染与路由 |
| Tailwind CSS | 3.4.1 | 样式解决方案 |
| Zustand | 5.0.3 | 状态管理 |
| React Table | 8.21.2 | 数据表格 |
| React Flow | 12.4.4 | 工作流可视化 |
| Tremor React | 3.18.7 | 数据可视化组件 |
项目结构
项目采用Next.js App Router架构,按功能模块组织代码,核心目录结构如下:
keep-ui/
├── app/ # Next.js路由与页面
├── components/ # 共享UI组件
├── entities/ # 领域实体模型
├── features/ # 业务特性模块
├── shared/ # 共享工具与API
├── utils/ # 工具函数
└── types/ # TypeScript类型定义
关键目录解析
-
app/: 基于Next.js 15 App Router的路由系统,包含页面组件与API路由
(keep)/workflows/: 工作流管理页面api/: 服务端API端点- 路由分组设计:使用括号分组如
(keep)、(signin)隔离不同功能模块
-
entities/: 领域实体模型,按业务概念划分
workflows/: 工作流相关模型与状态管理alerts/: 告警系统实体providers/: 外部集成提供者模型
-
features/: 业务特性模块,包含特定功能的完整实现
workflows/builder/: 工作流可视化编辑器filter/: 通用数据过滤功能
TypeScript类型系统设计
项目充分利用TypeScript的类型系统保障代码质量,核心类型定义集中在types/目录与各实体模块中。
工作流核心类型定义
// entities/workflows/model/types.ts
export type V2Step = z.infer<typeof V2StepSchema>;
export type WorkflowMetadata = Pick<Workflow, "name" | "description">;
export type WorkflowProperties = z.infer<typeof WorkflowPropertiesSchema>;
export type Definition = {
sequence: V2Step[];
properties: WorkflowProperties;
isValid?: boolean;
};
export interface WorkflowStateValues {
workflowId: string | null;
definition: DefinitionV2 | null;
nodes: FlowNode[];
edges: Edge[];
selectedNode: string | null;
// 省略其他状态...
}
类型验证与Zod集成
项目使用Zod进行运行时类型验证,确保数据流的安全性:
// entities/workflows/model/schema.ts
export const WorkflowPropertiesSchema = z.object({
name: z.string().min(1, "Workflow name is required"),
description: z.string().optional(),
enabled: z.boolean().default(true),
tags: z.array(z.string()).optional(),
incident: z.object({
createIncident: z.boolean().default(false),
incidentType: z.string().optional(),
}).optional(),
});
export const V2StepSchema = z.discriminatedUnion("componentType", [
V2StepTriggerSchema,
V2StepActionSchema,
V2StepConditionSchema,
V2StepContainerSchema,
]);
状态管理架构
项目采用Zustand作为主要状态管理方案,结合React Context实现状态共享,核心状态集中在实体模块中。
工作流状态管理
// entities/workflows/model/workflow-store.ts
export const useWorkflowStore = create<WorkflowState>()(
devtools(
(set, get) => ({
...defaultState,
setDefinition: (def) => set({ definition: def }),
updateDefinition: () => {
const { nodes, edges } = get();
const { sequence, properties: newProperties } =
reConstructWorklowToDefinition({ nodes, edges });
const { isValid, validationErrors, canDeploy } =
get().validateDefinition({ sequence, properties: newProperties });
set({
definition: wrapDefinitionV2({ sequence, properties: newProperties, isValid }),
validationErrors,
canDeploy
});
},
// 省略其他状态操作...
})
)
);
状态管理设计特点
- 模块化状态:按业务领域划分状态存储,避免单一状态树过于庞大
- 不可变更新:使用Zustand的不可变更新模式,确保状态变更可追踪
- 中间件支持:集成Redux DevTools进行状态调试
- 计算属性:通过派生状态减少冗余数据存储
UI组件架构
项目采用原子设计模式组织UI组件,结合Tremor React与自定义组件构建界面。
组件层次结构
表格组件实现示例
// components/table/GenericTable.tsx
export function GenericTable<T>({
data,
columns,
rowCount,
offset,
limit,
onPaginationChange,
onRowClick,
}: GenericTableProps<T>) {
const [pagination, setPagination] = useState({
pageIndex: Math.floor(offset / limit),
pageSize: limit,
});
const table = useReactTable({
columns,
data,
state: { pagination },
getCoreRowModel: getCoreRowModel(),
manualPagination: true,
pageCount: Math.ceil(rowCount / limit),
onPaginationChange: setPagination,
});
return (
<div className="flex flex-col gap-4">
<TremorTable>
<TableHeader>
{table.getHeaderGroups().map(headerGroup => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map(header => (
<TableHeaderCell key={header.id}>
{flexRender(header.column.columnDef.header, header.getContext())}
</TableHeaderCell>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows.map(row => (
<TableRow
key={row.id}
onClick={() => onRowClick?.(row.original)}
>
{row.getVisibleCells().map(cell => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</TremorTable>
<Pagination table={table} />
</div>
);
}
工作流编辑器核心实现
工作流编辑器是keep前端的核心功能,基于React Flow实现可视化拖拽编辑。
工作流编辑器架构
// features/workflows/builder/WorkflowGraph.tsx (概念实现)
export const WorkflowGraph = () => {
const { nodes, edges, onNodesChange, onEdgesChange, onConnect } =
useWorkflowStore();
const flowRef = useRef<ReactFlowInstance>(null);
return (
<div className="h-full w-full">
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
fitView
>
<Controls />
<Background />
<Minimap />
</ReactFlow>
</div>
);
};
工作流节点类型设计
// entities/workflows/model/types.ts
export type V2Step =
| V2StepTrigger // 触发器节点
| V2StepAction // 动作节点
| V2StepCondition // 条件节点
| V2StepContainer; // 容器节点
export type V2StepTrigger = z.infer<typeof V2StepTriggerSchema>;
export type V2StepAction = z.infer<typeof V2StepActionSchema>;
export type V2StepCondition = z.infer<typeof V2StepConditionSchema>;
工作流解析与序列化
工作流定义在内存中以图形化节点表示,通过序列化函数转换为可存储的YAML格式:
// entities/workflows/lib/parser.ts
export function parseWorkflow(yamlString: string, providers: Provider[]): Definition {
const workflow = yaml.parse(yamlString);
// 解析触发器
const triggers = Object.entries(workflow.triggers || {}).map(
([triggerType, config]) => createTriggerStep(triggerType, config)
);
// 解析步骤
const steps = (workflow.steps || []).map(step => parseStep(step, providers));
return {
sequence: [...triggers, ...steps],
properties: workflow.properties || {}
};
}
API通信层设计
项目通过ApiClient类封装API通信逻辑,实现前后端数据交互的统一管理。
API客户端实现
// shared/api/ApiClient.ts
export class ApiClient {
private readonly isServer: boolean;
constructor(
private readonly session: Session | null,
private readonly config: InternalConfig | null
) {
this.isServer = typeof window === "undefined";
}
getHeaders() {
if (!this.session?.accessToken) {
throw new Error("No valid session");
}
return {
Authorization: `Bearer ${this.session.accessToken}`,
"Content-Type": "application/json"
};
}
async request<T = any>(url: string, requestInit: RequestInit = {}): Promise<T> {
const apiUrl = this.isServer ? getApiURL() : getApiUrlFromConfig(this.config);
const fullUrl = `${apiUrl}${url}`;
const response = await fetch(fullUrl, {
...requestInit,
headers: { ...this.getHeaders(), ...requestInit.headers }
});
return this.handleResponse(response, url);
}
// 省略get/post/put等方法...
}
请求拦截与错误处理
ApiClient实现了统一的错误处理机制,包括认证失败、权限不足等常见错误场景:
// shared/api/ApiClient.ts
async handleResponse(response: Response, url: string) {
if (!response.ok) {
if (response.status === 401) {
// 认证失败,触发重新登录
if (!this.isServer) {
await signOutClient();
}
throw new KeepApiError("Authentication required");
}
if (response.status === 403) {
throw new KeepApiError("You don't have permission to perform this action");
}
// 其他错误处理...
}
return response.json();
}
认证与安全
项目采用NextAuth.js实现认证功能,支持多种认证方式,并通过中间件保护路由访问。
认证流程实现
// auth.ts
import NextAuth from "next-auth";
import MicrosoftEntraID from "next-auth/providers/microsoft-entra-id";
import Credentials from "next-auth/providers/credentials";
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [
MicrosoftEntraID({
clientId: process.env.AZURE_AD_CLIENT_ID!,
clientSecret: process.env.AZURE_AD_CLIENT_SECRET!,
tenantId: process.env.AZURE_AD_TENANT_ID,
}),
// 租户切换提供者
tenantSwitchProvider
],
callbacks: {
async session({ session, token }) {
session.user.tenantIds = token.tenantIds;
return session;
},
async jwt({ token, user }) {
if (user) {
token.tenantIds = user.tenantIds;
}
return token;
}
}
});
性能优化策略
项目通过多种方式优化前端性能,确保应用在大数据量场景下仍保持流畅。
关键优化措施
- 代码分割:利用Next.js的自动代码分割功能,按路由拆分代码包
- 组件懒加载:对大型组件如工作流编辑器实施按需加载
// app/(keep)/workflows/[workflow_id]/page.tsx const WorkflowEditor = dynamic( () => import("@/features/workflows/builder/WorkflowEditor"), { ssr: false } ); - 虚拟滚动:对大量数据表格采用虚拟滚动技术
- 缓存策略:使用SWR实现数据缓存与重新验证
// entities/workflows/model/useWorkflowsV2.ts export function useWorkflowsV2(workflowsQuery: WorkflowsQuery) { const api = useApi(); return useSWR( workflowsQuery ? workflowKeys.list(workflowsQuery) : null, () => api.post("/workflows/query?is_v2=true", workflowsQuery), { revalidateOnFocus: false } ); }
可扩展性设计
项目架构注重可扩展性,通过以下设计支持功能扩展:
- 插件化架构:外部集成提供者(Providers)采用插件化设计
- 动态表单:基于JSON Schema的动态表单生成
- 工作流扩展点:支持自定义工作流节点类型
部署与监控
项目集成了Sentry进行错误监控,通过Next.js的构建优化确保生产环境性能。
Sentry集成
// next.config.js
const { withSentryConfig } = require("@sentry/nextjs");
const nextConfig = {
// ...其他配置
};
const sentryConfig = {
org: "keep-hq",
project: "keep-ui",
tunnelRoute: "/monitoring",
hideSourceMaps: true,
disableLogger: true
};
module.exports = withSentryConfig(nextConfig, sentryConfig);
总结与最佳实践
keep前端架构基于现代React技术栈,通过TypeScript确保类型安全,采用DDD思想组织代码,实现了高可维护性和可扩展性。核心最佳实践包括:
- 强类型设计:充分利用TypeScript类型系统,减少运行时错误
- 模块化架构:按业务领域划分代码,提高代码复用性
- 状态集中管理:使用Zustand管理复杂状态,保持组件轻量
- 统一API层:通过ApiClient封装通信逻辑,便于维护
- 可扩展设计:插件化架构支持功能扩展
未来架构演进方向
- 微前端架构:按业务域拆分独立前端应用
- 组件驱动开发:完善组件文档与测试,推进CDD实践
- 状态标准化:探索使用Normalized Store模式优化状态管理
- 编译时优化:利用Turbopack提升构建性能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



