ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Wasp 运行时配置访问全解:深入理解 server `config` 与 client `config` 对象(frontendUrl 与 apiUrl)

Wasp 运行时配置访问全解:深入理解 server `config` 与 client `config` 对象(frontendUrl 与 apiUrl) Wasp 运行时配置访问全解深入理解 serverconfig与 clientconfig对象frontendUrl 与 apiUrl【免费下载链接】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 应用在运行时由客户端与服务端两个独立进程组成Wasp 通过配置对象configuration objects让开发者以类型安全的方式在代码中访问这两个进程的关键运行时配置。本文以 Wasp 0.16 文档为骨架结合本仓库waspc中 SDK 模板与生成器的源码实现完整讲解WASP_WEB_CLIENT_URL/REACT_APP_API_URL两个核心环境变量的作用、config对象的访问方式及其底层原理帮助你正确地在前后端代码中读取运行时 URL并规避部署环境下的常见坑。双进程架构Wasp 应用的运行时构成Wasp 应用每次启动时实际上会启动两个独立进程它们分别承载前端与后端客户端进程The client process实现应用前端的 React 应用。开发阶段它是一个带热重载hot reloading的 dev server生产阶段它是一个简单的进程用于托管预先构建好的静态文件环境变量在构建时被内嵌进产物中具体细节取决于部署方式。服务端进程The server process实现应用后端的 Express 服务器。开发阶段它是一个由nodemon进程托管的 Express 服务器负责热重载与自动重启生产阶段它就是一个由 Node 直接运行的普通 Express 服务器。这两个进程都可以通过环境变量进行配置。Wasp 为它们分别维护了一套受支持的环境变量清单完整列表参见环境变量文档。而要让代码在运行时读取这些配置Wasp 提供的就是配置对象configuration objects——这也是本文的主角。配置对象与env对象的区别在深入之前先厘清两个容易混淆的 APIconfig本文主题暴露 Wasp 内置的、经过处理的运行时配置如frontendUrl、apiUrl字段已经过校验与标准化处理。env暴露原始环境变量Wasp 内置变量 用户自定义变量同样经过 Zod 模式校验但保留变量原有的命名与取值。二者都从wasp/server与wasp/client两个入口导出。本文聚焦config对象其定义位于 SDK 模板中客户端模板client/config.ts服务端模板server/config.tsServer 配置对象如何读取frontendUrl服务端配置对象包含以下字段frontendUrl: String—— 通过环境变量WASP_WEB_CLIENT_URL设置。含义你的客户端应用前端的 URL开发阶段运行wasp start时 Wasp 会自动设置它生产阶段你应该把它设置为服务端视角下的客户端 URL即要把 DNS 与反向代理因素考虑进去。在服务端代码中这样访问import { config } from wasp/server console.log(config.frontendUrl)源码视角frontendUrl的取值链路从本仓库的服务端 SDK 模板 server/config.ts 可以看出frontendUrl并非简单透传环境变量而是经过了去尾部斜杠的标准化处理const frontendUrl stripTrailingSlash(env[WASP_WEB_CLIENT_URL])stripTrailingSlash定义于 universal/url.ts其实现为url?.replace(/\/$/, )即移除 URL 末尾的单个/。这意味着无论你在.env.server中写的是https://myapp.com还是https://myapp.com/config.frontendUrl读到的都是不带尾部斜杠的统一形式。环境变量名WASP_WEB_CLIENT_URL的出处可以在生成器源码 ServerGenerator/Common.hs 中找到clientUrlEnvVarName :: String clientUrlEnvVarName WASP_WEB_CLIENT_URL不止frontendUrl服务端config的完整字段虽然原文档只声明了frontendUrl一个公开字段但从 server/config.ts 的模板实现看服务端配置对象实际还包含以下字段可以推断这些是 SDK 内部使用、同样可通过config访问的配置字段类型来源环境变量说明frontendUrlstringWASP_WEB_CLIENT_URL客户端 URL文档公开字段serverUrlstringWASP_SERVER_URL服务端自身 URL用于 OAuth 回调等场景envdevelopment \| productionNODE_ENV当前运行环境isDevelopmentboolean由NODE_ENV推导便捷布尔标记portnumberPORT服务端监听端口默认3001databaseUrlstringDATABASE_URLPostgreSQL 连接串allowedCORSOrigins(string \| RegExp)[]由NODE_ENV与frontendUrl推导允许的 CORS 来源auth.jwtSecret启用认证时stringJWT_SECRETJWT 签名密钥其中allowedCORSOrigins的行为尤其值得注意开发环境下 Wasp 允许所有来源[/.*/]生产环境下则只允许frontendUrl的 origin。也就是说生产环境里WASP_WEB_CLIENT_URL配置是否正确会直接决定浏览器跨域请求是否被服务端接受——这是配置对象影响面超出读取一个字符串的一个典型例子。谁在使用frontendUrl邮件与 OAuth 的真实调用场景frontendUrl并非仅供开发者自己console.logWasp 自身的认证体系就在使用它拼接前端跳转地址。两个可以直接在仓库中验证的实例邮件验证链接的拼接见 server/auth/email/utils.tsreturn${waspServerConfig.frontendUrl}${clientRoute}?token${jwtToken}OAuth 登录成功后的前端回调跳转见 server/auth/oauth/redirect.tsnew URL(${config.frontendUrl}${clientOAuthCallbackPath}#${oneTimeCode})这意味着如果生产环境的WASP_WEB_CLIENT_URL配错比如漏了代理前缀、多写了路径用户收到的验证邮件链接和第三方登录回调都会指向错误的地址。配置对象承载的不仅是给代码读的值更是认证流程正确性的前提。Client 配置对象如何读取apiUrl客户端配置对象包含以下字段apiUrl: String—— 通过环境变量REACT_APP_API_URL设置。含义你的服务端应用后端的 URL开发阶段运行wasp start时 Wasp 会自动设置它生产阶段它应包含用户浏览器视角下的服务端 URL同样要考虑 DNS 与反向代理。在客户端代码中这样访问import { config } from wasp/client console.log(config.apiUrl)源码视角apiUrl的取值链路客户端 SDK 模板 client/config.ts 的实现与服务端对称const apiUrl stripTrailingSlash(env[REACT_APP_API_URL]) export const config: ClientConfig { apiUrl, }同样经过stripTrailingSlash处理且ClientConfig类型被显式导出客户端代码可获得完整的类型提示。环境变量名REACT_APP_API_URL的出处位于 WebApp 生成器 WebAppGenerator/Common.hsserverUrlEnvVarName REACT_APP_API_URL客户端环境变量的校验与默认值从客户端环境变量校验模式 client/env/schema.ts 可以看到REACT_APP_API_URL在内置校验中是一个必须为合法 URL的字符串const serverUrlSchema z.string({ error: REACT_APP_API_URL is required }) .pipe( z.url({ error: REACT_APP_API_URL must be a valid URL }) )而根据环境变量文档中的参数表REACT_APP_API_URL不是必填项默认值为http://localhost:3001——即在开发模式下即使不显式配置客户端也会默认把请求发往本机 3001 端口。客户端环境变量在构建时被注入到浏览器代码中因此任何人都可以读取切勿在其中存放密钥。开发与生产的自动设置差异config对象两个字段在开发与生产环境下的取值来源完全不同字段开发wasp start生产部署config.frontendUrl服务端Wasp 自动设置必须手动设置WASP_WEB_CLIENT_URL取服务端视角的客户端 URLconfig.apiUrl客户端Wasp 自动设置默认http://localhost:3001必须手动设置REACT_APP_API_URL取浏览器视角的服务端 URL开发阶段Wasp CLI 负责在两个进程启动时注入合适的值开发者通常无需关心。生产阶段这两个值必须由部署配置提供且各自遵循不同的视角——frontendUrl是服务端看到的客户端apiUrl是浏览器看到的服务端。当应用部署在域名后并经过反向代理时这两个视角往往会与字面上配的地址产生差异这也是生产配置最容易出错的地方。开发阶段如何提供环境变量可参考环境变量文档中的两种方式在项目根目录使用.env.server与.env.client文件推荐或直接在 shell 中定义优先级更高适合临时覆盖。其中客户端环境变量的注入机制可见于 Vite 插件 envFile.ts它只在开发模式env.command serve下加载.env.client文件仅把带REACT_APP_前缀的键暴露给客户端并保证 shell 中的内联变量优先于文件变量。实践建议与常见问题不要在config之外散落硬编码 URL统一通过config.frontendUrl/config.apiUrl读取可以自动享受尾部斜杠标准化与 URL 合法性校验避免手写拼接导致的格式不一致。生产环境务必显式设置两个变量WASP_WEB_CLIENT_URL与REACT_APP_API_URL虽在开发期可被自动注入但生产部署时必须根据你的域名、代理与端口自行配置否则会出现邮件链接打不开、OAuth 回调失败或 CORS 请求被拒等问题。注意视角差异frontendUrl用服务端视角经 DNS、代理后可达的客户端地址apiUrl用浏览器视角用户可直接访问的服务端地址两者配置颠倒或遗漏代理路径都会导致运行时功能异常。理解配置对象的类型安全价值从模板源码看服务端Config与客户端ClientConfig类型均随 SDK 生成配合 TypeScript 项目参见仓库内各示例的tsconfig.jsonIDE 可对config.xxx做完整的字段补全与类型检查这是直接读process.env/import.meta.env无法获得的保障。区分config与env需要读取自定义业务变量如STRIPE_API_KEY时使用env对象并配合main.wasp中的envValidationSchema声明 Zod 校验需要读取 Wasp 内置的运行时 URL 时使用config对象二者职责互补。小结Wasp 通过双进程架构将前端与后端解耦并以config配置对象统一暴露两侧的运行时关键配置服务端通过WASP_WEB_CLIENT_URL得到frontendUrl客户端通过REACT_APP_API_URL得到apiUrl。在开发期 Wasp 自动注入、生产期手动配置的前提下配合模板源码中可见的尾部斜杠标准化、URL 校验与 CORS 推导逻辑config对象构成了 Wasp 应用在前后端间可靠传递运行时地址的基础设施。理解它的取值链路与使用场景是正确部署和排障 Wasp 应用的必修课。【免费下载链接】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),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进