Wasp 的愿景与实践:用声明式规范像写需求文档一样构建全栈 Web 应用

发布时间:2026/9/14 2:42:23
Wasp 的愿景与实践:用声明式规范像写需求文档一样构建全栈 Web 应用 Wasp 的愿景与实践用声明式规范像写需求文档一样构建全栈 Web 应用【免费下载链接】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/waspWasp 是一个为 AI 时代设计的全栈 Web 开发框架仓库简介将其定位为 batteries-included full-stack framework for the AI era其核心设计愿景写在该项目的 vision 文档历史版本见 version-0.11.8 的 vision.md中让 Web 应用开发对新手和专家都变得简单而愉快让编程体验接近用人类语言描述应用——像写一份需求规格说明书那样主要描述你想要什么而尽量少描述如何实现。读完本文你将理解 Wasp 为什么坚持走声明式规范而非库的路线看到它如何通过 Entity、Queries/Actions、CRUD、逃生舱等概念把复杂全栈能力抽象成声明式代码并能在当前仓库的源码与示例中逐条印证这些设计愿景的落地情况。愿景的起点让开发 Web 应用像写规格文档vision 文档开宗明义地给出目标With Wasp, we want to make developing web apps easy and enjoyable, for novices and experts in web development alike.让 Web 应用开发对新手和专家同样简单、愉快。Wasp 团队追求的理想状态是在 Wasp 中编程感觉就像用人类语言描述一个应用——像写一份规格说明书specification document主要描述需求把实现细节降到最少。同时创建一个可用于生产的新 Web 应用应该很容易把它部署到生产环境也应该直截了当。这正是 Wasp 把应用配置入口文件命名为Wasp Specmain.wasp.ts的原因。在 Wasp Spec 官方文档 中明确写道spec is short for specification: the pages, routes, queries, actions, APIs, jobs and CRUDs that make up your app.spec 是 specification 的缩写构成你应用的页面、路由、查询、动作、API、任务和 CRUD。也就是说你在main.wasp.ts里列出的每一项本质上都是对应用的一份声明式需求而不是命令式的实现步骤。这个理念从 vision 文档一路贯彻到了今天的代码组织方式。为什么必须是规范/语言而不是库vision 文档给出了一个关键论断Wasp 需要是一门编程语言DSL/规范驱动的框架而不是一个库因为团队想把 Web 应用的所有部分纳入一个为这一目的而完美裁剪的、统一集成的系统。与此同时文档也明确划定了边界把每一个细节都塞进同一种语言是不合理的。React负责 UI 组件、CSS/HTML负责设计与标记、JS/TS负责逻辑等方案在各自领域已经做得非常好Wasp 无意取代它们。因此Wasp 的定位是a declarative glue code uniting all these specific solutions and providing a higher-level notion of the web app above them.一种声明式的胶水代码把所有专用方案粘合起来并在它们之上提供更高层次的 Web 应用抽象。这个定位在今天的仓库里体现得非常直观。看一个最小的示例应用 examples/tutorials/TodoApp/main.wasp.tsimport { action, app, page, query, route } from wasp.sh/spec; import { createTask, updateTask } from ./src/actions with { type: ref }; import { MainPage } from ./src/MainPage with { type: ref }; import { getTasks } from ./src/queries with { type: ref }; export default app({ name: TodoApp, wasp: { version: 0.26.0 }, title: TodoApp, auth: { userEntity: User, methods: { usernameAndPassword: {} }, onAuthFailedRedirectTo: /login, }, spec: [ route(RootRoute, /, page(MainPage, { authRequired: true })), query(getTasks, { entities: [Task] }), action(createTask, { entities: [Task] }), action(updateTask, { entities: [Task] }), ], });这个文件描述了应用拥有什么路由、页面、认证、查询、动作而路由如何渲染、认证如何实现、数据库如何访问全部由 Wasp 在编译/生成阶段接管。React、Prisma、Node.js 这些具体技术成了背后的实现细节。声明式、静态、理解 Web 概念的横向语言vision 文档对未来 Wasp 语言的第一条设想是声明式、静态的语言基础规则简单但理解大量 Web 应用概念——即横向语言horizontal language支持多文件/模块、库。横向的意思是它不把某一层比如视图层或数据层做深而是横跨前后端所有层次提供统一的高层概念路由、页面、认证、数据模型、操作、任务……让开发者不用切换心智模型。而声明式 静态意味着声明本身可被静态分析和验证这为后面的可视化构建器、代码生成、类型安全提供了基础。从仓库源码结构可以印证这一点。Wasp 的编译器实现位于 waspc/src/Wasp/AppSpec 目录包含Crud.hs、Entity、Operation等模块说明编译器的核心数据模型AppSpec正是围绕这些Web 概念建模的。而在 examples/kitchen-sink/main.wasp.ts 中一个应用的规格被拆成了多个模块文件用 TypeScript 的 import 机制组织起来并支持库/模块式复用import { app, page, route } from wasp.sh/spec; import { authSpec } from ./src/features/auth/auth.wasp; import { crudSpec } from ./src/features/crud/crud.wasp; import { jobsSpec } from ./src/features/jobs/jobs.wasp; import { operationsSpec } from ./src/features/operations/operations.wasp; // ... export default app({ name: KitchenSink, wasp: { version: 0.26.0 }, spec: [ route(HomeRoute, /, page(HomePage), { prerender: true }), authSpec, operationsSpec, jobsSpec, apisSpec, crudSpec, // ... ], });与主流技术无缝集成React、CSS、JS 内联或外部提供vision 文档强调 Wasp 要与构建 Web 应用特定复杂部分的最流行技术无缝集成React、CSS、JS 等它们既可以内联与 Wasp 代码混写也可以通过外部文件提供。在今天的 Wasp Spec 实现中这一条对应的是引用导入Reference Imports机制。根据 Wasp Spec 文档任何期望你提供组件或函数的地方如页面组件、查询函数都可以通过with { type: ref }导入标记把src/目录下用普通 TS/JSX 写的代码粘进声明式规格里import { MainPage } from ./src/MainPage with { type: ref }; import { getTasks } from ./src/queries with { type: ref }; export default app({ spec: [page(MainPage), query(getTasks)], });也可以使用ref({ import: ..., from: ... })辅助函数。Wasp 的编译器会读取这些引用把 React 组件、Node.js 函数按声明配置接入生成后的应用。这样一来UI 层继续用你熟悉的 React/JS/TS 书写而它属于哪个页面、需要哪些实体、是否要求登录这些规格则由 Wasp 声明式地连接起来——正是胶水代码愿景的直接落地。逃生舱Hatches需要时出现、平时隐藏的定制机制vision 文档设想 Wasp 拥有逃生舱hatches即转义机制允许你在所有正确的位置定制应用但在你真正需要它们之前保持隐藏。这个理念在仓库中随处可见——Wasp 把大多数细节默认托管但为每个关键点预留了打开舱门的入口查询/动作的entities配置默认情况下 Wasp 根据你声明的实体自动处理权限与依赖追踪需要更细的控制时可以覆盖或自定义。CRUD 操作的overrideFn在 waspc/src/Wasp/AppSpec/Crud.hs 中CrudOperationOptions定义了isPublic :: Maybe Bool与overrideFn :: Maybe ExtImport即每个 CRUD 操作既可以用声明式开关控制公开性也可以用外部函数完全覆盖默认实现——这正是逃生舱的源码级证据。服务端/客户端定制入口在 examples/kitchen-sink/main.wasp.ts 中可以看到server: { setupFn: serverSetup, middlewareConfigFn: serverMiddlewareFn }与client: { rootComponent: App, setupFn: clientSetup }说明框架虽然默认搞定一切但服务端启动逻辑、中间件、客户端根组件都可以按需注入。环境变量校验envValidationSchema见 examples/ask-the-documents/main.wasp.ts允许你用 Zod schema 在编译/启动期校验配置属于需要时才打开的防护舱。Entity数据模型是一等公民vision 文档提出Entity 是一等公民——通过自定义 Wasp 语法定义并与其余功能紧密集成是围绕其构建一切的核心概念之一。当前仓库中Entity 实际上以 Prisma schema 的形式定义见 web/docs/data-model/entities.md。以 examples/ask-the-documents/schema.prisma 为例model Document { id String id default(uuid()) title String url String unique content String embedding Unsupported(vector(1536)) createdAt DateTime default(now()) updatedAt DateTime updatedAt }而Entity 是一等公民体现在你在main.wasp.ts里声明的每一个查询、动作、CRUD都要显式声明它操作哪些实体entities: [Document]Wasp 据此自动生成数据访问代码、进行依赖分析并施加权限。认证配置中的userEntity: User见 TodoApp 示例更是直接把用户这个实体提升为认证系统的核心进一步印证了实体在 Wasp 中的中心地位。开箱即用的 CRUD基于实体生成且可定制vision 文档设想 Wasp 提供基于 Entity 的开箱即用 CRUD UI让开发者快速起步同时允许一定程度的定制。这一设想的落地同样有源码证据。编译器侧waspc/src/Wasp/AppSpec/Crud.hs 定义了 CRUD 的完整模型一个Crud绑定一个Entity并包含五种可选操作——get、getAll、create、update、delete每种操作都可以配置isPublic和overrideFndata CrudOperations CrudOperations { get :: Maybe CrudOperationOptions, getAll :: Maybe CrudOperationOptions, create :: Maybe CrudOperationOptions, update :: Maybe CrudOperationOptions, delete :: Maybe CrudOperationOptions }而验证器 waspc/src/Wasp/AppSpec/Valid.hs 还强制要求CRUD 必须至少定义一个操作CRUD ... must have at least one operation defined.保证声明出来的 CRUD 一定是可用的。运行时这些操作会展开为对应的查询/动作toOperationList并据此生成前后端代码。仓库还提供了 CRUD 使用文档 与 数据操作文档 供进一步查阅。智能操作Queries Actions最小化客户端-服务器鸿沟vision 文档设想 Wasp 提供**智能的查询queries和动作actions**在大多数情况下自动推断何时需要更新即便推断失败也很容易定义自定义逻辑来弥补。用户几乎不需要操心客户端与服务器之间的鸿沟。在 examples/ask-the-documents/main.wasp.ts 中可以看到最典型的用法——所有前后端数据交互都被声明为query/action并标注它们涉及的实体action(embedDocument, { entities: [Document] }), query(getDocuments, { entities: [Document] }), action(searchDocuments, { entities: [Document] }), action(askDocuments, { entities: [Document] }),开发者写的只是一个普通的 TypeScript 函数位于src/documents.tsWasp 负责把它变成暴露给前端的 RPC 端点、生成客户端调用代码并维护端到端类型安全。仓库简介中end-to-end type safety与RPC这两项能力正是这条愿景的当代形态。声明式定义简单组件与操作以及面向非开发者的可视化构建器vision 文档还设想直接在 Wasp 中声明式地定义简单组件和操作同时除了作为语言的 Wasp未来还会有一个**可视化构建器visual builder**来生成/编辑 Wasp 代码让非开发者也能参与开发。由于 Wasp 是声明式的这种构建器被认为会自然而然地由 Wasp 语言派生出来。从仓库现状看声明式操作已经成型上面的query/action/route即声明式定义操作与路由的实例而可视化构建器属于愿景中尚待实现的未来部分。文档在 0.11.8 与当前版本 vision.md 中都明确承认Wasp is still early in its development and therefore far from where we imagine it will be in the futureWasp 仍处于早期开发阶段距离我们设想的样子还很远——这说明本文其余部分描述的是一份愿景蓝图其中一部分已经落地另一部分仍在路上。SSR、缓存、打包、安全交给 Wasp你告诉它要什么它负责怎么做vision 文档写道服务端渲染SSR、缓存、打包、安全等全部由 Wasp 接管——你告诉 Wasp 你想要什么Wasp 想办法做到。仓库中可以找到多项印证预渲染Prerendering在 kitchen-sink 示例 中route(HomeRoute, /, page(HomePage), { prerender: true })以声明方式开启页面预渲染对应 web/docs/advanced/prerendering.md 文档说明 SEO 相关的渲染策略不需要手写构建脚本。认证安全auth: { methods: { usernameAndPassword: {} }, onAuthFailedRedirectTo: /login }一行声明即可获得完整认证体系Wasp 负责密码哈希、会话、授权校验等安全细节可参考 认证文档。打包与静态资源head: [link relicon href/favicon.ico /]等声明由 Wasp 在生成阶段注入到 HTML 模板。简单到极致的部署vision 文档要求部署到生产/预发布环境要尽可能简单。仓库中每个示例应用都自带部署配置文件例如examples/ask-the-documents/下的fly-client.toml、fly-server.toml以及examples/kitchen-sink/Dockerfile。这印证了 Wasp 单命令部署仓库简介中的 single-command deployment的承诺从声明式规格出发Wasp 生成应用代码、Docker 镜像与部署清单部署成为常规流程而非工程难题。更详细的部署方式可参考 web/docs/deployment 目录下的文档。规范与实现解耦不止一个官方实现vision 文档最后一条设想非常关键Wasp 语言/规范不会与单一实现绑定——虽然它带有官方实现但其他人也可以提供编译到不同 Web 技术栈的实现。这一点解释了 Wasp 架构中编译器与生成器分离的设计位于 waspc/src/Wasp/Generator 的生成器负责把 AppSpec 翻译成当前技术栈React Node.js Prisma的代码而规范本身AppSpec是独立的数据模型。官方文档 web/docs/general/spec.md 中把wasp.sh/spec描述为按项目生成的包正是为了让规范 API 能灵活演化而不与某一套具体实现强耦合。结语从愿景蓝图到仓库里的当代落地对比 version-0.11.8 的 vision.md 与当前 web/docs/vision.md 可以发现一个有趣的演进当年的表述是Wasp needs to be a programming language (DSL)今天的表述则是a spec-driven framework规范驱动的框架——措辞变了但核心信念一脉相承用一份声明式、静态、可验证的规格来描述 Web 应用让框架接管实现细节。今天仓库中的示例TodoApp、ask-the-documents、kitchen-sink已经让愿景中的大部分能力变成了可运行的事实声明式路由与页面、Entity 驱动的数据层、智能查询与动作、可定制的 CRUD、认证与安全、预渲染与部署配置。而那些尚未实现的部分——更丰富的声明式组件、可视化构建器、多实现后端——则正如 vision 文档所言是 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),仅供参考