资讯动态

Wasp 的技术愿景:用声明式 Spec 描述整座 Web 应用

发布时间:2026/9/15 15:20:10 来源:尧图企业网站定制
Wasp 的技术愿景用声明式 Spec 描述整座 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/wasp导读本文以 web/versioned_docs/version-0.15/vision.md 为骨架解读 Wasp 的核心设计哲学它不是又一个 Web 框架库而是一门面向 Web 应用的声明式描述语言DSL / Spec。文章将逐一拆解愿景中Entity 一等公民、开箱即用 CRUD、智能查询与操作、逃生舱机制、由框架托管基础设施等构想并用当前仓库中的wasp.sh/spec构造器实现与main.wasp.ts示例逐一印证。读完你既能理解 Wasp 为什么这样设计也能看到这些理念在今天的代码库中是如何落地的。出发点让开发 Web 应用像写需求文档一样简单愿景文档的第一句话就定下了基调With Wasp, we want to make developing web apps easy and enjoyable, for novices and experts in web development alike.——无论是新手还是专家用 Wasp 开发 Web 应用都应当既简单又愉快。理想的编程体验是用 Wasp 写应用感觉像是在用人类语言描述一个应用像撰写一份规格说明文档——你主要描述需求what you want而不是实现细节how its done。同时从零创建一个可以上生产的 Web 应用应当容易把它部署到生产环境应当顺畅直接。在 Wasp 0.15 时代的愿景中这个目标的载体被明确为一门编程语言DSL而在当前仓库的 web/docs/vision.md及version-0.25版本中这一表述演进为 spec-driven framework、Declarative, statically typed spec。语言从DSL转向静态类型 Spec但内核一致用户声明需求Wasp 负责实现。为什么必须是语言/Spec而不是库愿景给出了一个关键论断we believe Wasp needs to be a programming language (DSL) and not a library - we want to capture all parts of the web app into one integrated system。理由是Web 应用横跨前端、后端、数据模型、认证、任务调度等多个层面一个库只能寄生在某一层生态里而 Wasp 想把 Web 应用的所有部分捕获进一个为它量身定制的、集成的系统。只有让 Wasp 处于语言层它才能统一描述路由、页面、数据操作、认证这些跨层概念。今天的仓库正是这样实现的waspc/data/packages/spec/src/spec/publicApi/constructors.ts定义了app、page、route、query、action、crud、job、api等一套构造器。以 examples/ask-the-documents/main.wasp.ts 为例整个应用的骨架名称、认证方式、路由、操作浓缩在一个声明式文件中import { action, app, page, query, route } from wasp.sh/spec; export default app({ name: askTheDocuments, wasp: { version: 0.26.0 }, title: PG Vector Example, auth: { userEntity: User, methods: { google: { userSignupFields, configFn: getGoogleAuthConfig } }, onAuthFailedRedirectTo: /, }, spec: [ route(RootRoute, /, page(Main), { prerender: true }), query(getDocuments, { entities: [Document] }), action(askDocuments, { entities: [Document] }), action(deleteDocument, { entities: [Document] }), ], });这正是用声明式规格描述应用的直观体现——没有一行 Express 路由代码也没有手工搭建认证中间件。声明式胶水代码不替代、只粘合愿景同时强调trying to capture every single detail in one language would not be reasonable。React 之于组件、CSS/HTML 之于样式与标记、JS/TS 之于逻辑这些专用方案已经解决得很好了Wasp 不打算用自己替代它们。Wasp 的定位是声明式胶水declarative glue它把这些专用方案粘合成一个整体并在它们之上提供更高层次的 Web 应用抽象。这一点在仓库中随处可见。constructors.ts中的page()直接接收一个 React 组件引用export function page(component: Page[component], config?: PageConfig): Page { return { kind: page, component, ...config }; }而main.wasp.ts中通过with { type: ref }引入外部源码文件import { Layout } from ./src/Layout with { type: ref }; import { Main } from ./src/pages/MainPage with { type: ref };也就是说复杂业务逻辑仍用 JS/TS 和 React 编写通过ref引用Wasp Spec 只负责描述它们如何被组织进应用。愿景中的可内联混用也可通过外部文件提供在 examples/kitchen-sink/main.wasp.ts 中得到了双重体现——既有直接写在main.wasp.ts里的emailSender、webSocket配置也有通过import { crudSpec } from ./src/features/crud/crud.wasp拆分到多个 Spec 文件/模块的做法。横向语言理解 Web 应用概念的多文件 Spec愿景设想 Wasp 是一门horizontal language规则简单却理解大量 Web 应用概念路由、认证、数据操作、定时任务……并支持多文件/模块与库。当前仓库的wasp.sh/spec正是对横向的兑现constructors.ts中的构造器覆盖了 App、Page、Route、Query、Action、Api、ApiNamespace、Job、Crud 等全部应用概念并且每个都是简单的基本规则——以job为例export function job(fn: Job[fn], config: JobConfig): Job { return { kind: job, fn, ...config }; }而 kitchen-sink 示例把这一理念发挥到极致main.wasp.ts只做汇总认证、CRUD、任务、流式输出等各自定义在独立的.wasp.ts模块中如src/features/jobs/jobs.wasp、src/features/crud/crud.wasp再统一装配进spec数组——这就是愿景所说的多文件/模块、库支持。Entity一等公民的数据模型愿景将数据模型列为一等公民first-class citizenEntity 用 Wasp 自身语法定义与其余功能紧密集成是一切围绕的中心概念。在今天的仓库中数据模型由 Prisma 定义schema.prisma并通过 Wasp 与之深度绑定。以 examples/ask-the-documents/schema.prisma 为例model User { id Int id default(autoincrement()) email String? } 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 }注意两点其一askTheDocuments应用是PG Vector 向量检索示例——embedding字段直接声明为Unsupported(vector(1536))并在datasource中启用了pgvector扩展展示 Wasp 应用同样能承载 AI 时代的向量数据其二Wasp 的每个操作都通过entities: [Document]声明其访问的数据模型让 Entity 成为连接 Spec 与业务逻辑的枢纽。开箱即用的 CRUD愿景承诺基于 Entity 提供开箱即用out of the box的 CRUD UI让应用快速跑起来同时保持一定程度的可定制性。constructors.ts中的crud()构造器是这一承诺的实现为某个 Prisma Entity 自动生成查询与操作查询/动作每个操作既可启用默认实现、可设为公开isPublic也可用overrideFn替换为自定义实现export function crud(name, entity, operations): Crud { return { kind: crud, name, entity, operations }; }kitchen-sink 示例 examples/kitchen-sink/src/features/crud/crud.wasp.ts 展示了实际用法crud(tasks, Task, { getAll: { isPublic: true }, get: {}, create: { overrideFn: createTaskOverride }, update: {}, });可定制到一定程度体现在两个维度isPublic控制是否免认证访问overrideFn则允许注入自定义的创建/更新逻辑——这正是愿景中defaults 加 customization模式的落地。智能操作Query 与 Action弥合客户端-服务端鸿沟愿景描述了一个理想状态Smart operations (queries and actions)在大多数情况下自动判断何时需要更新即便不满足也很容易通过自定义逻辑补偿用户尽可能少地为客户端-服务端之间的鸿沟操心。constructors.ts中query()与action()的 JSDoc 恰好把自动部分讲清楚了Query是服务端只读操作客户端通过useQuery调用并缓存在config.entities中列出其读取的 Entity 后Wasp 会把对应的 Prisma 委托注入context.entities并在相关 action 修改这些数据时自动使客户端缓存失效cache invalidation。Action是服务端写操作同样在entities里声明后运行时会触发相关 Query 缓存的失效。也就是说操作声明了它动哪些数据这一条信息被 Wasp 用来完成自动的数据同步让客户端代码无需手动刷新。以 ask-the-documents 为例前端只需useQuery(getDocuments)当embedDocument等 action 写入Document后列表会自动更新——这正是智能操作愿景在源码层面的直接证据。逃生舱Hatches需要时才出现的定制入口愿景提出Wasp 应在所有正确的位置提供逃生舱escape mechanisms/hatches允许定制应用但这些机制平时保持隐藏直到你需要它们。仓库中的典型逃生舱包括overrideFnCRUD 自动生成的实现可被自定义函数整体替换见上文 crud 示例不必推翻整个 Spec。自定义 API 端点api(method, path, fn)用于 Webhook、文件上传等 query/action 模型容纳不了的 HTTP 交互apiNamespace还能为某路径前缀批量挂中间件。服务端/客户端 Setup 与中间件examples/kitchen-sink/main.wasp.ts 中通过server.setupFn、server.middlewareConfigFn、client.setupFn挂入自己的初始化逻辑与中间件配置。ref导入用with { type: ref }引入任意外部 JS/TS 代码这是最大的逃生舱——任何 Wasp 没覆盖的逻辑都能用原生代码写。这些机制平时不占用心智需要时随时打开正是hidden until you need them。由框架托管的基础设施关注点愿景明确服务端渲染SSR、缓存、打包、安全等一律由 Wasp 负责——你告诉 Wasp 你想要什么Wasp 自己想办法做到。仓库中的落地证据包括预渲染prerenderingroute(RootRoute, /, page(Main), { prerender: true })中的prerender选项让路由在构建期渲染为静态 HTML对应 web/docs/advanced/prerendering.mdconstructors.ts的route()JSDoc 还说明可传入具体路径数组来预渲染动态路由的特定实例。懒加载route()支持lazy配置决定是否关闭页面 bundle 的懒加载。环境变量校验server.envValidationSchema/client.envValidationSchema让配置在启动时即被 Zod 之类的 schema 校验见 examples/kitchen-sink/main.wasp.ts。认证安全auth配置块统一声明用户实体、登录方式与失败跳转路径认证基础设施由 Wasp 生成。部署尽最大可能地简单愿景要求as simple deployment to production/staging as it gets。仓库中每个示例如examples/ask-the-documents/fly-server.toml、examples/ask-the-documents/fly-client.toml、examples/waspello/fly-server.toml都预置了面向 Fly.io 的部署配置examples/kitchen-sink/Dockerfile则提供了容器化路径scripts/get-wasp-database-provider.sh与 web/docs/deployment/intro.md 也都在支撑一条命令部署的体验。部署时 Wasp 负责构建产物、数据库迁移与静态资源托管用户只需声明目标环境。不绑定单一实现开放的语言层愿景的最后一条是极具前瞻性的设计约束the Wasp Spec will not be coupled with the single implementation——官方提供参考实现但他人可以提供编译到不同 Web 技术栈的其他实现。这一条意味着 Wasp 的语言/规格与其生成器编译器是分离的。从仓库结构看waspc/src/Wasp/Generator/是官方编译器Haskell 实现waspc/data/packages/spec/定义 Spec 的构造器与类型examples/下的各示例通过wasp.sh/spec描述应用。Spec 层保持技术栈无关理论上允许第三方实现面向别的技术栈的编译器——这也是Wasp 是语言而不是库这一判断的必然推论。从愿景到现实一句话总结0.15 时代的愿景文档描述的是我们想象中 Wasp 的样子而当前仓库已经把它变成了Wasp 现在就是这个样子wasp.sh/spec提供了一套理解 Web 应用概念的声明式构造器Entity 是一等公民CRUD 开箱即用query/action 自动管理缓存同步hatches 在需要时随时打开SSR/预渲染/安全/部署由框架托管。开发者要做的仍然是愿景开篇那句话——像写规格说明一样描述你的应用剩下的交给 Wasp。想深入验证这些理念可以从这几个文件开始examples/ask-the-documents/main.wasp.ts最小而完整的 Spec、examples/kitchen-sink/main.wasp.ts全功能示例的装配、waspc/data/packages/spec/src/spec/publicApi/constructors.ts构造器的权威定义以及最新愿景文档 web/docs/vision.md。【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价