Wasp 子目录部署指南:baseDir 与 WASP_WEB_CLIENT_URL 的正确配置
【免费下载链接】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 应用部署到域名子路径(如https://example.com/my-app)时,需要在main.wasp中配置client.baseDir,同时必须保证服务端环境变量WASP_WEB_CLIENT_URL包含同样的子路径前缀。本文结合 Wasp 0.19 官方文档 client-config.md 及仓库源码,说明这一配置约束的来龙去脉、底层实现与排查方法,帮助你在子目录部署场景下避免路由 404 与资源加载失败。
为什么需要 baseDir:子目录部署的两种典型场景
默认情况下,Wasp 生成的客户端应用假定自己挂在域名根路径下,React Router 的basename为/,Vite 构建产物的base也是/。当出现以下两种场景时,这种假设不再成立:
- 静态托管子目录:例如将客户端构建产物部署到 CDN 或对象存储的某个目录下,通过
https://example.com/my-app对外提供访问; - 多应用共域:同一个域名下托管多个 Web 应用,每个应用占据一个子路径。
此时如果不做任何配置,浏览器访问https://example.com/my-app时,React Router 无法正确匹配路由(页面 404),打包后的 JS/CSS 资源也会从错误路径(https://example.com/...)加载。Wasp 提供的client.baseDir配置项正是为解决这一问题而生。
配置 baseDir:声明与效果
在main.wasp的app声明中加入client.baseDir即可:
app MyApp { title: "My app", // ... client: { baseDir: "/my-app", } }依据官方文档,当应用从https://example.com/my-app提供访问时,配置baseDir: "/my-app"后:
- 路由器能够正确解析并匹配
https://example.com/my-app之下的所有路由; - 所有静态资源(JS、CSS、图片等)都会从
https://example.com/my-app前缀下加载。
底层实现:baseDir 如何同时作用于 Router 与 Vite
从源码看,baseDir并非一个孤立的配置项,它在生成客户端代码时会被注入到两个关键位置:
- React Router 的
basename。在客户端入口模板 client-entry.tsx 中,createBrowserRouter调用时传入basename,该值直接取自baseDir:
const router = createBrowserRouter({= routeObjects.importIdentifier =}, { basename: "{= baseDir =}", ... })baseDir在 SDK 生成阶段通过 VitePluginG.hs 等模板注入点写入生成代码,从而让浏览器端的路由始终基于子路径解析。
- Vite 的
base配置。同一份baseDir还会作为 Vite 构建的base选项,决定打包产物中资源引用的公共路径,保证 HTML 中引用的 JS/CSS 链接带上子路径前缀。
校验规则与默认值
- 必须以
/开头:仓库的校验逻辑位于 Valid.hs 的validateWebAppBaseDir,若baseDir不以斜杠开头(例如写成"my-app"或"my-app/"),Wasp 会报错:The app.client.baseDir should start with a slash e.g. "/test"。 - 默认值为
/:当未配置client.baseDir时,生成器取默认根路径,见 WebAppGenerator/Common.hs 中的getBaseDir(fromMaybe [absdirP|/|])。因此不配置该选项时,一切行为与baseDir: "/"等价。
核心注意事项:WASP_WEB_CLIENT_URL 必须与 baseDir 保持一致
⚠️这是本文最关键的一条约束:一旦设置了
baseDir,必须确保环境变量WASP_WEB_CLIENT_URL也包含该子目录路径。
例如,如果应用从https://example.com/my-app提供服务,那么WASP_WEB_CLIENT_URL也必须设置为https://example.com/my-app,而不能只设置为https://example.com。
这一注意事项来自官方文档中随baseDir一同出现的环境变量说明(见 _baseDirEnvNote.md,该说明在 client-config.md 的 “Base Directory” 小节与baseDir的 API Reference 中被引用)。之所以如此强调,是因为这两者的作用域完全不同:
baseDir只管浏览器端:它决定 React Router 的路由前缀与 Vite 资源的公共路径,属于客户端构建与运行层面的配置;WASP_WEB_CLIENT_URL影响服务端:它在服务端生成代码中被定义为客户端 URL 的环境变量名,见 ServerGenerator/Common.hs(clientUrlEnvVarName = "WASP_WEB_CLIENT_URL"),服务端据此配置 CORS 允许来源等安全策略(Wasp 的版本历史中也明确记录过该变量是“为了提升 CORS 安全性而引入的必要环境变量”,见 ChangeLog.md)。
当两者不一致时,最典型的现象是:页面本身能通过子路径正常访问,但来自服务端 API 的跨域请求被浏览器拦截——因为服务端 CORS 允许的源是https://example.com,而页面实际来源是https://example.com/my-app,二者不匹配导致请求失败。
生产环境的两种配置方式
- 手动配置:在部署平台的环境变量中,将
WASP_WEB_CLIENT_URL显式设置为包含子路径的完整 URL,例如https://example.com/my-app。 - 部署工具自动推导:仓库内置的部署包在初始化 Fly 或 Railway 环境时,会自动写入
WASP_WEB_CLIENT_URL。例如 Fly 部署脚本 setup.ts 会将其设为客户端 Fly 应用的 URL,Railway 脚本 setup.ts 同理。需要留意的是:若这些工具推导出的 URL 不含子路径,而你又在main.wasp中设置了baseDir,仍需要手动覆盖为带子路径的完整地址。
配置清单与排查建议
在子目录部署时,按以下顺序逐项核对:
- 声明 baseDir:在 main.wasp(或你的项目
main.wasp)的client块中写入baseDir,确保以/开头且无尾部多余斜杠; - 同步环境变量:将生产环境中的
WASP_WEB_CLIENT_URL设置为「域名 + baseDir」的完整形式,例如https://example.com/my-app; - 核对服务端 URL:确认
WASP_SERVER_URL指向 API 服务根地址(不含子路径前缀),避免客户端请求 API 时再次叠加错误的路径; - 本地联调验证:在浏览器开发者工具中检查 Network 面板——HTML 中引用的 JS/CSS 请求 URL 应带子路径前缀;同时确认 API 请求的
Origin头与WASP_WEB_CLIENT_URL完全一致。
如果出现“页面白屏 / 资源 404”,优先检查 Vite 构建产物的资源前缀是否带上baseDir;如果出现“接口跨域报错”,优先核对WASP_WEB_CLIENT_URL是否遗漏了子路径。
相关阅读
- 完整配置说明与 API 参考:client-config.md(涵盖
rootComponent、setupFn、baseDir三个客户端选项的完整用法) - 环境变量注意事项原文:_baseDirEnvNote.md
- 生成器对
baseDir的默认值与解析:WebAppGenerator/Common.hs - 客户端入口模板中 Router
basename的注入:client-entry.tsx WASP_WEB_CLIENT_URL在服务端生成代码中的定义:ServerGenerator/Common.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),仅供参考