Wasp 编译器(waspc)源码解析与贡献指南:从 Haskell 架构到全栈应用生成
【免费下载链接】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
waspc是 Wasp 全栈框架的核心编译器与 CLI,它以 Haskell 实现编译管线,将声明式 Wasp 配置与src/目录中的 JS/TS 代码转换成一整套由 React 客户端、Node.js/Express 服务端与 Prisma 数据库组成的可运行 Web 应用。本文基于 waspc/README.md 的完整贡献者指南,结合仓库内run脚本、waspc.cabal与核心 Haskell 源码,系统讲解 waspc 的架构、开发环境搭建、构建测试流程、分支与发布策略,以及代码规范,帮助你快速上手这一编译器的源码开发。
waspc 是什么:编译器、CLI 与项目运行器的三位一体
在 Wasp 项目中,waspc指的是waspCLI/编译器的 Haskell 源码目录,但构建产物的可执行文件名并不是waspc。这一点很容易混淆,README 特别做了说明:
- 正式发布时,可执行文件名为
wasp; - 开发阶段的可执行文件名为
wasp-cli,用于与已安装的发布版区分。
从 waspc.cabal 可以看到,可执行文件定义为executable wasp-cli,入口为cli/exe/Main.hs,它依赖cli-lib与waspc两个 Haskell 库。因此从产物角度看,wasp二进制同时承担了三重角色:编译器(把 Wasp 声明编译成 Web 应用)、CLI(new、start、db、build、deploy等命令入口,见 cli/exe/Main.hs 中的命令分发逻辑)、以及Wasp 项目运行器(wasp start时编译并启动开发环境)。
# 查看当前 waspc 版本号 ./run get-waspc-version仓库当前waspc.cabal中的版本为0.26.0(waspc.cabal),版本号管理遵循 SemVer 语义,详见后文"发布策略"一节。
第一份贡献清单:快速上手指南
README 为第一次向 waspc 提交代码的贡献者提供了一份四步清单:
- 阅读本文的 Codebase overview 快速了解编译器的整体结构;
- 成功编译项目,并跑通
kitchen-sink示例应用(见下文 Basics); - 加入社区 Discord,打个招呼;
- 挑选标有
good first issue的 issue,主动提出工作计划并提问;随后创建面向main分支的 PR,参考 Typical workflow 与 Branching and merging strategy。
第 4 步是整个贡献闭环的关键:PR 的质量门禁是 CI 全部通过,因此建议在提交前完整执行一遍 Code analysis 中介绍的各项检查。
waspc 架构总览:Analyzer 与 Generator 两层管线
Wasp 编译器用 Haskell 实现,代码库分为**库(src/)**与CLI(cli/src/为库、cli/exe/为薄可执行包装)两部分。CLI 是实际的wasp可执行文件,绝大部分逻辑在库中。
从 src/Wasp/Analyzer.hs 的模块说明可以看到,编译管线分为两层:
- Analyzer(前端):解析 Wasp 声明并做类型检查与求值。历史上它解析
.waspDSL 文件,但该解析器已被移除,改为分析 TypeScript 配置文件(Wasp.Project.WaspFile.TypeScript);如今 Analyzer 保留的"解析 → 类型检查 → 求值"机制被复用于从 Prisma schema 推导实体声明:Analyzer.Prisma将 schema 转为 AST 实体语句,Analyzer.TypeChecker为 AST 补充类型信息,Analyzer.Evaluator把类型检查后的 AST 转换为 Wasp AST。 - Generator(后端):接收 Analyzer 产出的中间表示
AppSpec(定义于 src/Wasp/AppSpec.hs),基于它决定如何生成 Web 应用。
AppSpec是贯穿前后两层的中央 IR。从 src/Wasp/Generator.hs 可以观察到 Generator 的组装方式——genApp依次拼接多个子生成器:
genApp :: AppSpec -> Generator [FileDraft] genApp spec = do warnOverriddenDeps spec genServer spec <++> genSdk spec <++> genDb spec <++> genDockerFiles spec <++> genTypeAugmentation spec <++> genWaspLibsREADME 中描述的 WebAppGenerator / ServerGenerator / DbGenerator 三个主生成器,在实现中体现为Wasp.Generator.WebAppGenerator、Wasp.Generator.ServerGenerator与Wasp.Generator.DbGenerator三个模块(见 waspc.cabal 的 exposed-modules 列表)。
一个关键设计理念是:Generator 本身不写文件。它的输出是FileDraft列表,每个 FileDraft 描述"如何在磁盘上创建某个文件"(如CopyFileDraft、CopyLibDraft、TemplateFileDraft、TextFileDraft等类型,见 src/Wasp/Generator/FileDraft 目录)。最终由synchronizeFileDraftsWithDisk(在 src/Wasp/Generator.hs 的writeWebAppCode中调用)将草稿写入磁盘,完成应用生成。
FileDrafts 大量使用 Mustache 模板(存放于data/Generator/templates/),而生成的应用还依赖 Wasp 自带的内部 npm 包(WaspLibs),这些包随 Wasp 一起打包并安装进生成的应用中。
上图展示了完整的编译数据流:输入(Wasp 配置与src/资源)→ Analyzer(Parser → TypeChecker → Evaluator)产出AppSpec→ Generator 结合 Templates 驱动 Client/Server/DB 三个子生成器产出 FileDraft(FD)→ 写入磁盘生成 Web 应用。
生成出的 Web 应用技术栈为:客户端使用 React + TanStack Query(@tanstack/react-query),服务端使用 Node.js + Express,数据库层通过 Prisma 抽象。wasp start会先编译应用、在.wasp/out/目录生成 JS 代码,然后分别对 client 与 server 执行npm start并启动数据库;此后任何对 Wasp 源码的修改都会触发重新编译,client/server 的npm start会自动拾取变化。
从零搭建 waspc 开发环境
仓库准备与run脚本
克隆仓库后进入waspc/目录并确保处于main分支。README 特别强调:./run脚本(waspc/run)封装了 waspc 开发中最常用的命令,地位等同于 npm 项目中package.json的scripts,既是快捷入口也是开发方式的文档。不带参数运行./run会打印全部可用命令的帮助信息。
可以为其创建 bash 别名方便调用:
alias wrun="/path/to/your/wasp-lang/wasp/waspc/run"[!IMPORTANT]
./run脚本及配套开发工具是 Bash 脚本,在 Windows 的 PowerShell 或 Command Prompt 中无法直接使用。
从 waspc/run 源码可以看到脚本的结构:COMMAND=${1:-watch}默认执行watch类命令,每个子命令(build、test、wasp-cli、stan、hlint等)通过case分支映射到对应的底层命令。例如build实际执行:
# waspc/run 中的 BUILD_ALL_CMD node tools/packages/build.ts && node tools/libs/build.ts && cabal build all而wasp-cli命令则通过tools/wasp-cli-dev脚本(waspc/tools/wasp-cli-dev)以cabal -v0 --project-dir=... run wasp-cli -- "$@"的方式运行本地构建的 CLI,这样测试与开发调用总能反映waspc源码的最新状态,无需事先cabal install。
构建、测试与运行 CLI
按顺序执行以下三条命令,即可完成第一轮"构建 → 验证 → 运行":
# 1. 构建整个 waspc 项目(Haskell + TS 包 + WaspLibs) ./run build # 2. 确保所有测试通过 ./run test # 3. 运行本地构建的 wasp-cli(无参数会打印帮助/用法) ./run wasp-cli首次执行./run build可能需要约 10 分钟,因为要下载全部依赖(之后会被缓存)。开发期可执行文件名为wasp-cli,与正式安装后的wasp相区分——这正是方便开发者区分"开发版 CLI"与"发布版 CLI"的设计。
跑通 kitchen-sink 示例应用
examples/kitchen-sink/(examples/kitchen-sink)是 Wasp 团队始终维护的示例应用,用于手工验证对编译器的改动,也是新增功能的首选验证场。跑通它的步骤:
# 1. 进入示例目录 cd examples/kitchen-sink # 2. 启动开发数据库(保持运行,不要关闭该终端) ./run wasp-cli db start # 3. 新开一个终端,更新数据库 schema ./run wasp-cli db migrate-dev # 4. 准备服务端 mock 环境变量 cp .env.server.example .env.server # 5. 以开发模式启动示例应用 ./run wasp-cli start首次执行第 5 步可能需要一分钟左右下载并安装 npm 依赖;完成后浏览器会自动打开新标签页并展示 Kitchen Sink 应用。
[!NOTE]
kitchen-sink中的部分功能不会工作,因为.env.server里只是 mock 值。关于如何配置开发环境变量,请查看kitchen-sink自己的 README(examples/kitchen-sink/README.md)。
典型开发工作流:从分支到合入
README 给出了一套完整的迭代流程,结合 waspc/run 可以还原每一步的实际命令:
- 从
main创建功能分支。 - 若 IDE 没有可靠的 HLS(Haskell Language Server,强烈建议配置),在
waspc根目录运行./run ghcid:它会监视 Haskell 项目并持续报告编译错误,保持运行即可。ghcid需先全局安装:cabal install ghcid。 - 修改代码(最常见于
src/、cli/src/或data/目录),并视情况更新测试。对照 HLS/ghcid修复错误,循环迭代。 - 用
./run build:hs单独构建 Haskell/cabal 项目;./run wasp-cli则会构建并运行。若改动涉及data/packages/,还需执行./run build:packages(详见下文 TypeScript 包章节);嫌慢的话可以一步到位执行./run build同时构建 Haskell、TS 包等所有部件。 - 手工验证改动时使用
kitchen-sink(保持更新);新增功能应同时加入该应用及其测试。 - 执行
./run test确认全部测试通过。若 waspc e2e 快照测试出现预期变更,用./run test:waspc:e2e:accept-all接受新基线。 - 若做了 bug 修复、新功能或破坏性变更,在
Changelog.md(waspc/ChangeLog.md)中补充简要说明;必要时同步提升waspc.cabal与ChangeLog.md中的版本号(版本确定方法见 Determining next version)。 - 创建 PR,紧盯 CI——一切必须通过。
- 若 PR 改变了用户使用 Wasp 的方式,同步更新同仓库
web/docs下的文档。 - 与 reviewer 协作迭代直至 PR 获批。
- Reviewer 将分支合入
main。
团队内部成员的注意事项
不要在你的 PR 获批前更新 waspc e2e 测试。过早接受 e2e 测试会拖慢 UI、给 reviewer 制造噪音,并降低你在所有评审迭代后仔细核对最终 diff 的可能性。接受 waspc e2e 测试 diff 前务必仔细审查。
深入 waspc 的关键目录
README 列出waspc/内的核心目录,结合 waspc.cabal 可以对应到实际的 Haskell 模块:
src/→ 主源码(库),对应 cabal 的library段;cli/src/→ CLI 库代码,对应library cli-lib段,实现Wasp.Cli.Command.*系列命令模块(如Wasp.Cli.Command.Db.Migrate、Wasp.Cli.Command.Deploy、Wasp.Cli.Command.News等,见 waspc.cabal);cli/exe/→ 可执行文件薄包装(Main.hs),对应executable wasp-cli段;tests/、e2e-tests/、cli/tests/、starters-e2e-tests→ 各类测试;data/Generator/templates/→ 生成 client/server 的 Mustache 模板;data/Generator/libs/→ 随 Wasp 打包并复制进生成应用的内部 npm 包(WaspLibs);data/packages/→ Wasp 编译器自身使用的 TypeScript 包;data/Cli/starters/→ 新项目的 starter 模板。
TypeScript 包:Haskell 与 TS 的协作
waspc虽以 Haskell 实现,但部分功能(如解析 TS 代码、部署脚本)依赖 TypeScript。Haskell 代码将这些 TS 包作为独立进程运行,通过输入/输出流通信。这些包位于 waspc/data/packages/README.md 所述的data/packages/中,是标准 npm 项目;deploy、prisma、spec、studio等包可在 waspc/waspc.cabal 的data-files中找到对应条目。
要让 Haskell 代码正确使用这些 TS 包(并在发布 tarball 中正确打包),需要它们在waspc_datadir目录中被正确安装/构建。开发中每当这些包有改动就运行:
./run build:packagesCI 构建 release 时也会执行同样的操作。data/packages/README.md还说明了新增包的规范:包目录需在package.json中提供build脚本和调用编译产物的start脚本,并在waspc.cabal的data-files中登记packages/<name>/package.json、package-lock.json及dist/**/*.js等文件。
WaspLibs:生成应用的构建块
WaspLibs 是 Wasp 自有的 npm 包,位于 waspc/data/Generator/libs/,其中包含会进入生成应用的核心逻辑。README(waspc/data/Generator/libs/README.md)明确了两条向生成应用注入代码的途径:
- 在
waspc/data/Generator/templates/写 Mustache 模板; - 在 libs 目录中开发真正的 JS 项目。
模板不是真正的 JS 工程(含 Mustache 语法),无法写测试、无法类型检查;而 libs 是真正的 JS 工程,可以写测试并被类型检查。理想做法是大部分逻辑放在 libs 中,模板只负责产出配置对象并编排这些 lib。
WaspLibs 的版本跟随 Wasp 编译器版本(如0.19.2),被视为 Wasp CLI 的实现细节。libs 的导出遵循按运行时区分的命名约定:
| 导出路径 | Node.js | 浏览器 | 说明 |
|---|---|---|---|
. | ✅ | ✅ | 两种运行时通用 |
./node | ✅ | ❌ | 仅 Node.js 运行时 |
./browser | ❌ | ✅ | 仅浏览器运行时 |
例如authlib 的package.json中可通过exports字段暴露@wasp.sh/lib-auth(通用)、@wasp.sh/lib-auth/node(Node 专用)与@wasp.sh/lib-auth/browser(浏览器专用)三个导入路径。开发 lib 时运行./run build:libs将编译产物复制进data/;由于 npm 按版本缓存已安装包而 lib 版本不变,必要时在 Wasp 应用根目录执行./run bust-libs-cache清理所有@wasp.sh/lib-*的锁文件条目、重新编译并重装依赖。
测试体系:Tasty、Hspec、QuickCheck 与快照测试
waspc 的 Haskell 测试基于Tasty测试框架,它允许把多种类型的测试组合进同一个测试套件。测试以"测试树"形式组织,可递归分组、混合 hspec / QuickCheck 等不同类型。
为避免手工组织测试文件与导入,项目使用tasty-discover自动发现测试:它自动识别包含测试的文件并组装成测试树。测试函数需要特殊前缀来标明类型:spec*表示 Hspec 测试、prop*表示 QuickCheck 属性测试等;也可以手动组织 Tasty 测试树并用test_前缀让 tasty-discover 拾取。目前自动发现被限制为只匹配*Test.hs结尾的文件。
三个测试框架各司其职:Hspec用于单元测试,QuickCheck用于属性测试,doctest用于测试文档中的代码示例。所有测试放入tests/目录(Haskell 构建工具不擅长把测试与源码混放)。在 waspc.cabal 中可以看到三个测试套件:waspc-tests(单元测试,入口tests/TastyDiscoverDriver.hs)、wasp-cli-tests(CLI 测试)与waspc-e2e-tests(e2e 快照测试,入口e2e-tests/Main.hs,依赖tasty-golden)。
运行测试的完整命令家族如下:
./run test # 运行所有测试 ./run test:waspc # 仅 waspc 测试(单元 + e2e) ./run test:waspc:unit # 仅 waspc 单元测试 ./run test:waspc:unit "Some test description to match" # 按描述模式运行单个单元测试 ./run test:waspc:e2e # 仅 waspc e2e 测试 ./run test:cli # 仅 Wasp CLI 测试 ./run test:kitchen-sink # kitchen-sink e2e 测试 ./run test:examples # 所有 examples e2e 测试 ./run test:starters # starter 模板 e2e 测试从 waspc/run 可以看到底层实现:test:waspc:unit执行cabal test waspc-tests,test:waspc:e2e执行cabal test waspc-e2e-tests,test:cli执行cabal test wasp-cli-tests;test:examples则循环遍历examples/tutorials/TodoApp、examples/tutorials/TodoAppTs、examples/waspello、examples/waspleau、examples/websockets-realtime-voting、examples/ask-the-documents、examples/kitchen-sink七个示例目录,逐一执行wasp-cli install && npm run test。
waspc e2e 快照测试:黄金输出的评审机制
waspc e2e 测试中有一类快照测试:对若干准备好的项目运行wasp-cli,验证它们能成功运行,并将生成的应用与期望的生成结果(golden 输出)做对比。
当你修改了影响生成应用的代码时,快照测试会失败并展示新旧输出的 diff。这给了你观察差异、确认其符合预期的机会。审查 diff 是 PR 作者(外部贡献则由 reviewer)的责任——不要盲目接受变更,务必确认与预期修改一致。确认满意后,用便捷命令接受新基线:
./run test:waspc:e2e:accept-all从 waspc/run 看,该命令的实现是"删除当前 golden 输出 → 重跑快照测试生成新 golden"。
代码质量检查:格式化、lint 与静态分析
提交 PR 前,务必让以下检查全部通过——它们同样是 CI 的门禁:
./run code-check该命令会依次执行代码格式化检查、lint 与静态分析,并输出汇总报告(waspc/run 的code-check分支分别记录 prettier / ormolu / cabal-gild / hlint / stan 五项结果)。目前 CI 只检查代码格式化,lint 与静态分析暂未纳入 CI(waspc/run 中的 TODO 注释说明未来会补上)。
格式化:Ormolu + cabal-gild + Prettier
Haskell 代码使用Ormolu格式化,通常在编辑器里配置保存时自动运行,也可手动执行:
./run check:ormolu # 检查是否存在需要格式化的文件 ./run format:ormolu # 就地格式化所有需要格式化的文件此外,.cabal文件由 cabal-gild 格式化,仓库整体代码由 Prettier 格式化:
./run check:cabal / ./run format:cabal ./run check:prettier / ./run format:prettier ./run check # 全部 formatter 的 check 模式 ./run format # 全部 formatter 就地格式化[!NOTE] 首次运行 Ormolu 相关命令时,安装依赖可能耗时约 10 分钟,后续运行会快得多。
Lint:hlint
使用hlint对 Haskell 代码做 lint:
./run hlint静态分析:stan
使用stan对代码库做静态分析(waspc/run 显示stan会先完整构建项目再运行分析):
./run stan该命令会构建代码库、以正确的 GHC 版本安装并运行 stan,结果输出到 CLI 并生成stan.html报告。首次运行同样需要约 10 分钟安装依赖。
分支与合并策略:main 与 release 的双轨模型
本仓库同时包含构成 Wasp 发布的源码(waspc/)以及包含文档与博客的网站(web/)。为兼顾新功能开发与线上文档/热修复,仓库采用最小化分支策略:
main:承载所有活跃开发的新功能与配套文档更新,可包含未发布的内容,但合入main的任何改动都应处于"可发布"状态。这是功能分支的默认目标分支。release:包含当前/最近 Wasp 发布的源码,以及已发布、网站可见的文档与博客。
完整发布(基于main制作新版本)的流程是:先把release合并进main(可能有冲突但易解决),再从更新后的main制作 waspc 发布;随后把main合并回release(上一步已解决冲突,故无冲突)。
如何选择 PR 目标分支?
- 需要立刻或很快发布的改动(网站内容、博客、文档热修复、需要以新 patch 版本快速发布的编译器热修复等)→ 目标为
release; - 不紧急、可等到下一个"常规" Wasp 发布的内容(新功能、重构、配套文档)→ 目标为
main。
一句话总结:release代表当下,面向已发布内容的改动;main代表近期未来,面向待发布内容的改动。
[!IMPORTANT] 若向
release合并 PR 或推送任何改动,系统会自动创建一个把release变更同步到main的 PR,并分配给你负责合入。
CI 与发布流程
项目使用 GitHub Actions 作为 CI,在main分支的任何提交、PR 以及以v开头的 tag 上运行。CI 在 Linux、macOS 与 Windows 上构建并测试 Wasp 代码。
提交以
v开头的 tag 时,会创建包含二进制包的 GitHub draft release,并将 Wasp npm 包上传到 npm 的暂存队列(须经维护者批准才会发布)。另有部署示例应用到 Fly.io 的 workflow(
release-examples-deploy.yaml),可在 GitHub UI 手动触发,通常应在发布新版本后从release分支运行,确保已部署示例使用最新稳定版 Wasp。也可用 GitHub CLI 触发:# 使用最新 Wasp 版本部署 gh workflow run release-examples-deploy --ref release # 使用指定版本部署 gh workflow run release-examples-deploy --ref release -f version=0.13.2提交信息中包含
[skip ci]可跳过 GitHub Actions。仓库还提供
new-release脚本辅助发版:传入新版本号(./new-release 0.3.0),它会检查一切就绪、创建对应 tag 并推送,从而触发 CI 在 GitHub 上创建新 release。
典型发布流程
以下步骤中带 👉 的步骤是每次waspc发布都必须执行的;其余步骤视改动情况决定(例如没有破坏性变更时可跳过部分步骤):
- 确保 OpenSaaS 已更新到最新 Wasp
main(手动运行其 e2e workflow)。 - 👉 确保已将
release分支的变更合并进main。 - 👉 拉取远端全部变更(
git fetch),确保本地main是最新。 - 👉 从要发布的最后一个提交(通常是最新
main)创建名为rc-<version>的 RC 分支(如rc-0.24.1),后续步骤都在该分支进行。 - 👉
waspc.cabal中的版本号应已正确,但需复核并按需更新;若修改了waspc.cabal,创建 PR、等待审批与 CI 通过,再 squash 合并进 RC 分支。 - 👉 创建 RC 发布并做测试与修复(见下文 Test releases),一切就绪后继续。
- 👉 检查自上次发布以来的提交,斟酌完善
ChangeLog.md与迁移指南。 - 若是主版本更新,在 RC 分支上运行
npm run docusaurus docs:version {version}为当前文档拍版本快照(在web/目录),提交到 RC 分支并推送。 - 👉 切换到
release分支,通过git merge --ff rc-<version>快进到 RC 分支。 - 👉 准备正式发布时确保处于
release分支,运行./new-release 0.x.y(脚本会做若干检查、打 tag 并推送)。 - 👉 等待新 tag 的 CI 完成且成功(tag 推送自动触发;完成后创建 GitHub draft release 并把 npm 包放到暂存队列)。
- 👉 找到 draft release,编辑发布说明(通常直接粘贴对应版本的 ChangeLog 条目),就绪后发布。
- 👉 批准暂存的 npm 包:
npm stage list查看 stage ID,npm stage approve <stage-id>逐一批准(需要 2FA)。 - 👉 推送本地
release分支到远端。 - 👉 你会在自动生成的"把
release合并回main"的 PR 中被 @(也可在 PR 列表按head:release base:main过滤找到),务必合并它——用 merge commit,不要 squash 或 rebase,确保main领先于release,避免未来发布产生合并冲突。 - 通过
release-examples-deployworkflow 把示例应用部署到 Fly.io。 - 若有文档改动,从
release分支发布新版本文档。 - 在 Discord 宣布新版本。
版本号如何确定
waspc遵循标准 SemVer 的major.minor.patch方案。由于尚未到 1.0,遵循约定将major保持为 0,破坏性变更时提升minor。
测试发布(RC)
制作测试发布(尤其是 Release Candidate)可以在不打扰普通用户的情况下先行验证。步骤:
从要发布的最后一个提交(通常是最新
main)创建rc-<version>分支。本地执行
new-release脚本,并在版本号后追加-rc.N以标明预发布性质(如./new-release 0.24.1-rc.1),脚本会给出一些可接受的警告。draft release 创建后:用 UI 将其标记为 pre-release 并发布——这是区分测试发布与正式发布的关键一步(会自动取消"latest release"的勾选);同时把
rc-<version>分支推送到远端。批准暂存的 npm 包(
npm stage list+npm stage approve <stage-id>,需 2FA)。显式指定版本安装包进行验证:
npm i -g @wasp.sh/wasp-cli@0.24.1-rc.1创建 checklist 并走查发布前事项;发现问题就在
rc分支上修复并照同样流程创建下一个 RC(如0.24.1-rc.2)。
文档、Haskell 实践与依赖策略
- 外部文档:面向 Wasp 用户的文档托管于官网,其源码就在本仓库的 web/docs 目录中,与网站、博客同处
web/下。 - Haskell 最佳实践:项目维护独立的 Haskell Handbook 记录相关最佳实践。
- Cabal 依赖冻结:项目刻意不使用 cabal freeze 文件来锁定依赖,而是借助 cabal 的
index-state特性从 Hackage 获得包版本固定,以更好地支持更广泛的开发者操作系统(waspc/cabal.project 中可查看实际配置)。
代码风格指南
注释规范
注释以大写字母开头时,必须以标点结束;不以大写开头则不应以标点结尾。
TODO / NOTE 一律全大写:
-- TODO: Wash the car. -- NOTE: This piece of code is slow.可在 TODO / NOTE 后附加作者名,便于读者在需要时咨询原作者:
-- TODO(martin): Doesn't work on my machine in some unusual use cases.
JavaScript 函数风格
顶层具名函数优先使用函数声明语句,而非箭头函数或函数表达式:
// good function foo(param) { // ... } // bad const foo = (param) => { // ... }; // bad const foo = function (param) { // ... };内联函数表达式优先使用箭头语法:
// good const squares = arr.map((x) => x * x); // bad const squares = arr.map(function (x) { return x * x; });
设计文档(RFC):复杂功能的标准流程
如果实现的功能因设计或技术实现而复杂,README 推荐先写一份设计文档(RFC)。做法是提交一个 PR,在wasp/docs/design-docs下新增 Markdown 文档,阐述功能实现的思路与决策。其他人会在文档上评论,经过必要迭代并获得批准后,再在单独的 PR 中开始实现。
结语
waspc 以"Analyzer 产出 AppSpec、Generator 产出 FileDraft"的两层管线,将声明式配置精确转换为全栈应用,其工程实践(Bash 驱动的run开发工具链、Tasty 多框架测试体系、快照 golden 评审机制、双分支发布模型)本身就是一份高质量的编译器项目范本。无论你是想修复 bug、添加新功能,还是仅仅想理解一个真实 Haskell 编译器如何工作,都可以从./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),仅供参考