ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

深入解析 Wasp 全栈框架:从声明式 DSL 到编译器的端到端架构

深入解析 Wasp 全栈框架:从声明式 DSL 到编译器的端到端架构 深入解析 Wasp 全栈框架从声明式 DSL 到编译器的端到端架构【免费下载链接】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导读Wasp 是一个面向现代 Web 应用的全栈框架它用一份声明式配置文件描述应用的高层结构页面、路由、认证、数据操作再由内置编译器把这份配置与你的 React、Node.js、Prisma 代码编译成可直接运行的客户端、服务端与部署代码。本文基于 Wasp 官方 0.19 版本文档web/versioned_docs/version-0.19/introduction/introduction.md展开结合本仓库的 Haskell 编译器源码与真实示例应用带你完整理解 Wasp 的秘密酱料——Wasp 编译器并掌握用声明式方式搭建一个带认证、数据模型、服务端操作与前端页面的完整全栈应用的实战方法。一、Wasp 是什么一个构建现代 Web 应用的带电池框架Wasp 是一种构建全栈 Web 应用的强观点opinionated工具。一个 Web 应用通常包含三大组成部分客户端Client前端、服务端Server后端与数据库Database而 Wasp 同时接管这三者让你从拼装技术栈的重复劳动中解脱出来专注于业务本身。1.1 与现有技术栈协同工作Wasp 并不是试图重新发明一切而是聚焦于连接技术栈各部分客户端、服务端、数据库、部署时所产生的那部分复杂性。它底层基于React负责 Web 组件前端 UINode.js负责服务端查询Queries与操作Actions的实现Prisma负责数据模型定义与数据库访问ORM。这意味着 Wasp 的学习曲线不是从零开始的你已有的 React、Node.js、Prisma 知识可以原样迁移过来Wasp 只是把把它们黏合起来的样板代码glue code替你生成好。从本仓库的真实示例可以印证这一点——examples/kitchen-sink/main.wasp.ts 一个应用就同时聚合了认证、CRUD、Jobs、WebSocket、Streaming、预渲染prerender等多个特性examples/ask-the-documents/main.wasp.ts 则是结合 PG Vector 的 RAG 示例examples/tutorials/TodoApp/main.wasp.ts 是最经典的 Todo 教程应用。它们共用同一套 React Node.js Prisma 技术栈只通过配置差异就产生了完全不同的应用形态。1.2 Wasp 的秘密酱料Wasp 编译器Wasp 的核心是一个编译器Wasp compiler。它接收两份输入Wasp 配置文件0.19 版本文档中使用main.wasp文件你的 JavaScript / TypeScript 业务代码。然后输出三类产物客户端应用代码、服务端应用代码、部署代码。这个编译器在本仓库中是用 Haskell 实现的源码位于 waspc/src/Wasp/Generator.hs其子模块按产物划分清晰可见waspc/src/Wasp/Generator/WebAppGenerator.hs生成前端React Vite应用waspc/src/Wasp/Generator/ServerGenerator.hs生成服务端Node.js Express应用waspc/src/Wasp/Generator/DbGenerator.hs生成数据库相关代码waspc/src/Wasp/Generator/DockerGenerator.hs 与 waspc/src/Wasp/Generator/EmailSenders.hs生成部署与邮件发送相关代码。从 waspc/src/Wasp/Generator.hs 中可以看到生成器工作流程的线索它先对应用规范进行分析校验若无错误则调用各子生成器产出新版本的项目代码。拥有一个理解你代码的编译器带来的直接好处是你只需在 Wasp 配置中声明应用就能免费获得登录/注册及配套的Auth UI 组件全栈类型安全full-stack type safety邮件发送e-mail sending异步处理任务async processing jobs基于React Query的数据获取安全最佳实践security best practices以及更多能力。这些功能你不需要手写任何代码Wasp 会替你生成并持续维护。也就是说当 Wasp 升级时你的应用会同步获得最新的安全实践而不必担心技术债。二、代码长什么样一个完整的 Recipes 应用实战为了让概念落地官方文档用创建并分享菜谱Recipes的应用走了一遍完整流程。我们完整复现这个过程。2.1 第一步在main.wasp中定义应用与认证main.wasp是应用的中枢文件你在其中从高层描述整个应用。首先给应用起个名字并立刻打开基于用户名/密码的全栈认证app RecipeApp { title: My Recipes, wasp: { version: {latestWaspVersion} }, auth: { methods: { usernameAndPassword: {} }, onAuthFailedRedirectTo: /login, userEntity: User } }要点解析app RecipeApp { ... }声明一个名为RecipeApp的应用title用于展示在浏览器标签页等位置wasp: { version: ... }声明 Wasp 编译器版本auth块开启认证。methods: { usernameAndPassword: {} }指定认证方式onAuthFailedRedirectTo: /login指定未认证用户访问受保护页时跳转到/loginuserEntity: User告诉 Wasp 使用User实体作为用户模型。对照本仓库中的 examples/tutorials/TodoApp/main.wasp.ts可以看到同一模式的真实落地在新版 TS 规范中写法略有不同但语义一致auth: { userEntity: User, methods: { usernameAndPassword: {}, }, onAuthFailedRedirectTo: /login, },2.2 第二步用 Prisma Schema 定义数据模型Wasp 直接理解并复用schema.prisma文件中的数据模型。我们希望有User且User拥有多个Recipe... // 数据模型使用 Prisma Schema Language 定义。 model User { id Int id default(autoincrement()) recipes Recipe[] } model Recipe { id Int id default(autoincrement()) title String description String? userId Int user User relation(fields: [userId], references: [id]) }要点解析User通过recipes Recipe[]声明一对多关系Recipe通过userId外键与user User relation(...)建立反向关联description String?表示可选字段这份文件同时服务于数据库迁移migrations与运行时类型Wasp 会基于它生成对应实体类型与查询 API。在 examples/ask-the-documents/schema.prisma 与 examples/kitchen-sink/schema.prisma 中可以看到真实应用是如何扩展这种模式引入enum、向量字段、会话模型等的。2.3 第三步定义 OperationsQuery 与 Action接下来定义如何操作这些数据。Wasp 通过Operations完成这件事Query查询如getRecipes与Action操作/副作用如addRecipe。本质上它们都是运行在服务端的 Node.js 函数但借助 Wasp 可以非常轻松地从客户端调用。先在main.wasp中声明这两个 Operation让 Wasp认识并武装它们// Query 拥有自动缓存失效能力并且是类型安全的。 query getRecipes { fn: import { getRecipes } from src/recipe/operations, entities: [Recipe], } // Action 是类型安全的可用于执行副作用。 action addRecipe { fn: import { addRecipe } from src/recipe/operations, entities: [Recipe], }然后在 JavaScript / TypeScript 中实现它们这里以 TypeScript 展示 Query 的实现// Wasp 会为你生成类型。 import { type GetRecipes } from wasp/server/operations; import { type Recipe } from wasp/entities; export const getRecipes: GetRecipes{}, Recipe[] async (_args, context) { return context.entities.Recipe.findMany( // Prisma 查询 { where: { user: { id: context.user.id } } } ); }; export const addRecipe ...要点解析GetRecipes{}, Recipe[]Wasp 生成的操作类型签名泛型参数分别代表入参类型与返回类型context.entities.Recipe.findMany(...)通过 Prisma Client 查询当前登录用户context.user.id拥有的全部菜谱entities: [Recipe]声明告诉编译器这个 Operation 会访问Recipe实体编译器据此生成类型、处理权限与依赖关系。本仓库的 examples/tutorials/TodoApp/src/queries.js 展示了完全相同的模式export const getTasks async (args, context) { if (!context.user) { throw new HttpError(401); } return context.entities.Task.findMany({ where: { user: { id: context.user.id } }, orderBy: { id: asc }, }); };注意这里还演示了未登录时抛出HttpError(401)的服务端防护——这正是 Wasp 生成的服务端基础层Server SDK所提供的能力。2.4 第四步在 React 组件中使用 Operation定义好 Operation 后就能在 React 组件中非常方便地使用它们。先创建应用的首页还是在main.wasp中声明路由与页面... route HomeRoute { path: /, to: HomePage } page HomePage { component: import { HomePage } from src/pages/HomePage, authRequired: true // 未认证用户将被重定向到 /login。 }要点解析route HomeRoute { path: /, to: HomePage }把根路径/映射到HomePageauthRequired: true声明该页面需要登录未认证访问会被重定向配合前面配置的onAuthFailedRedirectTo。然后用 React 组件实现它调用前面定义好的 Operationimport { useQuery, getRecipes } from wasp/client/operations import { type User } from wasp/entities export function HomePage({ user }: { user: User }) { // 由于全栈类型安全这里的 recipes 类型为 Recipe[]。 const { data: recipes, isLoading } useQuery(getRecipes) // 在这里调用我们的 Query if (isLoading) { return divLoading.../div } return ( div h1Recipes/h1 ul {recipes ? recipes.map((recipe) ( li key{recipe.id} div{recipe.title}/div div{recipe.description}/div /li )) : No recipes defined yet!} /ul /div ) }要点解析useQuery(getRecipes)来自wasp/client/operations是 Wasp 基于 React Query 封装的数据获取 Hook自带缓存、自动失效与加载状态{ user }: { user: User }authRequired页面会自动注入当前登录用户编译器在wasp/server/operations、wasp/client/operations、wasp/entities等虚拟模块中生成类型与运行时代码这就是全栈类型安全的载体——前端拿到的recipes与后端返回的类型严格一致。至此你的应用已经能列出当前用户的所有菜谱了。官方文档特别说明上面的示例省略了/login与/signup页面以保持简洁但在实际项目中使用 Wasp 的Auth UI特性可以非常简单地补齐这两个页面。2.5 小结从配置到运行的全流程环节你在哪里写你写什么应用/认证声明main.waspapp块、auth块数据模型schema.prismaPrismamodel定义业务逻辑src/**/operations.ts返回context.entities查询的 Node 函数页面与路由main.waspsrc/pages/*.tsxroute/page声明 React 组件这样一个配置声明 业务实现的双层结构就是 Wasp 全栈开发的核心心智模型。三、什么时候该用和不该用WaspWasp 解决的是典型 Web 应用框架所解决的同一类核心问题在行为上看起来、游起来、叫起来都像一个 Web 应用框架鸭子测试。3.1 最适合的场景构建全栈 Web 应用例如 Airbnb、Asana 这类以数据交互为主的应用快速启动一个内置行业最佳实践的 Web 应用与现代 Web 技术栈配合使用当前支持 React 与 Node.js。本仓库中的示例应用正好覆盖了这些场景examples/waspello类 Trello 看板、examples/waspleau数据看板 Worker、examples/websockets-realtime-voting实时投票等都是全栈 快速启动的典型代表。3.2 不适合的场景构建静态/展示型网站这类场景用静态站点生成器更合适作为无代码no-code解决方案使用Wasp 仍是面向开发者的代码工具期望它成为单一语言解决一切的万能工具。四、Wasp 是一门 DSL领域特定语言的哲学官方文档用一个独立章节专门讨论 Wasp 的本质它不符合人们对传统 Web 框架的典型期待——Wasp 不是一个库的集合而是一门能够理解你的代码并为你做很多事的简单编程语言。Wasp 是一门特定类型的编程语言它专门服务于单一目的——构建现代 Web 应用。我们把这类语言称为DSLDomain Specific Language领域特定语言。其他常见的 DSL 例子SQL专门用于数据库查询HTML专门用于网页布局。DSL 存在的主要原因和优势在于它只需要做好一件事比如数据库查询因此可以把它做到极致为开发者提供最优体验。同样的思想也支撑着 Wasp——它是一门让开发者用少 10 倍的代码、更少的栈特定知识构建现代 Web 应用的语言。从实现角度看这门语言的解析与类型检查在仓库中由 waspc/src/Wasp/Analyzer含解析器、类型检查器与求值器完成语法/语义校验由 waspc/src/Wasp/AppSpec 与 waspc/src/Wasp/Validator.hs 负责而 waspc/src/Wasp/Generator 则负责把分析后的规范翻译成真实可运行的 React/Node/Prisma 工程。这正好呼应了文档中的表述Wasp 是一种理解你代码的语言——它先理解分析/校验再行动生成。五、从入门到实战推荐的学习路径读完本文后你可以沿着以下路径继续深入安装与快速开始参考 version-0.19 快速开始指南安装 Wasp 后依次运行wasp new、cd my-project-name、wasp start即可在http://localhost:3000得到一个前后端同时在线的全栈应用系统教程跟着 version-0.19 Todo App 教程wasp new TodoApp -t minimal一步步走完 Wasp 的核心特性完整代码见 examples/tutorials/TodoApp读真实示例仓库中的 examples 目录提供了覆盖认证、CRUD、Jobs、WebSocket、邮件、AI 应用等多种场景的可运行项目研究编译器源码从 waspc/src/Wasp/Generator.hs 入手按 WebAppGenerator.hs → ServerGenerator.hs → DbGenerator.hs 的顺序理解配置如何变成代码。结语Wasp 的价值不在于多了一套新的框架 API而在于提供了一种声明式描述 编译器生成的全新开发范式你在main.wasp中描述应用是什么编译器负责生成它怎么运转——认证、类型安全、邮件、后台任务、部署细节都被折叠进编译器的职责范围。这既保留了 React、Node.js、Prisma 生态的成熟能力又让全栈应用 10 倍减码从口号变成了可落地的开发体验。【免费下载链接】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),仅供参考
返回列表