
Wasp kitchen-sink 示例应用全解析Wasp CLI 开发测试平台与全特性展示场【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/wasp导读examples/kitchen-sink是 Wasp 仓库中一个样样俱全的示例应用它既是 Wasp 团队为 contributors 准备的低成本开发测试平台也是向开发者集中展示 Wasp 全栈框架各项能力的演示工程。本文将带你梳理这个应用的定位、初始化流程、环境变量管理、开发/运行/测试全链路并深入到其 TypeScript 配置与源码实现中逐一解读认证、查询/动作、后台任务、CRUD、自定义 API、数据库种子、WebSocket 等特性在真实工程里是如何声明的。读完你既能快速把它跑起来也能把它当作 Wasp 官方功能的活字典按图索骥。kitchen-sink 的设计目标既是测试床也是特性清单从 README.md 开篇可以明确看到这个应用承担两大使命首要目的让 Wasp 贡献者轻松地测试开发版本的 Wasp CLI。Wasp 的 CLIHaskell 实现位于 waspc/ 目录在迭代过程中需要不断验证wasp start、wasp db migrate-dev、wasp build等命令的可用性kitchen-sink 就是那个随时可以拿来跑一遍的靶场。次要目的尽可能多地演示 Wasp 特性。README 特别说明并非所有特性都能同时共存例如email与usernameAndPassword两种认证方式互斥但在约束范围内应尽可能覆盖。此外它是 Waspe2e 应用测试的主战场——任何新增或修改的特性都应尽量在这个应用里补充对应的端到端测试。这一点在 e2e-tests/tests/ 目录的 19 个 spec 文件中得到印证auth.spec.ts、crud.spec.ts、jobs、websocket.spec.ts等我们将在后文详述。项目结构一个用 TypeScript 声明一切的应用kitchen-sink 采用 Wasp 较新的 TypeScript 定义方式核心配置集中在 main.wasp.ts业务代码按特性feature分目录组织在 src/features/ 下每个特性通过独立的*.wasp.ts文件导出自己的声明片段再由main.wasp.ts汇总。// main.wasp.ts节选 import { app, page, route } from wasp.sh/spec; // ... export default app({ name: KitchenSink, wasp: { version: 0.26.0 }, title: Wasp Kitchen Sink, webSocket, auth: authConfig, server: { setupFn: serverSetup, middlewareConfigFn: serverMiddlewareFn, envValidationSchema: serverEnvValidationSchema, }, client: { rootComponent: App, setupFn: clientSetup, envValidationSchema: clientEnvValidationSchema, }, db, emailSender: { provider: SMTP, defaultFrom: { email: kitchen-sinkwasp.sh } }, spec: [ /* route、page、authSpec、operationsSpec、jobsSpec、apisSpec、crudSpec ... */ ], });从这段声明可以看到一个完整的 Wasp 应用骨架应用级配置name/wasp版本/head标签、服务端与客户端的setupFn、中间件配置函数、环境变量校验 schema、数据库配置、SMTP 邮件发送器以及按特性拆分的路由与能力清单spec。按特性组织的 src 目录src/features/ ├── apis/ 自定义 HTTP API 与命名空间 ├── auth/ 多 Provider 认证Google/GitHub/Discord/Slack/Microsoft/Email ├── chat/ WebSocket 实时通信 ├── crud/ CRUD 操作与覆盖函数 ├── db/ Prisma 设置与数据库种子 ├── jobs/ PgBoss 后台任务与定时任务 ├── lazy-loading/ 懒加载路由演示 ├── operations/ Query/Action 与序列化演示 ├── prerender/ 静态预渲染演示 └── streaming/ Server-Sent Events 流式响应这种一个特性一个目录 一个*.wasp.ts声明文件的组织方式本身就是对 Wasp以声明式代码驱动全栈能力理念的最佳示范。初始化与依赖安装首次拿到仓库后进入 kitchen-sink 目录执行依赖安装wasp install该命令会基于 main.wasp.ts 中的wasp: { version: 0.26.0 }校验 CLI 版本兼容性并为项目生成.wasp输出目录。项目本身是 npm workspace 结构package.json 中声明了workspaces: [.wasp/out/*, .wasp/out/sdk/wasp]即把 Wasp 生成的前端、后端与 SDK 包作为本地 workspace 链接保证运行时依赖与生成代码始终一致。环境变量从最小启动到团队共享最小启动复制示例文件kitchen-sink 提供了带假值的示例环境变量文件最小化配置即可启动cp .env.server.example .env.serverREADME 明确说明这样创建的.env.server中各项变量都是 dummy 值应用可以正常启动但并非所有特性都能工作——例如 Google Auth、GitHub Auth 等第三方 Provider 需要真实的 API Key 才能完成 OAuth 流程。配置这些 Provider 的细节可查阅 Wasp 官方文档中对应章节。团队共享dotenv-vault对于 Wasp 团队成员kitchen-sink 通过 package.json 中的脚本封装了 dotenv-vault外部工具此处仅说明命令本身# 拉取共享的 .env.server含真实 API Keys npm run env:pull # 将本地改动同步回共享配置 npm run env:push对应的脚本定义为env:pull: npx dotenv-vaultlatest pull development .env.server, env:push: npx dotenv-vaultlatest push development .env.server这套机制解决了本地开发需要真实密钥、但密钥不应进入 Git的矛盾适合团队协作场景。环境变量的运行时校验kitchen-sink 还示范了 Wasp 的环境变量校验能力。src/env.ts 使用 Zod 分别定义了服务端与客户端的校验 schemaimport { defineEnvValidationSchema } from wasp/env; import * as z from zod; export const serverEnvValidationSchema defineEnvValidationSchema( z.object({ TEST_ENV_VAR: z.string({ error: TEST_ENV_VAR is required. }), }), ); export const clientEnvValidationSchema defineEnvValidationSchema( z.object({ REACT_APP_NAME: z.string().default(Kitchen Sink App), }), );可以看到服务端变量TEST_ENV_VAR缺失时会抛出自定义错误信息客户端变量REACT_APP_NAME则提供了默认值Kitchen Sink App。这两个 schema 分别挂在 main.wasp.ts 的server.envValidationSchema与client.envValidationSchema上在应用启动阶段即完成校验属于配置即验证的实践。运行应用三步启动kitchen-sink 的运行方式与任何 Wasp 应用完全一致README 给出了标准流程1. 启动数据库独立终端wasp start db该命令拉起 Postgres 容器。从 schema.prisma 可以看到数据库 provider 固定为postgresqlDATABASE_URL由环境变量注入。2. 迁移数据库如需要另一个终端wasp db migrate-devkitchen-sink 的迁移记录都在 migrations/ 目录下涵盖初始表、地址字段、会话、投票、可见性枚举、邮件验证钩子、大写文本任务等多次演进。以 schema.prisma 当前模型为例核心实体包括User除基础字段外还带有isOnAfterSignupHookCalled、isOnAfterLoginHookCalled、isOnAfterEmailVerifiedHookCalled、numTimesOnAfterEmailVerifiedCalled等钩子调用记录字段——它们正是 e2e 测试中验证认证钩子是否被正确触发的依据Task含TaskVisibility枚举PRIVATE/LINK_ONLY/PUBLIC演示枚举类型在查询与 CRUD 中的应用TaskVote多对多关系的投票表UppercaseTextRequest配合后台任务演示提交请求 → 异步处理 → 查询结果的完整链路。3. 启动应用第三个终端wasp start4. 浏览器打开localhost:3000即可看到应用首页。使用开发版 Wasp CLIwaspc/run 脚本kitchen-sink 的首要定位是测试开发版Wasp CLI因此 README 特别给出了三种调用方式# 从 kitchen-sink 目录内使用仓库内脚本的相对路径 ../../waspc/run wasp-cli start db # 或为该脚本设置别名后使用绝对路径 wrun wasp-cli start db # 或将开发版 waspc 二进制全局安装后直接调用 wasp-cli start db这里的 waspc/run 脚本是 Wasp 仓库内为 contributors 准备的开发用包装器它会构建或复用已构建的waspc Haskell 可执行文件并转发后续参数从而让你总是用最新源码的 CLI 行为来驱动 kitchen-sink而不是已发布的正式版本。这对贡献者验证 CLI 改动、排查回归至关重要任何一个start、build、db子命令的改动都可以在 kitchen-sink 上立刻得到真实反馈。全特性深度解读从声明到实现kitchen-sink 的价值在于它几乎覆盖了 Wasp 的每一项核心能力。下面逐特性拆解其声明文件与配套实现。1. 认证六种 Provider 完整生命周期钩子src/features/auth/auth.wasp.ts 是仓库里信息量最大的声明文件之一展示了 Wasp 认证体系的全貌五种 OAuth Providerslack、discord、google、gitHub、microsoft每个 Provider 都带有configFn读取对应环境变量、组装 OAuth 配置与userSignupFields声明注册时需要收集的额外用户字段对应实现位于 providers/邮箱密码认证email方法配置了fromField、邮件验证getEmailContentFn 客户端验证路由EmailVerificationRoute和密码重置getPasswordResetContentFnPasswordResetRoute认证钩子onBeforeSignup、onAfterSignup、onAfterEmailVerified、onBeforeLogin、onAfterLogin实现见 hooks.ts。这些钩子会修改 User 实体上那些isOnAfter*HookCalled字段供 auth-hooks.spec.ts 端到端验证自定义注册流程/custom-signup自定义 Signup 页面 自定义 action见 customSignup.ts与/manual-signup手动注册页两条演示路由对应 custom-signup.spec.ts 与 manual-signup.spec.ts跳转策略onAuthFailedRedirectTo: /login、onAuthSucceededRedirectTo: /。认证相关路由注册、登录、密码重置、邮件验证、Profile 页统一由authSpec导出并在main.wasp.ts中注册其中/profile页使用了{ authRequired: true }保护。2. Query / Action类型安全的 RPC 与实体跟踪src/features/operations/operations.wasp.ts 展示了 Wasp 的 RPC 核心query(getTasks, { entities: [Task] }), query(getNumTasks, { entities: [Task], auth: false }), action(createTask, { entities: [Task] }), action(updateTaskIsDone, { entities: [Task] }), // ... query(getSerializedObjects),query/action的entities字段声明操作涉及的数据模型Wasp 据此生成自动缓存失效逻辑——相关的测试见 cacheInvalidation.test.tsauth: false可标记无需认证的公开查询如getNumTasks页面路由/tasks、/tasks/:id都带authRequired: true特别地getSerializedObjects与 SerializationPage.tsx 用来演示 Wasp 对 Date、特殊对象等复杂类型在客户端/服务端之间的序列化处理配套 serialization.spec.ts 测试。3. 后台任务PgBoss 执行器与 Cron 调度src/features/jobs/jobs.wasp.ts 覆盖了 Wasp 后台任务的两个核心场景job(uppercaseTextJob, { executor: PgBoss, entities: [UppercaseTextRequest], }), job(mySpecialJob, { executor: PgBoss, performExecutorOptions: { pgBoss: { retryLimit: 1 } }, entities: [Task], }), job(mySpecialScheduledJob, { executor: PgBoss, schedule: { cron: 0 * * * *, args: { foo: bar }, executorOptions: { pgBoss: { retryLimit: 2 } }, }, }),按需任务uppercaseTextJob接收一个UppercaseTextRequest记录异步完成文本大写转换并回写结果——配套 uppercaseText.ts 与 JobsPage任务级重试策略mySpecialJob通过performExecutorOptions.pgBoss.retryLimit设置重试次数定时任务mySpecialScheduledJob用cron: 0 * * * *声明每小时执行并携带静态参数args与调度级重试配置executorOptions。从源码结构看所有后台任务均指定executor: PgBoss这意味着 kitchen-sink 的 job 依赖 Postgres与 schema.prisma 的UppercaseTextRequestState枚举PENDING/SUCCESS/ERROR共同构成任务状态机对应 e2e 测试为 async-jobs.spec.ts。4. CRUD声明式增删改查 覆盖函数 部分 CRUDsrc/features/crud/crud.wasp.ts 演示了三种 CRUD 用法crud(tasks, Task, { get: {}, getAll: { overrideFn: crudGetAllTasks }, create: { overrideFn: crudCreateTask }, update: {}, delete: {}, }), // 故意只声明 getAll覆盖用户未请求的操作不应出现在生成代码中的情形 crud(taskVotes, TaskVote, { getAll: {} }),一个crud声明即可为指定实体生成get/getAll/create/update/delete全套操作overrideFn允许用自定义函数替换默认实现例如在创建任务前补充业务逻辑实现在 crud.tstaskVotes示例故意只声明getAll用于验证 Wasp 生成的代码不会包含用户未请求的操作——这是对最小生成面的测试用例属于 contributor 场景下的边界验证。5. 自定义 API方法、命名空间与中间件src/features/apis/apis.wasp.ts 覆盖了自定义 REST API 的声明方式api(ALL, /foo/bar, fooBar, { middlewareConfigFn: fooBarMiddlewareFn, entities: [Task], }), apiNamespace(/bar, { middlewareConfigFn: barNamespaceMiddlewareFn }), api(GET, /bar/baz, barBaz, { auth: false, entities: [Task] }), api(POST, /webhook/callback, webhookCallback, { middlewareConfigFn: webhookCallbackMiddlewareFn, auth: false, }),api声明支持指定 HTTP 方法ALL/GET/POST、路径、处理函数与可选配置apiNamespace可以为路径前缀统一注入中间件/bar下的所有 API 共享barNamespaceMiddlewareFnauth: false用于公开端点如 webhook 回调entities声明同样驱动缓存失效中间件实现位于 apis.ts配套测试 custom-apis.spec.ts。6. 数据库种子数据与 Prisma 设置函数src/features/db/db.wasp.ts 演示了数据层的两个扩展点export const db: Db { seeds: [devSeedSimple, prodSeed], prismaSetupFn: setUpPrisma, };seeds区分开发种子devSeedSimple与生产种子prodSeed实现见 seeds.tsprismaSetupFn允许在 PrismaClient 创建时注入自定义设置如日志、扩展实现见 prisma.ts并有 prisma-setup-fn.spec.ts 做端到端验证。7. 其他特性WebSocket、Streaming、预渲染、懒加载main.wasp.ts的spec中还导入了其余特性WebSocket来自 chat.wasp.ts通过webSocket配置与 webSocket.ts 实现实时聊天测试见 websocket.spec.tsStreamingSSEstreaming.wasp.ts 声明流式 APIStreamingTestPage.tsx 展示逐块接收响应测试见 streaming.spec.ts预渲染prerender.wasp.ts 覆盖静态预渲染、带参数的预渲染实例与 hydration mismatch 场景对应 prerender.spec.tsmain.wasp.ts中route(HomeRoute, /, page(HomePage), { prerender: true })即首页预渲染示例懒加载lazyLoading.wasp.ts 演示 Eager/Lazy 两种加载模式测试见 lazy-loading.spec.tsRPC 类型安全专项src/rpcTests/ 通过 TS 与 JS 两套定义definitions.ts 与 jsDefinitions.js对比验证 Wasp 生成的 RPC 客户端在两种语言下的类型/行为一致性。端到端测试Playwright 双视口矩阵kitchen-sink 的 e2e 测试是 Wasp 验证框架行为的主要手段。测试入口为npm run test该脚本实际执行见 package.jsontest: npm run test:install-deps DEBUGpw:webserver playwright test --config e2e-tests/, test:install-deps: playwright install --with-depsPlaywright 配置要点playwright.config.ts 中值得注意的设计两个测试项目chromium桌面 Chrome与Mobile ChromePixel 5 视口覆盖响应式场景webServer 自动拉起通过WASP_APP_RUNNER_CLI_CMD、WASP_RUN_MODE默认dev、WASP_CLI_CMD默认wasp-cli三个环境变量拼出启动命令run-wasp-app dev --path-to-app../ --wasp-cli-cmdwasp-cli等待localhost:3001就绪后开始测试超时 180 秒reuseExistingServer: !process.env.CI允许本地复用已运行的服务部署模式当WASP_RUN_MODEdeployed时不再自启 webServer而是测试已部署的实例PLAYWRIGHT_SERVER_URL指定地址CI 行为forbidOnly、retries: 2、单 worker、dotreporter 均为 CI 环境专用。测试覆盖清单e2e-tests/tests/ 下的 19 个 spec 文件与上文特性一一对应auth.spec.ts、auth-hooks.spec.ts、custom-signup.spec.ts、manual-signup.spec.ts、user-api.spec.ts、operations.spec.ts、serialization.spec.ts、async-jobs.spec.ts、crud.spec.ts、custom-apis.spec.ts、websocket.spec.ts、streaming.spec.ts、prerender.spec.ts、lazy-loading.spec.ts、catch-all-route.spec.ts、prisma-setup-fn.spec.ts等另有 mailcrab.ts 用于测试邮件类功能验证邮件、密码重置邮件。这让 kitchen-sink 成为名副其实的特性回归测试中心。小结如何用好 kitchen-sink综合来看kitchen-sink 的三种典型用法对应三条路径作为普通 Wasp 开发者复制.env.server.example即可wasp installwasp start dbwasp db migrate-devwasp start全流程跑通把首页当作特性导航逐个进入/tasksQuery/Action、/crudCRUD、/jobs后台任务、/apis自定义 API、/chatWebSocket、/serialization序列化、预渲染与懒加载页面感受 Wasp声明即所得的开发体验作为 Wasp 贡献者通过../../waspc/run wasp-cli 子命令用源码级 CLI 驱动应用任何 CLI 改动都能立刻在此验证新增特性时同步补充*.wasp.ts声明、源码实现与 e2e 测试作为测试基础设施npm run test一键跑完双视口 e2e 矩阵配合env:pull/env:push共享真实密钥的团队工作流构成 Wasp 仓库内闭环的质量保障体系。无论从哪个角度切入examples/kitchen-sink 都是理解 Wasp 框架能力边界与工程实践的最佳入口。【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/wasp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考