尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Wasp 客户端配置详解:client 字段中 rootComponent、setupFn 与 baseDir 的用法与源码实现

Wasp 客户端配置详解:client 字段中 rootComponent、setupFn 与 baseDir 的用法与源码实现 Wasp 客户端配置详解client 字段中 rootComponent、setupFn 与 baseDir 的用法与源码实现【免费下载链接】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 框架 v0.12 版文档 Client Config系统讲解app声明中client字段的三个核心选项rootComponentReact 根组件、setupFn客户端初始化函数与baseDir子目录部署。文章同时深入 waspc 编译器与代码生成模板源码说明这三个配置在生成产物中的实际生效路径帮助你不仅会用这些配置还能理解它们背后的实现机制与适用边界。一、配置入口app声明中的client字段在 Wasp 中客户端即浏览器端 React 应用的行为通过main.wasp中app声明的client字段来定制。v0.12 版文档给出的完整写法JavaScript 与 TypeScript 项目分别对应.jsx/.tsx与.ts文件app MyApp { title: My app, // ... client: { rootComponent: import Root from src/Root.jsx, // TS 项目为 src/Root.tsx setupFn: import mySetupFunction from src/myClientSetupCode.js } }在编译器侧client字段对应的数据模型定义于 Client.hsdata Client Client { setupFn :: Maybe ExtImport, rootComponent :: Maybe ExtImport, -- We expect the base dir to start with a slash e.g. /client baseDir :: Maybe String, envValidationSchema :: Maybe ExtImport }可以确认三个选项在 AppSpec 中均为Maybe即全部可选源码注释也明确要求baseDir必须以斜杠开头。二、rootComponent定义应用级根组件Wasp 允许你为 React 应用定义一个包装wrapper组件。文档指出其最常见的两类用途定义整个应用共用的布局header/footer 等挂载应用所需的各类 React Provider。定义公共布局app MyApp { title: My app, // ... client: { rootComponent: import Root from src/Root.jsx, } }export default function Root({ children }) { return ( div header h1My App/h1 /header {children} footer pMy App footer/p /footer /div ) }TypeScript 版本只是加上类型标注export default function Root({ children }: { children: React.ReactNode }) { return ( div header h1My App/h1 /header {children} footer pMy App footer/p /footer /div ) }挂载 Providerimport store from ./store import { Provider } from react-redux export default function Root({ children }) { return Provider store{store}{children}/Provider }文档强调只要渲染了children根组件里可以放置任何东西。从源码结构看这一点体现在生成模板 routes.tsx 中——当rootComponent已定义时模板会导入你的组件并将其渲染在路由Outlet之上包裹住所有页面路由若未定义则直接渲染Outlet /const rootElement div idroot { /* 若定义了 rootComponent*/ } RootComponent / { /* 否则Outlet / */ } /div文档 API 参考部分给出的Provider 自定义布局组合写法同样完整保留import store from ./store import { Provider } from react-redux export default function Root({ children }) { return ( Provider store{store} Layout{children}/Layout /Provider ) } function Layout({ children }) { return ( div header h1My App/h1 /header {children} footer pMy App footer/p /footer /div ) }仓库中的完整示例 examples/kitchen-sink 展示了当前版本 TS spec 语法下的等价写法client.rootComponent指向src/App.tsxclient.setupFn指向clientSetup函数并额外配置了envValidationSchema。三、setupFn客户端启动前的初始化函数setupFn声明一个由 Wasp 在客户端先于一切其他逻辑执行的函数。文档明确其契约必须是异步函数Wasp 会 await 其完成后再渲染页面函数不接受任何参数返回值被忽略。从生成模板 routes.tsx 可以看到这一执行顺序的实现证据{ /* 若定义了 setupFn*/ } await { /* setupFn 导入标识符 */ }() initializeQueryClient()即先await你的 setup 函数再初始化 QueryClient最后才构建并渲染路由元素。这保证了你在 setup 函数中完成的任何状态准备如全局配置注入、埋点初始化都一定发生在页面渲染之前。场景一运行任意客户端代码文档给出的示例——每小时输出一条在线时长日志export default async function mySetupFunction() { let count 1 setInterval( () console.log(You have been online for ${count} hours.), 1000 * 60 * 60 ) }export default async function mySetupFunction(): Promisevoid { let count 1 setInterval( () console.log(You have been online for ${count} hours.), 1000 * 60 * 60 ) }场景二覆盖 Query 的全局默认配置Wasp 的useQueryhook 底层基于react-queryTanStack Query的useQuery。由于 react-query 自带激进但合理的默认选项绝大多数场景无需改动全局默认值而单个 Query 的选项可通过options对象单独覆盖参见 queries 文档中 The useQuery hook 一节。当确实需要修改全局默认值时应在客户端 setup 函数中调用 Wasp 暴露的configureQueryClienthook 来配置底层QueryClient对象import { configureQueryClient } from wasp/client/operations export default async function mySetupFunction() { // ... some setup configureQueryClient({ defaultOptions: { queries: { staleTime: Infinity, }, }, }) // ... some more setup }注意传入的对象必须符合QueryClient构造函数的QueryClientConfig类型。该约束在生成代码中有严格实现见 queryClient.ts// PUBLIC API export function configureQueryClient(config: QueryClientConfig): void { if (isQueryClientInitialized) { throw new Error( Attempted to configure the QueryClient after initialization ) } queryClientConfig config; }也就是说configureQueryClient必须在QueryClient初始化之前调用这正是 setup 函数被await在先的价值所在否则直接抛错初始化时若未调用过它则回退到空配置{}即采用 react-query 自带的默认值。四、baseDir从子目录部署应用当需要把应用部署到域名下的子路径时使用baseDir选项app MyApp { title: My app, // ... client: { baseDir: /my-app, } }设置后如果应用部署在https://example.com/my-app路由器和所有静态资源都会正确地以https://example.com/my-app为基准工作。源码层面对 baseDir 的处理校验Valid.hs 在分析阶段校验baseDir必须以/开头否则报错The app.client.baseDir should start with a slash e.g. /test默认值getBaseDir 在未配置时回退为/注入 RouterAppG.hs 的 genRouter 将baseDir传入router.tsx模板最终体现在 client-entry.tsx 中createBrowserRouter的basename参数SSR 入口ssr-entry.tsx同样注入注入 Vite 构建配置VitePluginG.hs 将baseDir写入 Vite 配置的base选项使打包产物的资源 URL 前缀一致。环境变量注意事项引用 BaseDirEnvNote 的原文警告设置了baseDir时必须同步修改WASP_WEB_CLIENT_URL环境变量使其包含该基础目录。例如应用部署在https://example.com/my-app时WASP_WEB_CLIENT_URL应设为https://example.com/my-app而不是仅https://example.com否则客户端资源定位会出错。五、API 参考汇总client字段全部选项一览v0.12 文档语法app MyApp { title: My app, // ... client: { rootComponent: import Root from src/Root.tsx, setupFn: import mySetupFunction from src/myClientSetupCode.ts, baseDir: /my-app, } }选项类型说明rootComponentExtImport客户端应用根组件。必须是 React 组件Wasp 用它包裹整个应用必须渲染children即你的页面setupFnExtImport客户端先于一切执行的异步初始化函数。无参数返回值被忽略Wasp await 其完成后才渲染页面。可用于自定义初始化如客户端周期性任务、覆盖 Query 全局默认值baseDirString以/开头的子路径。同时设置 Router 的basename与 Vite 的base用于子目录部署六、版本适用说明本文以 v0.12 版 Client Config 文档 为主体该版本使用main.wasp文件加import ... from src/...的 DSL 语法书写client配置。当前仓库主干已演进为 TypeScript spec 写法如 examples/kitchen-sink/main.wasp.ts 中以export default app({ ... client: { rootComponent, setupFn, envValidationSchema } ... })对象形式声明但三个选项的语义、执行顺序与baseDir的环境变量约束在生成器实现中保持一致阅读旧版配置知识迁移到新版时只需替换书写语法。【免费下载链接】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),仅供参考
返回列表