新闻详情

新闻详情

首页 / 资讯中心 / 详情

Gadgets Workshop 前端工程规范:基于 Kumo 与 TanStack Router 的 React SPA 架构与编码约定

发布时间:2026/9/24 23:45:11来源:尧图网络
Gadgets Workshop 前端工程规范:基于 Kumo 与 TanStack Router 的 React SPA 架构与编码约定
人工智能AI 应用AI AgentAgent 沙箱AI 安全治理【免费下载链接】cloudflare-osAgent workspace built on Cloudflare Workers for creating documents, building apps, and running agents with your company’s context and systems.项目地址https://gitcode.com/gh_mirrors/cl/cloudflare-os点击查看免费下载导读本文以gadgets/workshop-frontend包的开发规范文档为核心系统讲解 Workshop 单页应用的目录架构、页面/路由边界、共享代码归属、Kumo 语义化样式体系、React 编码约定与测试策略并结合仓库源码逐条印证每一项约定的落地方式。读者读完后既能按规范组织新代码也能理解该前端在 Cloudflare Workers 生态中如何通过 WebSocket RPC 与后端通信、如何用 Kumo 语义 token 保持全站视觉一致。一、包定位与技术栈packages/workshop-frontend是 Gadgets Workshop 的纯客户端单页应用SPA完全运行在浏览器中通过基于 WebSocket 的 RPC 与packages/workshop-backend通信。从 package.json 可以看到其技术栈组合React 19react/react-dom19.x作为视图层基础TanStack Routertanstack/react-router负责路由配合tanstack/router-plugin做自动代码分割Kumocloudflare/kumo提供组件库与语义设计 tokenTailwind CSS 4tailwindcsstailwindcss/vite负责布局与结构样式capnweb实现浏览器端 RPCnewWebSocketRpcSessionPhosphor Iconsphosphor-icons/react提供图标CodeMirror 系列包支撑聊天编辑器与代码编辑器场景Vite Vitest jsdom作为构建与测试工具链。包名gadgets/workshop-frontend归属于该仓库的公共 workspace其构建通过仓库级工具vpVite驱动见 scripts/package.json 与 README.md。二、目录架构先按产品归属再按实现类型规范的核心原则是新代码按产品归属product ownership优先组织实现类型implementation type其次。目标目录形态src/ routes/ TanStack route declarations and route-level wiring pages/ Substantial route-level screens that compose one or more features features/ Product features and their owned UI, hooks, and logic components/ UI and application primitives shared across unrelated features hooks/ Hooks shared across unrelated features utils/ Feature-independent utilities需要特别说明的是现有代码树先于该约定存在。例如当前src/根目录下仍散落着AdminPage.tsx、Connections.tsx、SettingsPage.tsx等历史遗留页面级文件并没有独立的pages/目录。规范明确约定适用于新代码与大规模重构中的代码不应顺带迁移无关文件——避免为迎合规范而做无收益的大面积搬动。2.1 Feature 目录扁平起步按职责细分Feature 目录拥有产品行为可包含属于该行为的组件、hooks、测试与工具。规范给出的理想形态features/chat/composer/ ChatComposer.tsx ComposerAddMenu.tsx ComposerAddMenu.test.tsx useComposerDraft.ts composerTokens.ts即一开始保持扁平文件名本身已传达类型useXxx是 hook、Xxx.test.tsx是测试、PascalCase.tsx是组件不要仅仅为了按实现类型分类而创建components/、hooks/、helpers/、tests/子目录测试通常与被测对象同目录放置。只有当某个连贯的内部子系统积累到多个文件、或扁平目录难以扫描时才引入以其职责命名的子目录例如draft/、tokens/、attachments/、slash-commands/并避免通用的helpers/桶式目录。这一约定在仓库中有真实落点src/features/chat/composer/内部正是按职责划分出attachments/、draft/内含composerDraft.ts、useComposerDraft.ts、inline-items/、slash-commands/四个子系统目录其余组件ChatComposer.tsx、ComposerAddMenu.tsx、ComposerModelSelector.tsx等平铺在 composer 目录下测试如ComposerAddMenu.test.tsx、useComposerDraft.test.tsx与被测文件同置。组织代码的依据是这些文件因何而一起变更organize by the reason files change together而 Feature 化组织并不取代一个组件一个文件的模型。2.2 组件文件的提取标准当组件满足以下任一属性时应单独创建组件文件拥有有意义的 state、effects 或交互行为可独立测试或可复用代表一个明确的 UI 职责保持内联会让父组件难以理解已积累出遮蔽父组件主流程的支持类型或逻辑。反之仅在父组件中使用、且易于理解的小型无状态渲染辅助应保持私有、留在父文件内当它发展出自己的行为或测试时再提取到父组件旁边。命名规则组件用PascalCase文件名hooks 与非组件模块用camelCase文件名优先直接导入不要仅为缩短路径而添加 barrel 文件index.ts 聚合导出。三、页面与路由职责边界与迁移路径src/routes/下的文件定义路由应只关注路由关注点参数parameters、搜索校验search validation、loaders、导航以及组合路由页面。页面page是组合边界而非 feature一个页面可以组合多个 feature一个 feature 可以出现在多个页面上。小型页面可以直接留在路由文件里体量较大的页面实现应移到src/pages/page/在那里组合 feature 组件——仅对该页面有意义的组件与 hooks 也留在页面目录中而不是放进全局components/或hooks/。把页面支撑代码移出src/routes/的另一个好处是避开 TanStack Router 的文件扫描避免被误当作路由。src/pages/下每个路由级屏幕组件必须以Page.tsx后缀命名如HomePage.tsx、WorkspacePage.tsx支撑组件则用描述自身职责的名字如HomeTaskSuggestions.tsx。两条重要边界不要把产品行为搬进页面仅仅因为页面当前消费了它。具有独立产品含义、或会被多个页面使用的行为属于src/features/feature/。不确定时先默认放在页面当归属拓宽时再提升promote。src/routeTree.gen.ts是生成文件禁止手动编辑——它在构建时由tanstack/router-plugin重新生成。实际路由注册见 router.tsxcreateRouter({ routeTree, scrollRestoration: true, defaultPreload: intent, defaultPreloadStaleTime: 0 })从routeTree.gen导入路由树。文档给出的 Home 页例子恰是先于规则的历史代码components/AppShell/HomeTaskSuggestions.tsx与components/MeshBackground.tsx唯一的线上消费者是routes/index.tsx它们本质是 Home 专属的组合与展示层而非共享的 AppShell 原语因此目标组织应是pages/home/ HomePage.tsx HomeTaskSuggestions.tsx MeshBackground.tsx若未来任务建议task suggestions成为被其他页面使用的独立工作流再将其提升为features/task-suggestions/——不要仅凭推测性复用一开始就建 feature。四、共享代码components/ 与 hooks/ 不是默认目的地src/components/与src/hooks/是共享应用基础设施而非默认放置地。代码应先放在拥有其行为的 feature 下。复用本身不构成通用化的理由规范给出了明确的升级阶梯若一个 feature 的多个部分使用某物移到它们最近的共同 feature 目录若另一个 feature 消费了仍由原 feature 拥有的概念保持从原 feature 导出只有当互不相关的 feature使用同一个与 feature 无关的抽象、且其 API 不再依赖原始 feature 时才提升到全局components/或hooks/不要因为看起来相似就合并组件避免抹掉重要领域行为的通用 prop 重载式抽象。只把代码移动到其归属要求的高度。例如被 composer 与聊天历史共享的 skill pill 属于features/chat/而通用的应用图标按钮属于components/。五、组件 API 与组合设计规范的 API 设计原则强调让非法状态不可表达5.1 成对属性用对象或可辨识联合只在一起才有效的 props 应表达为一个对象或 discriminated union禁止允许部分配置// 避免调用方可以给 count 却不给任何关闭方式 count?: number; onDismiss?: () void; // 优先该能力要么完整存在要么完全缺失 notice?: { count: number; onDismiss: () void };5.2 受控值必须配变更回调受控值controlled value必须同时提供 change callback否则组件应自己拥有该值。不要用 Effect 把受控 prop 复制进本地 state// 受控 value: string; onValueChange: (value: string) void; // 非受控 initialValue?: string;5.3 回调命名与传值回调命名为onAction传递领域值domain values而非 React setter 或浏览器事件。例如对外暴露onModelChange(modelId)而不是setSelectedModel或onChange(event)。这一条在源码中有直接实例src/features/chat/composer/ComposerModelSelector.tsx的 props 定义即为{ selectedModel: string | null; onModelChange: (modelId: string | null) void }选中项通过onModelChange(model.id)/onModelChange(null)上报消费者拿到的是模型 ID 领域值。5.4 扩展面只在当前需要时添加children、命名插槽、variants、className、DOM prop 透传、命令式 ref只有当前调用方确实需要该控制能力时才添加不要为预期的复用提前加上。5.5 Context 的使用边界用 Context 承载应用级的值认证、主题、toast。实例特定的 feature 数据与动作应通过 props 传递不要仅仅为了避免穿透一两个组件层级就引入 Context。仓库中RpcContext、AuthContext、ThemeContext、ServerConfigContext、FeatureFlagsContext均属应用级基础设施见 main.tsx 与 __root.tsx 的 Provider 嵌套。5.6 提取时机当被提取单元拥有完整关注点——如 state 及其转移、一个 Effect 生命周期与清理、一个可访问的交互、或一个可独立测试的纯变换——就提取组件或 hook。若子组件主要只是转发标记markup或需要父组件的 refs、setters 与同步回调才能工作则应保持代码聚合。六、Kumo 与样式体系语义 token 优先杜绝自定义色样式规范的核心是默认使用 Kumo 组件与 Kumo 语义设计 token。在创建自定义控件、交互模式或视觉原语之前先查 Kumo。Workshop 已有的包装器wrapper只有在提供了 Kumo 未直接提供的既定应用行为时才可使用。6.1 硬性禁止项除非用户明确要求禁止在 Kumo 之外添加自定义颜色与设计 token具体包括组件样式中出现 Hex、RGB、HSL 或 OKLCH颜色字面量任意 Tailwind 颜色值arbitrary color values新增应用级颜色变量或 token 族为 Kumo 的 surface、border、text、status、focus、interaction token 做feature 本地替换。应使用 Kumo 语义类例如bg-kumo-base、text-kumo-subtle、border-kumo-line而不是调色板颜色。全局 Kumo token 主题化是应用级的刻意决策不得作为日常 feature 工作的一部分引入或更改。现有代码中的遗留自定义 token 与颜色声明不是新代码的先例不要扩散其使用只可在明确范围的清理任务中迁移。源码印证src/components/AppShell/AppShell.tsx中侧栏布局大量使用bg-kumo-base、border-kumo-line、text-kumo-default、hover:bg-kumo-tint、text-kumo-inactive等语义类CommandPalette.tsx 同样只使用bg-kumo-base、text-kumo-strong等 token 类未出现任何调色板颜色。根路由 __root.tsx 的加载与错误页也全部基于bg-kumo-base/text-kumo-subtle/bg-kumo-brand等语义类。6.2 Tailwind 与自定义 CSS 的分工Tailwind 仍适用于结构布局、间距、尺寸、定位、响应式行为与排版。自定义 CSS 仅用于 Kumo 与工具类无法表达的技术行为如编辑器集成或测量型浮层自定义 CSS不会放宽颜色与 token 规则。当 Kumo 组件不适用时先记录具体的行为或可访问性缺口再添加共享的 Workshop 抽象不要仅为换肤而包装 Kumo。6.3 主题机制的源码视角从 theme.ts 可以看到该规范背后的主题架构亮/暗基础调色板通过 TailwindthemeCSS 变量与[data-modedark]覆盖静态定义在styles.cssapplyThemeMode在html上设置data-mode与colorScheme使 Kumo 语义 token 与原生控件一致解析部署方可通过applyAccentColor在运行时以单个 seed 色派生 accent 家族hover/lighter/selection 用 CSSoklch(from ...)相对色语法推导。这解释了为什么新增自定义颜色变量被严格禁止——主题是应用级决策feature 层只能消费语义 token。七、React 编码约定7.1 组件与 hook 的写法默认用命名const箭头函数定义组件与 hooks保证声明在使用之前、不依赖函数声明提升。props 直接类型化不用React.FC。被memo、forwardRef等包裹的组件要保留显式名称必要时用displayName保证 React DevTools 与堆栈可读。7.2 Effect 是逃生舱不是状态管理工具Effect 用于与外部系统同步遵循 React 官方 You Might Not Need an Effect 的思路具体规则不要用 Effect 从 props/state 派生渲染数据——渲染期间计算不要用 Effect 承载用户交互引起的逻辑——在知道发生了什么的事件处理器里执行不要用 Effect 同步两份 React state——优先单一数据源、派生值、受控组件或提升 state当身份变化应重置组件状态时优先用组件key外部 store 订阅适合时优先用useSyncExternalStore发起 fetch 或订阅的 Effect 必须清理过期工作与订阅组件在开发模式下 Effect 重启/重挂载时仍须正确避免用Effect 链——更新 state 只为触发另一个 Effectstate 尽量靠近拥有该行为的位置。7.3 hook 与记忆化在表示连贯行为或被复用时才提取 hook不要仅为缩短文件而提取。默认不加useMemo/useCallback只在 identity 或昂贵计算产生实际影响时使用。7.4 可访问性与 RPC stub 纪律提取交互式 UI 时必须保留键盘行为、焦点管理与可访问名称。RPC stubs 必须遵守仓库级 AGENTS.md 的处置与 React state 规则——这点在源码中有典型体现main.tsx 中 RPC 连接中断时用stub[Symbol.dispose]()清理候选连接disposeQuietly并在handleBroken中以new RpcPromisePublicApi(reconnect())替换当前 stub保证同一时刻只有一个处置路径。7.5 连接管理实例main.tsx的 WebSocket RPC 连接管理还体现了若干约定初始退避 1s、最大退避 10s、抖动系数 0.85–1.150.85 0.3 * Math.random()防惊群、重连前用ping()探活20s 超时、在visibilitychange/online事件时对疑似僵尸连接做唤醒探测WAKE_PROBE_MIN_IDLE_MS 15000。这一实现与文档订阅/连接必须清理、重启后必须正确的 Effect 纪律一脉相承——连接管理被抽到模块级而非组件 Effect 内正是为了避免开发模式下 Effect 双跑导致重复建连。八、注释原则优先让命名、类型与结构传达意图不要添加逐行复述代码的注释。注释只适用于坑gotchas与非显然的不变量外部约束安全或性能推理刻意偏离惯例的决策——解释为什么这个意外选择是必要的而不是代码中可见的机制。当注释所描述的约束不再存在时删除或更新它。九、测试约定9.1 测试的放置单元测试与其主题同目录存放命名*.test.ts或*.test.tsx。仅当场景跨多个模块、没有单一归属时才使用 feature 级__tests__/目录。仓库中的典型形态ComposerAddMenu.test.tsx与ComposerAddMenu.tsx同目录、useComposerDraft.test.tsx与useComposerDraft.ts同目录而src/components/format/__tests__/messageFormatRefs.test.ts属于跨模块场景示例。9.2 测试什么、不测试什么测试应保护回归重要的行为或验证变更引入的真实逻辑。不要因为 React、JavaScript、TypeScript、Kumo 或某个框架的行为出现在实现里就去测框架本身。应测试可观察契约observable contracts产品规则状态转移可访问性行为竞态处理失败路径。避免只断言实现细节、琐碎的透传标记、或已由类型与底层平台保证的行为。一个测试应有对本应用有意义的明确失败含义。行为保持不变的移动behavior-preserving moves除 import 外应保持测试不变提取暴露了此前未测的重要逻辑时才补针对性覆盖不要仅因为文件或组件边界出现了就加测试。9.3 常用命令在公开 workspace 根目录执行pnpm --filter gadgets/workshop-frontend test:run pnpm exec tsc -p packages/workshop-frontend/tsconfig.json pnpm exec tsc -p packages/workshop-frontend/tsconfig.vite.json pnpm exec vp run -F gadgets/workshop-frontend build推送前在 workspace 状态允许时运行pnpm lint对应仓库级 lint 门禁lint:check、types:check。注意test:run直接走 vitest适合迭代期使用vp run走任务缓存。十、构建与开发工具链补充vite.config.ts 揭示了该包构建的独特设计与规范中的目录纪律互为表里build是 Vite 任务而非 package.json 脚本因为任务可以声明env: [VITE_*]缓存的vp运行会在干净环境中执行脚本、丢失环境变量而声明在任务上既能转发VITE_*标志、又能将其纳入指纹fingerprint改变取值会触发缓存未命中而非回放旧产物。VITE_CF_ACCESS_MODE会被内联进src/useAuth.tsVITE_FRONTEND_ERROR_REPORTING决定是否生成隐藏 sourcemap二者都会改变产物语义因此必须被指纹追踪。build 任务由三段命令组成tsc应用类型检查、tsc -p tsconfig.vite.json配置文件自身检查、以及强制NODE_ENVproduction的 vite build——保证无论 shell 环境如何都产出生产包。dist/被从任务 input 中排除{ pattern: !dist/**, base: package }因为vp不会缓存既读又写的任务**/.wrangler/**被 workspace 级排除因为 wrangler 的随机命名临时产物会让任何跑过wrangler dev的兄弟包导致缓存失效。开发服务器代理/api/client-errors、/blueprint-screenshot、/api/site-logo到VITE_BACKEND_HOST默认localhost:8787对应 README.md 中描述的 dev 工作流pnpm dev端口 3000、pnpm exec vp run build、pnpm preview。10.1 构建期认证模式README 明确该前端支持两种构建期选择的认证模式默认的密码模式用户名密码/signup注册与 Cloudflare Access 模式VITE_CF_ACCESS_MODEtrue构建由后端authenticateFromCfAccess()基于 CF Access 已建立的会话自动认证同时禁用密码登录与注册页后端需配置CF_ACCESS_ISS与CF_ACCESS_AUD环境变量用于 JWT 校验。这与 __root.tsx 中CF_ACCESS_MODE分支未认证时显示 Authenticating... 加载态以及useAuth的实现对应。结语workshop-frontend的这份 AGENTS 规范本质上回答了三个问题代码放哪里产品归属优先、扁平起步、按职责细分、组件长什么样语义 token、领域值回调、非法状态不可表达、Kumo 优先、如何保证长期健康Effect 纪律、共享代码的克制提升、只测有意义行为。它与仓库级 AGENTS.md 一脉相承后者进一步约定了 RPC stub 处置、capnweb promise 流水线、useState不得直接持有 RpcStub 等跨包规则。对任何要在此 SPA 上新增或重构功能、评审他人前端代码的开发者而言这份规范配合 AGENTS.md、README.md 与 vite.config.ts 即可完整掌握该包的组织逻辑与构建机制。赞分享人工智能AI 应用AI AgentAgent 沙箱AI 安全治理【免费下载链接】cloudflare-osAgent workspace built on Cloudflare Workers for creating documents, building apps, and running agents with your company’s context and systems.项目地址https://gitcode.com/gh_mirrors/cl/cloudflare-os点击查看免费下载相关推荐Infisical 前端架构实战基于 React 18、TanStack Router 与 React Query 的 SPA 工程化指南Infisical 前端架构实战基于 React 18、TanStack Router 与 React Query 的 SPA 工程化指南 本文以 Infis后端前端密钥管理应用安全认证鉴权cloudflare-os 前端开发规范实战Workshop 与 Gatekeeper 管理界面的 React、Kumo 与测试约定cloudflare os 前端开发规范实战Workshop 与 Gatekeeper 管理界面的 React、Kumo 与测试约定 本文以仓库内 front人工智能AI 应用AI AgentAgent 沙箱AI 安全治理Open edX前端路由React Router与SPA架构Open edX前端路由React Router与SPA架构 引言现代在线教育平台的前端挑战 在线教育平台Open edX面临着复杂的前端架构挑战需要支持后端教育上一篇快速免费解锁网易云音乐NCM格式解密ncmdump终极使用指南下一篇TypeSpec http-server-csharp Emitter 完整使用指南命令行、tspconfig 配置与全部选项解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

ExternalDNS 集成 Skipper RouteGroup 源:从 CRD 部署到 DNS 记录生成的完整指南 2026/9/25 3:01:10

ExternalDNS 集成 Skipper RouteGroup 源:从 CRD 部署到 DNS 记录生成的完整指南

云原生 【免费下载链接】external-dns Configure external DNS servers dynamically from Kubernetes resources 项目地址: https://gitcode.com/gh_mirrors/ex/external-dns 点击查看 免费下载 导读:本文围绕 ExternalDNS 的 skipper-routegroup 源&am…

阅读更多 →
使用 Java 与 graphql-java 构建 GraphQL 服务器:从 schema-first 到 code-first 的完整指南 2026/9/25 3:01:10

使用 Java 与 graphql-java 构建 GraphQL 服务器:从 schema-first 到 code-first 的完整指南

【免费下载链接】howtographql The Fullstack Tutorial for GraphQL 项目地址: https://gitcode.com/gh_mirrors/ho/howtographql 点击查看 免费下载 本指南以 howtographql 仓库中 Java 后端教程的开篇章节为核心,系统讲解 GraphQL 服务器在 Java 生态…

阅读更多 →
OpenShift Origin 容器化部署与 Sample App 环境准备指南 2026/9/25 3:01:09

OpenShift Origin 容器化部署与 Sample App 环境准备指南

测试云原生质量保障 【免费下载链接】origin Conformance test suite for OpenShift 项目地址: https://gitcode.com/gh_mirrors/or/origin 点击查看 免费下载 本文基于 origin 仓库中的 container-setup.md 展开,介绍如何以 Docker 容器方式拉起一个自…

阅读更多 →
LeetCode Top 100高频题刷题指南:吃透双指针、BFS与动态规划 2026/9/25 3:01:09

LeetCode Top 100高频题刷题指南:吃透双指针、BFS与动态规划

还记得我第一次打开LeetCode的Top 100题单时,第一反应是:这些题真的够用吗?刷完到底要花多久?说实话,很多帖子喜欢把这份题单捧成“面试通关秘笈”,但我完整刷过两轮之后,更愿意把它看作一份高频…

阅读更多 →
QGIS数据处理-CityEngine程序化生成建筑 2026/9/25 3:01:03

QGIS数据处理-CityEngine程序化生成建筑

高德矢量 http://webrd01.is.autonavi.com/appmaptile?x{x}&y{y}&z{z}&langzh_cn&size1&scale1&style8 高德影像 https://webst01.is.autonavi.com/appmaptile?style6&x{x}&y{y}&z{z} 腾讯矢量 http://rt0.map.gtimg.com/realtimerender…

阅读更多 →
MySQL常用函数实战指南:从字符串到窗口函数的避坑手册 2026/9/25 3:01:03

MySQL常用函数实战指南:从字符串到窗口函数的避坑手册

如果说每一行 SQL 都是在和表里的数据对话,那函数就是我们最顺手的表达工具。刚开始写 MySQL 的那几年,我干过最蠢的事就是把函数当字典背——今天查字符串,明天查日期,结果同一个统计需求写出过三种风格完全不一样的 SQL&#xf…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉