前端构建系统与配置
前端构建系统与配置
相关源文件
本章引用的主要源码文件:
.github/actions/setup-web/action.ymlapi/Dockerfilepackage.jsonpackages/dify-ui/README.mdpackages/dify-ui/src/dialog/index.tsxpackages/dify-ui/src/toast/__tests__/index.spec.tsxpackages/dify-ui/vite.config.tspackages/dify-ui/vitest.setup.tspnpm-lock.yamlpnpm-workspace.yamlsdks/nodejs-client/tsconfig.jsonsdks/nodejs-client/vite.config.tsvite.config.tsweb/.env.exampleweb/Dockerfileweb/app/components/base/form/index.stories.tsxweb/app/components/header/account-setting/members-page/edit-workspace-modal/__tests__/index.spec.tsxweb/app/layout.tsxweb/config/index.tsweb/contract/router.tsweb/docker/entrypoint.shweb/eslint.config.mjsweb/eslint.constants.mjsweb/knip.config.tsweb/types/feature.tsweb/vite.config.ts
目的与范围
本文档记录了 Dify Web 应用的前端构建系统、工具配置和开发环境搭建。内容涵盖包管理、构建工具、环境变量、样式系统、代码质量保障以及 Docker 容器化流程。
Dify 前端是一个 [Next.js] 项目,同时也支持通过 [vinext] 和 [Vite+] 进行开发,以提供更佳的开发者体验 web/Dockerfile:45-46。
技术栈概览
Dify Web 前端采用现代 JavaScript 工具链构建,核心技术如下:
| 技术 | 版本 | 用途 |
|---|---|---|
| Next.js | 16.2.6 | 支持 SSR/SSG 的 React 框架 pnpm-workspace.yaml:198 |
| React | 19.2.6 | UI 库 pnpm-workspace.yaml:206 |
| pnpm | 11.1.1 | 快速、磁盘高效的包管理器 package.json:5 |
| TypeScript | 6.0.3 | 类型安全的 JavaScript pnpm-workspace.yaml:234 |
| Tailwind CSS | 4.3.0 | 实用优先的 CSS 框架 pnpm-workspace.yaml:231 |
| Vite | 0.1.20(Vite+) | 开发服务器和构建工具 pnpm-workspace.yaml:240 |
| Vitest | 0.1.20(Vite+) | 单元测试框架 pnpm-workspace.yaml:243 |
| ESLint | 10.3.0 | 代码检查 pnpm-workspace.yaml:163 |
技术栈依赖关系图
来源:pnpm-workspace.yaml:1-249,package.json:1-10
使用 pnpm 进行包管理
工作区配置
Dify 采用 pnpm workspaces 管理的单体仓库(monorepo)结构。JavaScript 依赖由仓库根目录下的工作区文件管理:package.json、pnpm-lock.yaml 和 pnpm-workspace.yaml web/Dockerfile:24。
主要工作区包:
web:主 Next.js 应用pnpm-workspace.yaml:24e2e:Playwright 端到端测试pnpm-workspace.yaml:25sdks/nodejs-client:官方 Dify Node.js SDKpnpm-workspace.yaml:26packages/*:共享内部库,包括dify-uipnpm-workspace.yaml:27
依赖目录化
项目使用 pnpm 的 catalog 功能集中管理工作区中的依赖版本,确保一致性并简化升级 pnpm-workspace.yaml:60-249。
常见依赖覆盖: 为解决安全性和兼容性问题,pnpm-workspace.yaml 中覆盖了多个包:
lodash:强制使用4.18.0pnpm-workspace.yaml:41dompurify:强制使用3.4.2pnpm-workspace.yaml:155vite:替换为npm:@voidzero-dev/vite-plus-core@0.1.20pnpm-workspace.yaml:56
Vite 和 Vitest 配置
虽然项目是 Next.js 应用,但它利用 Vite+ 和 vinext 来提供更好的开发和测试体验 web/vite.config.ts:4-6。
Vite 管线
web/vite.config.ts 处理多种模式,包括标准开发、测试和 Storybook web/vite.config.ts:16-21。
Vite 插件集成
- vinext:提供核心开发体验,支持可选的 SSR
web/vite.config.ts:51。 - tailwindcss/vite:处理 CSS 处理管线
web/vite.config.ts:49。 - customI18nHmrPlugin:为国际化文件启用热模块替换
web/vite.config.ts:52。 - mdx-stub:在测试期间桩化
.mdx文件,以便导入这些文件的组件可以进行单元测试web/vite.config.ts:26-34。
测试设置
测试由 Vitest 驱动,使用 happy-dom 环境 web/vite.config.ts:83-85。
测试配置详情:
- 全局变量:启用后允许直接使用
describe、it和expect而无需导入web/vite.config.ts:86。 - 设置文件:
./vitest.setup.tsweb/vite.config.ts:87。 - 覆盖率:使用
v8提供者,为 CI 环境生成json-summaryweb/vite.config.ts:88-90。
来源:web/vite.config.ts:1-94,package.json:10-17
环境变量映射
前端依赖环境变量进行 API 通信和功能开关控制。这些变量在 web/.env.example 中定义,并通过集中式配置访问 web/.env.example:1-30。
关键环境变量:
| 变量 | 描述 |
|---|---|
NEXT_PUBLIC_API_PREFIX | 控制台 API 的基础 URL web/config/index.ts:18-21 |
NEXT_PUBLIC_PUBLIC_API_PREFIX | WebApp API 的基础 URL web/config/index.ts:22-25 |
NEXT_PUBLIC_SOCKET_URL | 用于实时更新的 WebSocket 服务器 URL web/config/index.ts:119-122 |
web/config/index.ts 文件处理这些变量的映射和校验,提供诸如 IS_CE_EDITION 和 IS_PROD 等常量 web/config/index.ts:37-48。
样式与布局
主题与提供者设置
Dify 在根布局中实现了多层提供者架构,用于处理主题、国际化和状态管理 web/app/layout.tsx:62-85。
提供者层级:
- JotaiProvider:原子状态管理
web/app/layout.tsx:62 - ThemeProvider:集成 next-themes,支持亮色/暗色/系统模式
web/app/layout.tsx:63-69 - TanstackQueryInitializer:React Query 客户端设置
web/app/layout.tsx:71 - I18nServerProvider:服务端 i18n 支持
web/app/layout.tsx:72
共享 UI 库:dify-ui
项目使用共享组件库 @langgenius/dify-ui 提供核心 UI 原语,确保应用内的一致性 web/app/layout.tsx:2-3。
数据流:通知系统 Toast 系统使用 ToastHost 全局管理和渲染通知 web/app/layout.tsx:73。
来源:web/app/layout.tsx:1-91,web/config/index.ts:1-50
代码质量与检查
项目使用基于 @antfu/eslint-config 的严格 ESLint 配置,并包含自定义的 Dify 插件 web/eslint.config.mjs:4-19。
检查管线:
关键检查约束:
- 限制导入:强制使用
@/next包装器而非直接导入nextweb/eslint.constants.mjs:10-15,并阻止使用next/image,推荐使用原生标签web/eslint.constants.mjs:19-20。 - 国际化校验:确保翻译文件有效且键值扁平
web/eslint.config.mjs:144-154。 - UI 一致性:阻止直接导入
@base-ui/react或@floating-ui/*,要求使用@langgenius/dify-ui原语替代web/eslint.constants.mjs:32-49。
来源:web/eslint.config.mjs:1-166,web/eslint.constants.mjs:1-87
Docker 构建流程
前端使用多阶段 Dockerfile 进行容器化,以优化镜像大小和构建速度 web/Dockerfile:1-90。
构建阶段:
- base:设置 Node.js 22 并启用
corepack以支持pnpmweb/Dockerfile:2-14。 - packages:使用
pnpm install --frozen-lockfile安装工作区依赖web/Dockerfile:20-35。 - builder:执行
pnpm build(Next.js)和pnpm build:vinextweb/Dockerfile:37-46。 - production:准备最终运行时环境,将独立服务器文件复制到
/app/targets/web/Dockerfile:49-80。
入口点逻辑: web/docker/entrypoint.sh 脚本将标准环境变量(例如 CONSOLE_API_URL)映射到 Next.js 前端在运行时所需的 NEXT_PUBLIC_ 前缀变量 web/docker/entrypoint.sh:15-24。然后启动相应的服务器(Next.js 独立模式或 Vinext)web/docker/entrypoint.sh:48-52。
来源:web/Dockerfile:1-90,web/docker/entrypoint.sh:1-53