拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Wasp 全栈框架入门:用声明式 DSL 与编译器构建 React + Node.js + Prisma 应用

Wasp 全栈框架入门用声明式 DSL 与编译器构建 React Node.js Prisma 应用【免费下载链接】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 应用框架其核心理念是用一份声明式的配置文件描述应用的高层结构再由内置编译器自动生成前端、后端与部署代码从而让开发者专注业务逻辑。本文以本仓库 0.11.8 版本文档为主线完整讲解 Wasp 的定位、编译器工作原理、main.wasp配置语法与基于 React/Node.js/Prisma 的实战写法并对照当前仓库源码与示例应用给出可验证的实现依据。Wasp 是什么一个构建现代 Web 应用的工具Wasp 是一种有主见opinionated的全栈 Web 应用构建方式它一次性接管 Web 应用的三大组成部分客户端client / 前端、服务器server / 后端和数据库database。开发者不需要分别搭建、连接和部署这三层而是在一处声明它们剩下的胶水代码由框架补齐。它的定位不是什么都要自己做而是聚焦于把整条技术栈客户端、服务器、数据库、部署连接起来时产生的复杂性——这正是全栈开发中最容易出错、最耗时的部分。换句话说Wasp 不发明新的组件体系而是把已有组件高效地粘合在一起。与现有技术栈良好协作Wasp 底层直接使用React、Node.js和Prisma并依赖它们来定义 Web 组件与服务器端的查询Query和操作ActionReact负责前端 UI 组件Node.js负责服务器端逻辑查询与操作的实现函数Prisma负责数据模型定义与数据库访问。这意味着开发者已有的 React、Node.js、Prisma 知识可以原样迁移到 Wasp 项目中。仓库中的示例应用正是这一技术栈的直接体现例如 examples/tutorials/TodoApp/schema.prisma 使用 Prisma Schema Language 定义User与Task模型而 examples/kitchen-sink/main.wasp.ts 中则通过wasp.sh/spec导入并编排client、server、db、emailSender等全栈配置。Wasp 的秘密武器理解代码的编译器Wasp 的核心是一个编译器compiler它接收 Wasp 配置文件0.11 时代的main.wasp以及当前版本的main.wasp.ts和你编写的 JavaScript/TypeScript 代码输出三样东西——客户端应用、服务器应用和部署代码。如上图所示对应仓库文件 web/static/img/lp/wasp-compilation-diagram.png左侧是开发者编写的.wasp配置、.jsx/.tsx组件与.js/.ts逻辑代码中间是 Wasp 编译器右侧是生成出的完整 Web 应用——前端使用 React、ES6 与 CSS后端使用 Node.js 与 Prisma部署部分则生成 Docker 与 Fly.io 相关配置。整个流程印证了文档中的核心论断编译器的价值在于理解你的代码从而替你做大量机械性工作。这份编译器的实现本身也完整存在于本仓库中waspc/目录是用 Haskell 实现的 Wasp 编译器源码包含 waspc/src/Wasp/Analyzer分析、waspc/src/Wasp/Generator代码生成、waspc/src/Wasp/AppSpec应用规格描述等模块并在 waspc/e2e-tests 下有完整的端到端测试如WaspCompileTest.hs、WaspBuildTest.hs验证编译产物。定义一次获得一整组内置能力编译器理解你的代码带来的直接收益是只要在 Wasp 配置中声明应用即可免费获得以下能力无需手写一行实现代码登录与注册以及配套的Auth UI 组件全栈类型安全full-stack type safety邮件发送e-mail sending异步处理任务async processing jobs基于React Query的数据获取安全最佳实践security best practices以及更多。更关键的是Wasp 不仅替你生成这些代码还持续替你维护它们随着 Wasp 版本更新应用内的安全最佳实践也随之更新开发者无需自己追踪业界最新安全要求。代码长什么样一个食谱分享应用的完整示例下面跟随原文档的经典例子一步步构建一个允许用户创建并分享自己最爱食谱的 Web 应用。整个例子只需要三种文件main.wasp高层声明、服务端 TypeScript 逻辑、客户端 React 组件。第一步在 main.wasp 中声明应用与认证main.wasp是应用的中心文件从高层描述整个应用。先给应用起个标题并立即开启基于用户名 密码的全栈认证app RecipeApp { title: My Recipes, wasp: { version: ^0.11.0 }, auth: { methods: { usernameAndPassword: {} }, onAuthFailedRedirectTo: /login, userEntity: User } }这段配置的语义均可在当前仓库示例中得到印证如 examples/tutorials/TodoApp/main.wasp.ts 与 examples/waspello/main.wasp.ts 中完全相同的usernameAndPassword、onAuthFailedRedirectTo、userEntity配置项title应用标题用于浏览器标签等场景wasp.version声明所需的 Wasp 版本范围这里为^0.11.0用于校验编译兼容性auth.methods.usernameAndPassword启用用户名密码登录方式Wasp 会自动生成对应的认证逻辑与数据库字段auth.onAuthFailedRedirectTo未认证用户访问受保护页面时重定向到的路径auth.userEntity指定承载用户数据的数据模型即下面定义的User。第二步用 Prisma Schema 定义数据模型接下来添加食谱的数据模型应用需要User且User拥有多条Recipe。数据模型使用Prisma Schema Language定义直接写在main.wasp的{psl ... psl}代码块中... entity User {psl // Data models are defined using Prisma Schema Language. id Int id default(autoincrement()) username String unique password String recipes Recipe[] psl} entity Recipe {psl id Int id default(autoincrement()) title String description String? userId Int user User relation(fields: [userId], references: [id]) psl}要点说明id default(autoincrement())自增主键unique用户名唯一约束String?可选字段描述可以为空Recipe[]与relation(fields: [userId], references: [id])建立User与Recipe之间的一对多关系。在 0.11 版本中Prisma 模型直接内嵌于main.wasp而在当前版本的仓库中数据模型被独立放入schema.prisma文件例如 examples/tutorials/TodoApp/schema.prisma 定义了User含tasks Task[]与Task含user User? relation(...)模型关系建模方式与本例完全一致。第三步定义操作——Query 与 Action有了数据模型接下来定义如何对这些数据做事。在 Wasp 中这通过Operations完成Query查询与Action操作。它们在本质上就是运行在服务器上的 Node.js 函数但借助 Wasp可以非常轻松地从客户端调用。先在main.wasp中声明这两个 Operation让 Wasp认识它们并为它们注入能力// Queries have automatic cache invalidation and are type-safe. query getRecipes { fn: import { getRecipes } from server/recipe.js, entities: [Recipe], } // Actions are type-safe and can be used to perform side-effects. action addRecipe { fn: import { addRecipe } from server/recipe.js, entities: [Recipe], }然后在一段 TypeScript 代码中实现它们这里只展示查询部分// Wasp generates types for you. import type { GetRecipes } from wasp/queries/types; import type { Recipe } from wasp/entities; export const getRecipes: GetRecipes{}, Recipe[] async (_args, context) { return context.entities.Recipe.findMany( // Prisma query { where: { user: { id: context.user.id } } } ); }; export const addRecipe ...这里有几个 Wasp 生成的运行时与类型值得注意wasp/queries/types与wasp/entities是Wasp 自动生成的模块类型标注GetRecipes{}, Recipe[]表明该查询无入参、返回Recipe[]数组context.entities.Recipe是 Wasp 注入的Prisma Client可直接调用findMany等 Prisma 查询 APIcontext.user由认证系统注入表示当前登录用户因此查询天然做到了只能看到自己的食谱这一权限语义entities: [Recipe]声明该操作访问的数据模型Wasp 会据此做缓存失效跟踪与权限约束。操作中声明的entities与自动生成的类型系统正是全栈类型安全与React Query 驱动数据获取两大特性的落地点。第四步定义路由与页面最后创建应用首页。先在main.wasp中定义路由与页面... route HomeRoute { path: /, to: HomePage } page HomePage { component: import { HomePage } from client/pages/HomePage, authRequired: true // Will send user to /login if not authenticated. }route把 URL 路径/映射到某个页面page声明页面组件来源与访问控制authRequired: true未登录用户访问时自动重定向到/login——这正是前面onAuthFailedRedirectTo配置发挥作用的地方。然后把它实现为一个 React 组件调用前面定义好的 Operationsimport getRecipes from wasp/queries/getRecipes; import { useQuery } from wasp/queries; import type { User } from wasp/entities; export function HomePage({ user }: { user: User }) { // Due to full-stack type safety, recipes will be of type Recipe[] here. const { data: recipes, isLoading } useQuery(getRecipes); // Calling our query here! 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 封装的React Query数据获取层调用后自动处理加载态、错误态与缓存由于全栈类型安全recipes的返回类型自动推导为Recipe[]客户端无需手写接口类型user作为 props 由 Wasp 的认证系统注入页面可直接读取当前登录用户。至此一个带认证、数据模型、服务端查询、客户端展示的完整全栈应用就串起来了。原文档还指出示例中为了精简省略了/login与/signup页面而这两者使用 Wasp 的Auth UI特性即可轻松补齐。什么时候该用 WaspWasp 解决的是典型 Web 应用框架解决的同一批核心问题从行为上看看起来像、游起来像、叫起来像它就是一个 Web 应用框架。最适合的场景构建全栈 Web 应用例如 Airbnb、Asana 这类产品形态希望以行业最佳实践快速起步一个新 Web 应用希望与现代化 Web 技术栈配合使用当前支持 React 与 Node.js。应避免使用 Wasp 的场景构建静态/展示型网站Wasp 的编译与全栈管线对这种场景属于过度设计当作无代码no-code解决方案使用Wasp 仍需编写 JS/TS 与 Prisma 代码期望它是单一语言解决所有问题的万能工具。Wasp 是一种 DSL领域特定语言Wasp 不符合人们对 Web 应用框架的常规期待它不是一组库而是一门能理解你的代码、并替你做大量工作的编程语言。Wasp 是编程语言但属于特殊的一类它专门服务于单一目的——构建现代 Web 应用。这类语言被称为DSLDomain Specific Language领域特定语言。其他常见的 DSL 例子包括用于数据库查询的SQL、用于网页布局的HTML。DSL 存在的核心优势在于它们只需做好一件事例如数据库查询因此能把它做到极致为开发者提供最佳体验。Wasp 背后的理念与之完全相同一门让开发者用 10 倍更少的代码、更少的栈特定知识来构建现代 Web 应用的语言。原文档也贴心提示不了解 DSL 概念并不影响使用 Wasp这一小节仅供有好奇心的读者深入理解。从 0.11 到当前版本的演进DSL 的 TypeScript 化值得说明的是本仓库中web/versioned_docs/version-0.11.8/目录记录的是 Wasp 0.11 时代的文档彼时 Wasp 配置使用独立的main.wasp文件Wasp 自有的 DSL 语法如上文所示。而查看当前仓库的示例应用如 examples/tutorials/TodoApp/main.wasp.ts、examples/waspello/main.wasp.ts、examples/kitchen-sink/main.wasp.ts可以看到该 DSL 已演进为TypeScript 规格文件main.wasp.tsimport { app, page, query, route, action } from wasp.sh/spec; // ... 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] }), // ... ], });可以清楚看到演进脉络auth配置methods、onAuthFailedRedirectTo、userEntity、route/page、query/action等核心概念与 0.11 文档一脉相承只是换成了 TypeScript 函数式写法Prisma 数据模型则从内嵌于main.wasp迁至独立的schema.prisma文件。编译器驱动、声明式声明应用结构的思想则始终未变。延伸阅读与仓库佐证分步教程Todo 应用教程0.11 版可带你走一遍 Wasp 的核心功能安装说明见 Quick Start0.11 版安装指引Linux/macOS/WSL 下通过安装脚本安装需 Node.js 环境可运行的完整示例仓库 examples/ 目录下提供了 TodoApp、kitchen-sink、waspello、waspleau、ask-the-documents、websockets-realtime-voting 等多个真实项目直接展示了main.wasp.tsschema.prisma React/Node 组件的组织方式编译器实现感兴趣的读者可深入 waspc/src/Wasp 下的 Analyzer、Generator、AppSpec 等模块并参考 waspc/e2e-tests 中的WaspCompileTest.hs、WaspBuildTest.hs等测试了解编译链路的验证方式。【免费下载链接】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),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门