Wasp Monorepo 架构与编译管线深度解析:从 main.wasp.ts 到 React + Node.js 的声明式全栈框架
【免费下载链接】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
本篇技术指南以仓库根目录的 AGENTS.md 为骨架,系统拆解 Wasp 单仓库(monorepo)的整体布局、Haskell 编译器的内部结构、两阶段构建流程,以及"TypeScript 配置 → AppSpec → 代码生成"的声明式编译管线。读完本文,你将掌握 Wasp 仓库的目录职责划分、./run开发脚本的完整用法、代码规范与快照测试约束,并能对照源码快速定位各功能模块的实现位置。
Wasp 是什么:一个会"编译"的全栈框架
Wasp 是一个全栈 Web 框架,其核心思想是声明式开发:开发者用 TypeScript 编写配置文件main.wasp.ts,描述页面、实体、查询、操作、认证等高层抽象,Wasp 的编译器负责把这些声明"编译"成完整的 React + Node.js 应用。
与常规框架最大的不同在于:Wasp 的编译器本身是用Haskell编写的,位于waspc/目录。它承担了配置解析、类型检查、代码生成的全过程,最终产出可直接运行和部署的前后端代码。这种"语言驱动框架"的设计,让 Wasp 可以自动生成认证、后台任务(Job)、RPC、邮件发送、端到端类型安全等复杂全栈能力,而开发者只需在配置文件中做高层声明。
仓库全景:一个 monorepo,五个核心板块
AGENTS.md 将仓库划分为五大板块,各自职责明确:
| 目录 | 职责 | 关键内容 |
|---|---|---|
| waspc/ | Haskell 编译器、CLI 与 LSP 服务,Wasp 的核心 | 编译器库、CLI 命令、生成器模板、快照测试 |
| wasp-app-runner/ | Node.js CLI,用于在 e2e 测试中运行 Wasp 应用 | run-wasp-app dev/build两种模式,自动完成数据库初始化与迁移 |
| web/ | 文档网站(Docusaurus),部署至 wasp.sh | docs/、blog/、markdown-snapshots/ |
| examples/ | 教程与示例应用 | kitchen-sink、waspello、waspleau、ask-the-documents 等 |
| scripts/ | monorepo 级构建与打包脚本 | npm 包生成、部署密钥准备、缓存清理等 |
其中 wasp-app-runner/README.md 说明它提供两种运行模式:dev模式通过wasp start以开发方式运行,build模式先wasp build再以生产方式运行;全局安装后可直接使用run-wasp-app dev命令。examples 目录则承载了从入门(TodoApp、TodoAppTs)到综合演示(kitchen-sink 覆盖全部特性)的完整示例矩阵。
waspc:深入编译器内部
作为仓库的核心,waspc/的每个子目录都对应编译链路中的一个环节:
waspc/src/—— 主编译器库,包含四大模块:Analyzer:分析 TypeScript 配置文件并推导语义AppSpec:应用规范(IR,中间表示),定义了 Action、Query、Crud、Entity、Job、Page、Api、Route 等声明的 Haskell 数据类型,见 waspc/src/Wasp/AppSpec/Generator:根据 AppSpec 生成 React/Node.js 代码Psl:Prisma Schema Language 的解析与处理
waspc/cli/src/—— CLI 命令实现,见 waspc/cli/src/Wasp/Cli/Command/,包含start、build、new、deploy、db、compile、clean、doctor、deps、dockerfile、studio、watch等命令waspc/data/packages/—— CLI 在编译项目时以 FFI 方式调用的 TypeScript 包,目前包含deploy(部署逻辑)、prisma、spec(配置规范)、studio四个子包waspc/data/Generator/libs/—— 内嵌到生成项目代码中的 TypeScript 库,目前包含auth(认证库)与vite-ssr两类waspc/data/Generator/templates/—— 代码生成模板,包含server/、sdk/、db/、types/、Dockerfile等模板目录waspc/e2e-tests/—— 黄金文件(Golden File)快照测试,测试产物位于 waspc/e2e-tests/test-outputs/snapshots/,包含kitchen-sink-golden/、wasp-compile-golden/等waspc/run——主开发脚本,不带参数运行./run会打印全部可用命令
构建与开发:一切从 ./run 开始
AGENTS.md 明确指出:所有 waspc 开发命令都通过 waspc/run 脚本执行,且必须从waspc/目录运行。该脚本本身是一个精心设计的 Bash 封装,把cabal、npm、node等底层命令统一暴露成语义化子命令。
两阶段构建
Wasp 的构建是两阶段的,这一点决定了整个开发流程的形态:
- 先编译 TypeScript 部分:
data/packages/下的 TS 包与data/Generator/libs/下的库先被编译; - 再编译 Haskell 部分:Haskell 编译器会嵌入这些 TS 产物(作为>WASP_PACKAGES_COMPILE="node ${SCRIPT_DIR}/tools/packages/build.ts" WASP_LIBS_COMPILE="node ${SCRIPT_DIR}/tools/libs/build.ts" WASP_ALL_DEPS_COMPILE="$WASP_PACKAGES_COMPILE && $WASP_LIBS_COMPILE" BUILD_HS_CMD="cabal build all ${BUILD_STATIC:+--enable-executable-static}" BUILD_ALL_CMD="$WASP_ALL_DEPS_COMPILE && $BUILD_HS_CMD"
因此完整构建使用
./run build(等价于依次执行build:packages、build:libs、build:hs);如需静态链接构建,可以设置环境变量BUILD_STATIC=1,cabal会追加--enable-executable-static。常用开发命令
命令 作用 ./run wasp-cli <args>运行本地开发的 wasp 可执行文件并透传参数;无需进入 waspc 目录。实现上通过 waspc/tools/wasp-cli-dev 单可执行文件包装 cabal run,可无缝替代wasp命令,避免 shell 引号问题./run build完整构建(TS 包 + libs + Haskell) ./run build:packages仅构建 data/packages/下的 TS 包./run build:libs仅构建 data/Generator/libs/下的 Wasp 库./run install将 wasp 可执行文件全局安装为 wasp-cli./run test执行全部测试(waspc 单元 + e2e + CLI + 示例 + starter 模板) ./run test:waspc:e2e:accept-all接受快照测试中的差异(先删除 golden 再重跑生成新 golden) ./run code-check依次执行 prettier、ormolu、cabal-gild 检查 + hlint + stan 静态分析并汇总结果 ./run ghcid启动 ghcid 监视源码变更并报告错误 ./run wasp-cli还支持install、compile等子命令透传,例如bust-libs-cache命令会清理.wasp/out与@wasp.sh/lib-*缓存、修正package-lock.json中的过期条目,再重新wasp install与wasp compile——这是 Wasp 版本升级后刷新依赖的实用工具。工具链版本锁定
所有工具链版本在 mise.toml 中集中声明,包括:GHC 9.6.7(刻意停留在 9.6 是因为 HLint 尚不兼容 GHC 9.10)、cabal 3.16.1.0、Node 24.14.1(与 Wasp 最低支持 Node 版本保持一致)、HLS 2.14.0.0、HLint 3.8、Ormolu 0.8.1.1,以及 ghcup 0.2.6.2。文件同时声明了 Ubuntu/Debian 与 Alpine 的 apt/apk 系统依赖(如
libgmp-dev、zlib1g-dev、openssl等),并注明这些配置需与 CI 中的.github/actions/setup-tools/action.yaml保持同步。Node 后端被显式设置为compile = false,避免在 Alpine 上从源码编译。架构管线:声明式配置如何变成全栈应用
AGENTS.md 用一条清晰的链路描述了编译核心流程:
TypeScript 配置(
main.wasp.ts)由Wasp.Project.WaspFile.TypeScript读取 →AppSpec(IR)→Generator生成 React/Node.js 代码。Analyzer从 Prisma schema 推导实体(Entity)声明。Wasp 编译器实现架构图
从上图可以直观看到这条管线的全貌:输入经过Analyzer(Parser 解析 → TypeChecker 类型检查 → Evaluator 求值)产出AppSpec中间表示,再交给Generator(分为 Client、Server、DB 三个生成器)基于模板生成代码,最终通过文件草稿(File Draft)系统写入磁盘。
配置解析:TypeScript 文件的读取
管线的入口在 waspc/src/Wasp/Project/WaspFile/TypeScript.hs,其导出函数
analyzeWaspTsFile负责分析main.wasp.ts。从源码结构看,它会以 Node 子进程(Wasp.Job.Process.runNodeCommandAsJobWithExtraEnv)的方式运行@wasp.sh/spec包(Wasp.NodePackageFFI中的WaspSpecPackage)来完成配置的读取与校验,并将结果解析为 AppSpec 声明。中间表示:AppSpec
Wasp.AppSpec是编译链路中的唯一真相来源(single source of truth)。waspc/src/Wasp/AppSpec/ 下每个文件对应一类高层抽象:App.hs:应用级配置(认证、邮件、部署等)Entity.hs:数据实体Page.hs、Route.hs:页面与路由Query.hs、Action.hs、Operation.hs:前后端 RPC 操作Crud.hs:CRUD 声明Job.hs:后台任务Api.hs:自定义 APIValid.hs:声明校验逻辑
代码生成:Generator 与 File Draft
Generator接收 AppSpec 产出各端代码。waspc/src/Wasp/Generator.hs 聚合了完整生成流程:import Wasp.Generator.DbGenerator (genDb) import Wasp.Generator.DockerGenerator (genDockerFiles) import Wasp.Generator.SdkGenerator (genSdk) import Wasp.Generator.ServerGenerator (genServer) import Wasp.Generator.TypeAugmentationGenerator (genTypeAugmentation) import Wasp.Generator.WaspLibs (genWaspLibs) import Wasp.Generator.WriteFileDrafts (synchronizeFileDraftsWithDisk)其中
genServer、genDb、genSdk分别负责服务端、数据库与 SDK 代码,而synchronizeFileDraftsWithDisk体现的正是 AGENTS.md 提到的File Draft(文件草稿)系统:所有要生成的文件先以草稿形式在内存中构建,再统一与磁盘同步,从而保证生成过程的可控性与幂等性。生成器模板则来自 waspc/data/Generator/templates/。实体推导:Analyzer 与 Prisma
Analyzer负责从schema.prisma推导 Entity 声明,相关逻辑位于 waspc/src/Wasp/Project/Analyze.hs 与Psl模块。也就是说,数据模型以 Prisma Schema 语言定义,而 Wasp 层面的实体抽象由 Analyzer 自动推导而来,二者保持一致性。代码规范:两个语言世界的工程约束
AGENTS.md 对 Haskell 与 TypeScript/JavaScript 分别规定了编码规范,这些规范在 CI 中由
./run check系列命令强制执行。Haskell 规范
- 保持简单、可读,不引入复杂语言特性(详见 CONTRIBUTING.md)
- 默认扩展统一在 waspc/waspc.cabal 中声明
- 命名:类型/模块用 CamelCase,函数/值用 camelCase;优先使用限定导入(qualified imports)
- 格式化:Ormolu,检查/格式化命令为
./run check:ormolu/./run format:ormolu - Lint:HLint,命令为
./run hlint,配置位于waspc/.hlint.yaml - 测试:使用
tasty+hspec+QuickCheck,测试模块镜像源码模块路径并加Test后缀(例如Wasp/Util.hs对应tests/Util/UtilTest.hs)
TypeScript/JavaScript 规范
- 格式化:Prettier,配置在根目录 prettier.config.mjs,插件包含
organize-imports、pkg、sh、tailwindcss,并启用semi、singleQuote: false、trailingComma: "all";检查/修复命令为./run check:prettier/./run format:prettier - 命名:文件/函数用 camelCase,组件/类型用 PascalCase
三条铁律:快照、文档与 PR
AGENTS.md 最后列出了仓库协作的强制性规则,违反任何一条都可能导致 CI 失败或历史版本被污染。
1. E2E 快照严禁手动编辑
waspc/e2e-tests/test-outputs/snapshots/下的黄金文件永远不能手动修改。当编译器行为发生变化时,正确的更新方式是:cd waspc && ./run build && ./run test:waspc:e2e:accept-all该命令先删除当前 golden 输出,再重跑快照测试生成新的 golden 输出(脚本实现见
waspc/run中的WASPC_E2E_TESTS_ACCEPT_CURRENT_CMD)。这一机制确保了生成代码的任何变更都经过显式审查,而非静默覆盖。2. 文档只改最新版
只能编辑 web/docs/(最新版本文档);web/versioned_docs/ 下的旧版本文档是自动生成的快照,禁止修改。这也解释了仓库中从
version-0.11.8到version-0.25的版本化文档为何保持只读。3. Markdown 快照的再生成流程
web/markdown-snapshots/(如
llms.txt、llms-full.txt、llms-current.txt)同样严禁手动编辑。修改 docs、blog 或 LLM 文件插件之后,必须执行:cd web && npm run build-dev && npm run markdown-snapshots:update提交前应 review 生成的 diff,CI 通过
npm run markdown-snapshots:check校验一致性。4. PR 模板
提交 Pull Request 时始终使用仓库的
PULL_REQUEST_TEMPLATE.md,且永远不要删除模板中的任何复选框——无关项保持不勾选即可。总结:从 AGENTS.md 读懂整个 Wasp 工程
AGENTS.md 虽然是一份面向 Agent 的协作说明,但它精确勾勒了 Wasp 工程的全貌:一个以 Haskell 编译器
waspc为核心的 monorepo,通过"TS 配置解析 → AppSpec 中间表示 → 生成器产出 React/Node.js 代码"的管线实现声明式全栈开发。理解这份文档,等于拿到了探索 waspc/src/Wasp/ 编译源码、waspc/cli/src/Wasp/Cli/Command/ 命令实现、examples/ 示例应用与 web/docs/ 官方文档的完整地图。对于希望贡献代码、调试编译问题或深入理解 Wasp 原理的开发者而言,从./run命令体系与快照测试约束入手,是最快进入状态的路径。【免费下载链接】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),仅供参考