
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该值直接取自baseDirconst 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 中的getBaseDirfromMaybe [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.hsclientUrlEnvVarName 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 应用的 URLRailway 脚本 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客户端入口模板中 Routerbasename的注入client-entry.tsxWASP_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),仅供参考