
Dify 前端开发规约详解web/AGENTS.md 中的 Agent 工作流、包契约与 Next.js 生成规则【免费下载链接】difyBuild Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.项目地址: https://gitcode.com/GitHub_Trending/di/dify本文以 web/AGENTS.md 为骨架完整拆解 Dify 前端web/与packages/dify-ui/面向人类和 AI Agent 的双层开发规约从测试与静态检查文档的路由规则、i18n 与生成式 API 客户端的包契约到 Dify UI 组件库的各项canonical contract再到next dev自动写入的 Next.js 破坏性变更警示块。读完后可按仓库真实路径定位每一条契约的落点文件在贡献 Dify 前端代码时保持与工程体系一致。一、文档定位一份写给 Agent 的前端工作手册web/AGENTS.md 位于 Web 应用目录根部是 Dify 前端唯一的Agent 入口规约。它的结构分为三层Frontend Workflow——规定哪些文档、哪些技能skill在什么场景下加载Package Contracts——规定用户可见文案、API 调用、UI 组件、表单、可访问性等跨功能契约Next.js 生成规则块——由next dev自动写入并维护的警告区提示当前 Next.js 版本存在与训练数据不一致的破坏性变更。这种流程 契约 工具链警示的组合使文档既约束人的 PR 行为也约束 AI 编码助手的工具选择。二、Frontend Workflow文档与技能的路由规则原文第一条工作流要求非常克制——只在对应工作场景下加载对应文档web/docs/test.md只在处理前端测试工作时读取web/docs/lint.md只在运行或修改静态检查时读取。这两个文件在仓库中均真实存在且内容完备web/docs/test.md 声明自己是web/下自动化测试的 single source of truth定义了何时该写测试保护可观察契约用户交互、导航与 URL 状态、加载/成功/错误/空态、可访问性语义、可复现回归的 bug fix并给出两条显式测试项目unit走 happy-dombrowser走 Playwright Chromium与标准命令# happy-dom省略路径则运行整个 unit 项目 vp test run --project unit path/to/spec-or-directory # Browser Mode省略路径则运行整个 browser 项目 vp test run --project browser path/to/spec.browser.spec.tsx # 诊断性覆盖率报告不是验收目标 vp test run --project unit --coverage path/to/spec-or-directoryweb/docs/lint.md 说明vp checkOxfmt 格式化 Oxlint 规则 TypeScript 诊断与 ESLint 非代码文件兜底的分工根命令为pnpm check/pnpm check:fix。技能skill路由同样按场景触发how-to-write-component只在实现涉及组件归属、状态、数据流、effect 或交互边界决策时加载纯测试、纯文案、纯样式改动不得加载frontend-code-review仅在显式的前端评审/审计请求含测试评审时使用frontend-testing编写或修改 Vitest、React Testing Library 测试时使用。文档还特别强调web/docs/test.md是 Web 自动化测试策略的唯一事实来源Skills may route and execute that policy but must not redefine it——技能只能路由和执行该策略不能重定义它。这保证了策略演进只需改一处。三、Package Contracts七条跨功能契约逐条解析3.1 用户可见字符串必须走 i18n 键规约第一条即国际化契约面向用户的字符串必须使用web/i18n/en-US/下的键新增或重命名键时必须同步更新所有受支持语言的正确本地化值。仓库中 web/i18n/ 目录下实际维护了 24 个语言目录ar-TN、de-DE、en-US、es-ES、fa-IR、fr-FR、hi-IN、id-ID、it-IT、ja-JP、ko-KR、lo-LA、nl-NL、pl-PL、pt-BR、ro-RO、ru-RU、sl-SI、th-TH、tr-TR、uk-UA、vi-VN、zh-Hans、zh-Hant。这意味着一次键的重命名可能波及 24 个文件树——契约把多语言完整性从自觉行为升级为硬性规则。测试侧同样配套web/test/i18n-mock.ts 提供createReactI18nextMock在需要自定义翻译时加载共享的react-i18nextmock 全局加载测试默认不依赖真实翻译文件。3.2 后端调用只允许生成式 consoleQuery / consoleClient规约明确要求新后端调用与已迁移界面必须使用/service/client中生成的consoleQuery/consoleClientAPI禁止新增手写 REST helper、DTO 镜像、基于 mock 的 app 状态或直接修改生成契约。从源码结构看这条契约有明确实现落点 web/service/client.ts类型全部来自dify/contracts/api/console/**/types.gen与dify/contracts/console的consoleRouterContract即契约类型是生成的.gen后缀而非手写镜像客户端基于 oRPC 体系构建createORPCClientOpenAPILinkorpc/openapi-client/fetch再经createTanstackQueryUtils接入 TanStack Query这就是consoleQuery的形态请求上下文扩展了 TanStack Query 的 operation context加入 Dify 特有的keepalive与silent标志见 client.ts#L68-L71并封装了 SSE 流式生成streamWorkflowGeneration。因此不要手写 REST helper不是风格偏好而是保证 DTO 类型、OpenAPI URL 归一化normalizeConsoleOpenAPIURL、认证头注入getMarketplaceHeaders等只有一条代码路径。3.3 Dify UI 原语子路径导入与焦点指示规约要求优先使用langgenius/dify-ui/*原语、data attribute 与设计令牌选择原语时从 Dify UI 包索引入手并在最终可聚焦元素上保留可见焦点指示。包索引即 packages/dify-ui/README.md。从源码结构看该包有两条与规约直接对应的硬性设计故意没有根 barrel——只能按公共子路径导入如langgenius/dify-ui/button、langgenius/dify-ui/dialog、langgenius/dify-ui/field样式入口langgenius/dify-ui/styles.css在消费方根样式表引入一次大部分交互原语是 Base UI 无头组件的薄而有主见的封装Dify 自研原语使用语义化 HTML、cva、cn与设计令牌包虽为 workspace 私有但其公共子路径被当作稳定的包边界对待。README 的 Primitives 表按 Actions / Controls / Display / Feedback / Form / Layout / Media / Navigation / Overlay and menu / Search and pick 十类列出全部子路径./button、./icon-button、./form、./input-group、./dialog、./infotip所在的 overlay 家族等是选原语的唯一入口清单。3.4 搜索输入框SearchInput 复合组件优先规约当 Web 的SearchInput复合组件的搜索、清除、IME 契约与功能匹配时复用它否则遵循 canonical 的 Input Group 契约。这里的关键是契约匹配才复用SearchInput封装了搜索、清除按钮与 IME输入法组合边界这三件事只有功能同时命中该组合契约时才使用避免为了看起来像搜索框而引入不匹配的复合行为。不匹配时退回更底层的 Input Group 契约文档 packages/dify-ui/src/input-group/README.md其覆盖复合输入解剖、共享表面归属、DOM 顺序、焦点与可交互 addon。3.5 保存与提交流真实表单边界规约要求为保存/提交流程建立真实表单边界带可见标签与可访问错误当 Dify UI 的Form结构化提交与校验契约是归属方时使用它否则使用原生 form契约详见 packages/dify-ui/docs/forms.md。从 dify-ui 文档索引看forms.md 负责 native submit 边界、值归属、field、label 与 error 的契约划分——这与 AGENTS.md 中要么 Dify UI Form 拥有契约要么原生 form的二选一表述互补文档定义契约内容AGENTS.md 定义选择决策。3.6 按钮与图标按钮不得用 Web 包装层掩盖契约规约遵循 canonical 的 Button 契约 与 IconButton 契约覆盖操作语义、loading、可访问名称与原语组合不得添加一个 Web 包装层来隐藏这些契约。从 packages/dify-ui/README.md 的组件指南表可确认两条契约的具体职责Button 覆盖操作语义、submit 与 link 的选择、loading 与 disabled 的区分、内容间距Icon Button 覆盖可访问名称、装饰性 glyph、外观归属与原语组合。规约中不得在 Web 层包一层的禁令正是防止web/出现一个与契约文档不同步的中间封装。3.7 可访问名称、描述与弹层两条契约引用同一套命名与弹层文档命名选择或修改可见标签、ARIA 命名、描述、视觉隐藏文本时遵循 packages/dify-ui/docs/accessible-names-and-descriptions.md。规约补充了一条职责边界——Web 拥有本地化与功能特定的状态播报不得在本地重新定义 Dify UI 的命名契约。也就是说 dify-ui 文档定义命名的来源、描述、覆盖与安全的 label 移除web/只负责本地化与功能级状态播报。弹层原语选择、portal、焦点与层叠遵循 packages/dify-ui/docs/overlays.md信息图形打开解释性内容的场景复用 Web 的Infotip复合组件不得引入一个在 Web 层重新实现 Dify UI 弹层行为的通用包装。3.8 自定义 SVG 图标规约末尾自定义 SVG 图标遵循 packages/iconify-collections/README.md不得在web/app/components/base/icons/src/下添加生成的 React 图标。仓库中packages/iconify-collections/目录实际包含 500 余个 SVG 源文件与多个 JSON 集合描述即图标资产以 iconify 集合形式集中管理而不是把构建产物 React 图标散落在应用目录里。四、Next.js 生成规则块由next dev自动维护的警示区web/AGENTS.md 尾部被!-- BEGIN:nextjs-agent-rules --与!-- END:nextjs-agent-rules --包裹着一段机器维护的文本这是整篇文档中最特殊的部分This is NOT the Next.js you know——声明当前 Next.js 版本存在破坏性变更API、约定与文件结构都可能与模型训练数据不同写任何代码前先读node_modules/next/dist/docs/中相应指南从本文件所在目录解析monorepo 中next包可能从仓库根不可见并注意弃用通知自解释的维护机制——该块由next dev写入并在被删除后重新加回校验逻辑位于node_modules/next/dist/server/lib/generate-agent-files.js。文档给出了一条实用的 diff 建议从 diff 中移除它只会重新产生未提交的变更把它随你的改动一起提交才能保持工作树干净。这个设计值得借鉴Next.js 官方把AI 助手可能按旧知识写码这一风险变成了工具链自动写入 AGENTS 类文件的固定机制——规约不是靠人记得更新而是每次next dev运行时自我刷新。五、契约到文件的路径速查下表汇总 AGENTS.md 中每个契约指向的真实文件便于按图索骥契约/工作流条目契约文件仓库根相对路径前端测试策略唯一事实来源web/docs/test.md静态检查策略web/docs/lint.mdDify UI 包索引选原语起点packages/dify-ui/README.mdButton 契约packages/dify-ui/src/button/README.mdIconButton 契约packages/dify-ui/src/icon-button/README.mdInput Group 契约packages/dify-ui/src/input-group/README.mdForm 契约packages/dify-ui/docs/forms.md可访问名称与描述packages/dify-ui/docs/accessible-names-and-descriptions.mdOverlay 契约packages/dify-ui/docs/overlays.md自定义 SVG 图标packages/iconify-collections/README.md生成式 API 客户端实现web/service/client.ts国际化键web/i18n/en-US为键基准24 个 locale 同步六、实操要点小结动测试之前先读 web/docs/test.md并记住web/下测试必须显式--project unit或--project browser裸vp test会同时跑两个项目不是标准 Web 测试命令。覆盖率只是诊断信号文档未定义任何百分比门槛。动静态检查之前先读 web/docs/lint.md根命令pnpm checkOxlint 规则基线在lint.config.ts非代码文件兜底在eslint.config.mjsOxlint 历史错误基线在oxlint-suppressions.jsonOxlint 与 ESLint 的 disable 注释互不通用。加一条用户可见文案先在web/i18n/en-US/定义键再把 24 个 locale 目录全部补齐。加一次后端调用走/service/client的生成契约oRPC OpenAPI TanStack Query不手写 REST helper不碰.gen契约。加一个组件先到 packages/dify-ui/README.md 的子路径表里找原语命中SearchInput复合契约就复用否则按 Input Group / Button / IconButton / Form / Overlay / 命名契约文档决策并保留可见焦点指示图标只进 iconify 集合不进app/components/base/icons/src/。写任何 Next.js 相关代码前读node_modules/next/dist/docs/里的当前版本文档因为 AGENTS.md 中那个自更新块明示了这不是你训练数据里的 Next.js。整体来看web/AGENTS.md 的价值不在罗列规则而在于把哪个契约归谁所有Dify UI 拥有原语与命名契约Web 拥有本地化与功能播报docs/test.md拥有测试策略写得毫无歧义并用生成式代码、机器维护的 Next.js 规则块和 24 语言 i18n 目录这些仓库事实为每条规则提供了可核验的落点。【免费下载链接】difyBuild Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.项目地址: https://gitcode.com/GitHub_Trending/di/dify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考