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

资讯详情

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

Angular Query 的 DevtoolsFeature 类型解析:withDevtools 特性背后的类型设计与加载机制

Angular Query 的 DevtoolsFeature 类型解析:withDevtools 特性背后的类型设计与加载机制 Angular Query 的 DevtoolsFeature 类型解析withDevtools 特性背后的类型设计与加载机制【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/queryAngular Query 将可选的扩展能力例如开发工具、查询持久化封装为统一的一等公民“特性Feature”而DevtoolsFeature正是描述“启用开发者工具”这一特性的类型别名它用于刻画withDevtools函数的返回值。读完本文你将理解DevtoolsFeature QueryFeatureDevtools的真实含义、它在 providers.ts 中的定义位置与产生方式掌握它在 devtools 指南 中的完整配置用法以及生产构建如何通过替换桩实现自动裁剪 devtools 加载逻辑。DevtoolsFeature 是什么一张“类型标签化”的契约查看 DevtoolsFeature 类型别名文档可以看到其完整定义只有一行type DevtoolsFeature QueryFeatureDevtools;它本质上是泛型接口QueryFeatureTFeatureKind用字面量类型Devtools实例化后的别名。真正承载结构的是源码中定义的QueryFeature接口见 packages/angular-query-experimental/src/providers.ts#L135-L138export interface QueryFeatureTFeatureKind extends QueryFeatureKind { ɵkind: TFeatureKind ɵproviders: ArrayProvider }一个 Query 特性对象包含两个成员ɵkind特性种类标识用于区分不同特性。所有可用的种类收敛在常量数组queryFeatures [Devtools, PersistQueryClient] as constproviders.ts#L128派生的联合类型QueryFeatureKind中ɵproviders该特性真正注入进应用的 AngularProvider[]即特性的实际“生效内容”。与DevtoolsFeature并列的是代表持久化能力的PersistQueryClientFeature QueryFeaturePersistQueryClientproviders.ts#L164对应文档 PersistQueryClientFeature。两者合并成为QueryFeatures联合类型providers.ts#L173export type QueryFeatures DevtoolsFeature | PersistQueryClientFeature从源码结构看这种“ɵkind字符串标签 ɵprovidersprovider 列表”的设计使provideTanStackQuery无需关心每个特性的具体业务逻辑只要拿到QueryFeatures数组并统一展开ɵproviders即可——这是一种轻量的可插拔特性机制也是 QueryFeatures 类型文档 所强调的“通过向provideTanStackQuery调用添加特殊函数来启用特性”的含义所在。特性的统一工厂queryFeature 与 DevtoolsFeature 的构造为了让所有特性的对象结构保持一致Angular Query 在 providers.ts#L146-L151 提供了辅助函数queryFeatureexport function queryFeatureTFeatureKind extends QueryFeatureKind( kind: TFeatureKind, providers: ArrayProvider, ): QueryFeatureTFeatureKind { return { ɵkind: kind, ɵproviders: providers } }它只是把kind与providers打包成一个QueryFeature实例。withDevtools内部正是调用它完成DevtoolsFeature的创建。从工程视角看这套统一机制有明确收益可组合provideTanStackQuery接收...features: ArrayQueryFeatures变长参数devtools 与持久化特性可以按任意顺序、任意数量叠加可替换由于DevtoolsFeature只是一个“描述返回类型”的别名文档原文强调 “The type is used to describe the return value of thewithDevtoolsfunction”同一种类型既可由真实实现构造也可由生产构建桩构造见下文 stub 分析类型层面二者完全等价。withDevtools 的返回类型契约与典型接入方式withDevtools的完整签名定义在 devtools/types.ts#L110-L112export type WithDevtools ( withDevtoolsFn?: WithDevtoolsFn, options?: WithDevtoolsOptions, ) DevtoolsFeature即入参是一个可选的返回DevtoolsOptions的回调函数与一个可选的WithDevtoolsOptions返回值永远是DevtoolsFeature。这与 DevtoolsFeature 文档 中“该类型用于描述withDevtools的返回值”的描述一一对应。典型用法是将其作为第二参传给provideTanStackQuery参见 provideTanStackQuery 参考文档 与 devtools 指南import { QueryClient, provideTanStackQuery } from tanstack/angular-query-experimental import { withDevtools } from tanstack/angular-query-experimental/devtools export const appConfig: ApplicationConfig { providers: [provideTanStackQuery(new QueryClient(), withDevtools())], }执行链路如下实现证据见 packages/angular-query-experimental/src/providers.ts#L105-L113withDevtools()调用queryFeature(Devtools, [...providers])生成一个DevtoolsFeature其ɵproviders中注册了内部令牌DEVTOOLS_OPTIONS_SIGNAL与一个ENVIRONMENT_INITIALIZERprovideTanStackQuery(queryClient, ...features)先调用provideQueryClient注册共享的QueryClient并在 injector 销毁时自动unmount随后用features.map((feature) feature.ɵproviders)扁平展开所有特性的 providerAngular 启动时执行ENVIRONMENT_INITIALIZER按需在浏览器端动态创建 devtools 实例并挂载到body。DevtoolsOptions回调返回的配置项全解withDevtools允许通过回调函数返回配置对象DevtoolsOptions完整定义见 devtools/types.ts#L42-L106。下表整理了文档与源码共同确认的全部选项、类型与默认值选项类型默认值说明loadDevtoolsauto \| booleanautoauto仅在 Angular 开发模式下延迟加载生产模式跳过true任何环境都加载false任何环境都不加载。还支持用信号signal驱动动态加载initialIsOpenboolean—是否让 devtools 面板默认处于展开状态buttonPositiontop-left \| top-right \| bottom-left \| bottom-right \| relativebottom-right悬浮按钮TanStack logo的位置relative表示渲染在开发者指定插入的位置positiontop \| bottom \| left \| rightbottomdevtools 面板停靠方位clientQueryClient注入的实例指定自定义QueryClient缺省时自动注入provideTanStackQuery提供的客户端errorTypes{ name: string; initializer: (query: Query) TError }[]—预定义可在 UI 上触发的错误类型切换时会用具体 query 调用initializer生成错误styleNoncestring—为写入head的 style 标签附加 CSP nonce用于允许内联样式shadowDOMTargetShadowRootdocument.head让 devtools 样式作用于指定 Shadow DOM 内部而非 light DOM 的 headhideDisabledQueriesboolean—是否在面板中隐藏被禁用的查询themelight \| dark \| systemsystem面板主题此外源码 with-devtools.ts#L99-L104 揭示了loadDevtools的求值细节const shouldLoadToolsSignal computed(() { const { loadDevtools } devtoolsOptions() return typeof loadDevtools boolean ? loadDevtools : isDevMode() })即auto最终会被解析为isDevMode()的结果——这正是“生产构建默认不加载 devtools”的运行时依据。生产环境的两种加载姿态sub-path 与桩替换为什么生产包默认没有 devtoolsAngular Query 通过打包器替换实现了“开发包含、生产裁剪”。在 packages/angular-query-experimental/src/devtools/stub.ts 中生产构建会用如下桩替换真实实现export const withDevtools: WithDevtools () ({ ɵkind: Devtools, ɵproviders: [], })桩与真实函数具有完全相同的类型签名都返回DevtoolsFeature因此类型安全不受影响但ɵproviders为空数组——特性注册了却不会注入任何 providerdevtools 相关代码随之被摇树tree-shaking掉。production sub-path显式保留若需要在生产环境例如 staging也使用 devtools应改从production子路径导入。该子路径导出的函数与主入口完全一致但不会被排除在生产构建之外参见 devtools 指南的生产小节import { withDevtools } from tanstack/angular-query-experimental/devtools/production配合 Angular 的环境配置文件可以做到“只有特定环境才加载”import { environment } from ./environments/environment import { withDevtools } from tanstack/angular-query-experimental/devtools/production provideTanStackQuery( new QueryClient(), withDevtools(() ({ loadDevtools: environment.loadDevtools })), )其中environment.loadDevtools是布尔值会被shouldLoadToolsSignal直接采用也可以显式固定为true始终加载或false永不加载。用响应式信号驱动加载回调函数与 deps 注入devtools 指南 Derive options through reactivity 一节演示了如何让加载决策“活”起来。选项之所以放在回调里返回是为了借助 Angular 信号保持响应式——with-devtools.ts内部把回调结果包进了computed(() withDevtoolsFn?.(...deps) ?? {})with-devtools.ts#L68-L70随后在主effect中订阅当shouldLoadToolsSignal或任意选项信号变化时自动创建、更新或销毁 devtools 实例with-devtools.ts#L120-L178。例如把“快捷键 Ctrl/CmdShiftD 唤起面板”抽象成服务Injectable({ providedIn: root }) export class DevtoolsOptionsManager { loadDevtools toSignal( fromEventKeyboardEvent(document, keydown).pipe( map( (event): boolean event.metaKey event.ctrlKey event.shiftKey event.key D, ), scan((acc, curr) acc || curr, isDevMode()), ), { initialValue: isDevMode() }, ) }随后通过options.deps把服务注入回调机制与 AngularuseFactory的deps一致export const appConfig: ApplicationConfig { providers: [ provideHttpClient(), provideTanStackQuery( new QueryClient(), withDevtools( (devToolsOptionsManager: DevtoolsOptionsManager) ({ loadDevtools: devToolsOptionsManager.loadDevtools(), }), { // deps 中的令牌会被注入并作为参数传给回调 deps: [DevtoolsOptionsManager], }, ), ), ], }deps的类型定义见 devtools/types.ts#L13-L37它是一个任意令牌数组deps?: Arrayany在 provider 工厂中作为deps: options.deps || []传递给注入器。文档特别说明loadDevtools、client、position、errorTypes、buttonPosition、initialIsOpen、theme这些选项均支持通过信号响应式变化。底层加载与挂载机制回放把类型定义与实际运行时对照可以看到DevtoolsFeature背后是一套“懒加载 响应式配置同步”的实现平台与环境守卫ENVIRONMENT_INITIALIZER工厂先判断isPlatformBrowser(inject(PLATFORM_ID))与内部令牌DEVTOOLS_PROVIDED防止子注入器重复注册非浏览器或已提供则直接返回noopwith-devtools.ts#L76-L86动态导入真实加载通过import(tanstack/query-devtools)懒执行加载成功后new TanstackQueryDevtools({ ..., queryFlavor: Angular Query, version: 5, onlineManager })实例化通用 devtools 内核with-devtools.ts#L150-L162DOM 挂载与清理创建div.tsqd-parent-container追加到document.body调用devtools.mount(el)同时监听DestroyRefinjector 销毁时执行devtools.unmount()与节点移除with-devtools.ts#L114-L118。若异步加载期间 injector 已被销毁injectorIsDestroyed置位则会直接放弃本次创建动态配置同步devtools 已存在时选项变化不会重建实例而是调用setClient、setPosition、setTheme等方法增量更新加载失败时则输出提示安装tanstack/query-devtools或不要以--omitoptional安装依赖with-devtools.ts#L170-L175。如果希望对渲染位置有更精细的控制例如嵌入自己的界面可参考injectDevtoolsPanel源码位于 packages/angular-query-experimental/src/devtools-panel/inject-devtools-panel.ts它允许把面板渲染到自定义宿主而不是像withDevtools那样默认渲染到body。小结DevtoolsFeature 在类型体系中的位置把本文涉及的 API 串联起来可以勾勒出完整的类型关系图DevtoolsFeature QueryFeatureDevtools // 返回类型契约 WithDevtools (fn?, opts?) DevtoolsFeature // 生产/开发通用签名 QueryFeatures DevtoolsFeature | PersistQueryClientFeature // provideTanStackQuery 的 features 实参类型由 DevtoolsFeature 文档 出发可沿“See → withDevtools”线索进入 devtools 指南 获取完整的配置说明想了解特性被消费的入口见 provideTanStackQuery 参考文档想查看真实源码与测试用例可阅读 providers.ts、with-devtools.ts、types.ts 及对应测试 with-devtools.test.ts。理解DevtoolsFeature的关键在于把握“类型别名描述返回值”这一设计它对withDevtools的两种形态真实实现与生产桩给出同一份类型承诺从而在编译器层面保证了生产构建替换的安全性。配置时可依据实际场景灵活选择开发期直接withDevtools()交给auto需要生产/staging 调试则切换production子路径并把loadDevtools绑定到环境变量或响应式信号结合deps注入服务则能把加载策略完全收进业务控制之中。【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/query创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表