TanStack Solid Query Devtools 演进与实战:版本变更、核心原理与配置详解
【免费下载链接】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
@tanstack/solid-query-devtools是 TanStack Query 官方为 Solid Query 提供的开发者调试工具包,用于可视化与交互 Solid Query 的 Query 缓存内部状态。本篇文章以该包在仓库中的 CHANGELOG.md 为时间线骨架,结合 packages/solid-query-devtools/src 目录下的组件源码、单元测试与 Solid Query Devtools 官方文档,完整梳理其安装使用、两种运行模式、全部配置参数,并深入解析版本迭代中 theme、client、onClose、type 泄漏修复等关键变更背后的实现原理。读完本文,你将能熟练配置与调试 Solid Query Devtools,并理解其"框架适配层 + 共享核心"的分层架构。
一、包定位:一个薄薄的 Solid 适配层
从仓库结构看,packages/solid-query-devtools 是整个 TanStack Query monorepo 中面向 Solid 生态的调试工具适配包。它的核心职责并不是从零实现调试 UI,而是把共享的@tanstack/query-devtools(位于 packages/query-devtools,基于 Solid 实现的核心调试面板)和@tanstack/solid-query(Solid Query 主包)组合起来,为 Solid 应用提供开箱即用的组件。
这一点可以从它的 package.json 中看得很清楚:
- 唯一的运行时依赖是
@tanstack/query-devtools(workspace:*,即共享核心面板); - peerDependencies 要求
@tanstack/solid-query与solid-js@^1.6.0; - 包描述为"Developer tools to interact with and visualize the TanStack/solid-query Query cache"。
CHANGELOG 中绝大部分条目的正文都是Updated dependencies,且每次发布都严格同步@tanstack/query-devtools与@tanstack/solid-query的版本号。以最新一条为例:
## 5.102.8 ### Patch Changes - Updated dependencies []: - @tanstack/query-devtools@5.102.8 - @tanstack/solid-query@5.102.8这说明:本包的大多数"变更"其实来自上游两个包的升级,自身真正修改的是少量 Solid 适配逻辑。理解这一点是读懂该 CHANGELOG 的前提。
二、安装与引入:只在开发环境生效的组件
2.1 安装
官方文档 docs/framework/solid/devtools.md 给出了四种包管理器安装方式:
npm i @tanstack/solid-query-devtools # 或 pnpm add @tanstack/solid-query-devtools # 或 yarn add @tanstack/solid-query-devtools # 或 bun add @tanstack/solid-query-devtools2.2 引入与"零成本"的生产剔除
import { SolidQueryDevtools } from '@tanstack/solid-query-devtools'文档特别强调:默认情况下,Solid Query Devtools仅在开发构建中被包含,无需在生产构建中手动排除。这一行为由 index.tsx 中的源码保证:
import { isDev } from 'solid-js/web' import clientOnly from './clientOnly' export const SolidQueryDevtools: typeof SolidQueryDevtoolsComp = isDev ? clientOnly(() => import('./devtools')) : function () { return null } export const SolidQueryDevtoolsPanel: typeof SolidQueryDevtoolsCompPanel = isDev ? clientOnly(() => import('./devtoolsPanel')) : function () { return null }两个导出组件都遵循同一策略:
- 当
isDev === true时,通过clientOnly()包装,懒加载真正的组件实现(./devtools或./devtoolsPanel); - 当
isDev === false(生产环境)时,直接导出一个返回null的空组件,彻底避免任何调试代码进入生产包。
对应地,单元测试 devtools.test.tsx 和 devtoolsPanel.test.tsx 中都有"should return null in non-development environments"用例,通过 mocksolid-js/web的isDev为false来断言组件返回null。
2.3 clientOnly:SSR 安全的客户端专属加载
index.tsx 中使用的clientOnly包装器定义在 clientOnly.tsx(源码注释说明该实现取自 solid-start 的 codebase)。其核心逻辑是:
- 在服务端(
isServer === true)渲染时,返回props.fallback(未提供则渲染空); - 在客户端,先创建 signal 保存懒加载的组件,挂载(
onMount)后才真正渲染组件,从而绕过 SSR、只在客户端装载 Devtools。
三、Floating Mode(浮动模式):最常用的接入方式
浮动模式把 Devtools 挂载为页面角落的固定浮动元素,通过角落的 TanStack logo 切换面板开合,且切换状态会保存在localStorage中,刷新后仍然记忆。
官方文档建议把它放在组件树尽可能高的位置(越靠近根越好):
import { SolidQueryDevtools } from '@tanstack/solid-query-devtools' function App() { return ( <QueryClientProvider client={queryClient}> {/* The rest of your application */} <SolidQueryDevtools initialIsOpen={false} /> </QueryClientProvider> ) }3.1 SolidQueryDevtools 完整选项
CHANGELOG 中 5.91.0 的 Minor Changes 提到"allow passing a theme via prop",而 devtools.tsx 中DevtoolsOptions接口的 JSDoc 完整定义了全部选项:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
initialIsOpen | boolean | false | 是否默认展开面板 |
buttonPosition | 'top-left' \| 'top-right' \| 'bottom-left' \| 'bottom-right' \| 'relative' | 'bottom-right' | TanStack logo(开关按钮)的位置 |
position | 'top' \| 'bottom' \| 'left' \| 'right' | 'bottom' | 面板展开的位置 |
client | QueryClient | 就近 context | 自定义 QueryClient 实例(详见下文 5.91.0 / 5.90.4) |
errorTypes | Array<{ name: string; initializer: (query: Query) => TError }> | [] | 预定义可从 UI 触发的错误,initializer会在该错误被触发时以对应 query 为参数调用并返回一个Error |
styleNonce | string | — | 注入<style>标签的 nonce,用于配合 CSP(Content Security Policy)允许内联样式 |
shadowDOMTarget | ShadowRoot | — | 将样式注入 shadow DOM 而非 light DOM 的 head 标签 |
hideDisabledQueries | boolean | false | 隐藏禁用状态的查询 |
theme | 'light' \| 'dark' \| 'system' | 'system' | 面板主题 |
其中buttonPosition的可选值在 5.100.7 的变更"align logo, panel, and 'buttonPosition' union descriptions across docs and JSDoc"中被统一校准——即文档与 JSDoc 中的描述保持一致,最终以上表为准。
四、Embedded Mode(嵌入式模式):内嵌到你自己的调试 UI
嵌入式模式把 Devtools 面板作为应用内的固定元素展示,适合集成进你自己的开发者工具页面。官方文档示例:
import { createSignal, Show } from 'solid-js' import { SolidQueryDevtoolsPanel } from '@tanstack/solid-query-devtools' function App() { const [isOpen, setIsOpen] = createSignal(false) return ( <QueryClientProvider client={queryClient}> {/* The rest of your application */} <button onClick={() => setIsOpen(!isOpen())} >{`${isOpen() ? 'Close' : 'Open'} the devtools panel`}</button> <Show when={isOpen()}> <SolidQueryDevtoolsPanel onClose={() => setIsOpen(false)} /> </Show> </QueryClientProvider> ) }4.1 SolidQueryDevtoolsPanel 完整选项
devtoolsPanel.tsx 中DevtoolsPanelOptions定义如下:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
style | JSX.CSSProperties | { height: '500px' } | 面板容器自定义样式,如{ height: '100%', width: '100%' } |
onClose | () => void | no-op 空函数 | 面板被关闭时的回调 |
client | QueryClient | 就近 context | 自定义 QueryClient 实例 |
errorTypes | Array<{ name: string; initializer: (query: Query) => TError }> | [] | 预定义可触发错误 |
styleNonce | string | — | 注入<style>的 CSP nonce |
shadowDOMTarget | ShadowRoot | — | shadow DOM 样式注入目标 |
hideDisabledQueries | boolean | false | 隐藏禁用查询 |
theme | 'light' \| 'dark' \| 'system' | 'system' | 面板主题 |
值得注意的实现细节:面板组件内部为TanstackQueryDevtoolsPanel实例硬编码了buttonPosition: 'bottom-left'、position: 'bottom'、initialIsOpen: true(devtoolsPanel.tsx),因为嵌入式模式本就要求面板常驻展示,无需再暴露这些开关类选项。容器外层样式通过style={{ height: '500px', ...props.style }}合并,默认高度 500px,可被style覆盖——测试 devtoolsPanel.test.tsx 专门验证了"省略 height 时保留默认高度"与"显式 height 覆盖默认值"两种情形。
五、从 CHANGELOG 读懂演进脉络:关键变更逐一解析
CHANGELOG 中真正属于本包的变更(带标题的非依赖更新)只有少数几条,恰好勾勒出该适配层反复打磨的几个关键点:
5.15.90.4:修复 client prop 不生效
Fixed client prop not working on SolidQueryDevtools and SolidQueryDevtoolsPanel (#9763)
两个组件的clientprop 允许绕过 context 直接指定 QueryClient。当前实现(devtools.tsx)是:
const queryClient = useQueryClient(props.client) const client = createMemo(() => queryClient)即useQueryClient(props.client)优先使用显式传入的 client,否则回退到最近的QueryClientProvidercontext。如果既未传 prop 又不在 Provider 内,会抛出错误"No QueryClient set, use QueryClientProvider to set one"——这一行为被测试 devtools.test.tsx 覆盖。5.90.4 修复的正是早期版本中该 prop 未正确传递给底层实例的问题。
5.25.91.0(Minor):新增 theme prop
feat(devtools): allow passing a theme via prop (#9887)
这是该 CHANGELOG 中唯一的 Minor 级别新特性:允许通过themeprop 直接控制面板主题('light' | 'dark' | 'system',默认'system')。底层通过devtools.setTheme(props.theme || 'system')转发(devtools.tsx),测试则验证了theme="dark"的转发以及缺省时的'system'默认值(devtools.test.tsx)。
5.35.100.4:onClose 回调类型收紧
fix(devtools): change onClose callback type from () => unknown to () => void (#10118)
面板关闭回调的类型由() => unknown收紧为() => void,见 devtoolsPanel.tsx 的onClose?: () => void。类型收紧消除了"回调返回值被忽略却可以返回任意值"的隐患,也保证用户传入onClose后关闭面板行为可预期。测试 devtoolsPanel.test.tsx 断言onClose被转发到底层setOnClose,未传时默认转发一个"调用无副作用(返回undefined)"的空函数。
5.45.100.10:移除 experimentalDts,杜绝 solid-js 类型泄漏
fix(query-devtools): remove experimentalDts to prevent solid-js type leak (#10694)
这是对构建产物类型声明的修复:此前类型声明配置里使用了experimentalDts相关设置,导致构建出的.d.ts中泄漏出对solid-js内部类型的依赖;移除后避免使用者因 peer 依赖不匹配而出现类型解析错误。这与 tsconfig.prod.json / tsdown.config.ts 所控制的产物生成方式相关,属于典型的"构建产物质量"维护。
5.5 工程维护类变更:版本与构建目录
5.94.4:chore: fixed version—— 固定上游依赖版本,确保发布包版本严格对齐;5.94.5:fix(*): resolve issue about excluded build directory—— 修复构建目录被排除的问题,保证build产物正常发布(对应 package.json 的"files": ["build", "src", "!src/__tests__"]);5.100.7:统一 logo、panel 与buttonPosition联合类型在文档与 JSDoc 中的描述。
5.6 版本同步策略:紧跟上游
从 5.90.x 到 5.102.x 的每一次发布,CHANGELOG 都显示@tanstack/query-devtools与@tanstack/solid-query保持同版本号同步升级。这意味着:升级@tanstack/solid-query-devtools时,建议同步升级@tanstack/solid-query与共享面板版本,避免运行时 API 不匹配。包自身几乎总是Patch级变更,新功能(如 theme)主要来自上游@tanstack/query-devtools的 Minor 更新。
六、源码级原理:props 如何驱动底层 Devtools 实例
6.1 双组件共享的模式
两个组件(SolidQueryDevtools与SolidQueryDevtoolsPanel)的实现高度相似,本质是同一个模式:
- 解析 QueryClient(prop 优先,context 兜底);
new TanstackQueryDevtools({...})或new TanstackQueryDevtoolsPanel({...})创建共享核心实例(来自@tanstack/query-devtools),并注入queryFlavor: 'Solid Query'、version: '5'、onlineManager;- 用多个
createEffect把响应式 props 的变化同步到实例的setXxx方法; onMount时devtools.mount(ref)挂载到占位<div class="tsqd-parent-container">,onCleanup时devtools.unmount()卸载。
以 devtools.tsx 为例,props 与实例方法的映射为:
| props | 实例方法 | 缺省值 |
|---|---|---|
client | setClient | context 解析结果 |
buttonPosition | setButtonPosition | 不传则不设置 |
position | setPosition | 不传则不设置 |
initialIsOpen | setInitialIsOpen | false |
errorTypes | setErrorTypes | [] |
theme | setTheme | 'system' |
onClose(仅 Panel) | setOnClose | () => {} |
测试 devtools.test.tsx 对表中每个映射都有对应用例,且通过createSignal动态改值验证"挂载后 props 变化仍能转发"(如 devtools.test.tsx 中把buttonPosition从bottom-right切换到top-left)。
6.2 底层实例:TanstackQueryDevtools
共享核心 TanstackQueryDevtools.tsx 是一个命令式类,内部用 Solid 的createSignal保存各项配置(#buttonPosition、#position、#initialIsOpen、#errorTypes、#hideDisabledQueries、#theme、#client),并暴露setXxx方法与mount/unmount。mount时通过render()把配置信号注入到懒加载的DevtoolsComponent(packages/query-devtools/src/DevtoolsComponent.tsx),并调用setupStyleSheet处理styleNonce与shadowDOMTarget的样式注入。因此,Solid 适配层每次setXxx实质上都是在驱动这些内部信号,进而触发面板 UI 的响应式更新。
这种"框架适配层 + 共享核心"的分层,正是 TanStack Query 多个框架(React、Solid、Svelte、Vue 等)能共享同一套 Devtools 交互体验的关键架构选择。
七、测试体系:行为契约的守护者
本包的测试集中在 packages/solid-query-devtools/src/tests,与 CHANGELOG 中的修复一一对应,可作为行为契约参考:
- client 解析:无 client 时抛错;context 提供或 prop 提供均不抛错;
- props 转发:
buttonPosition、position、initialIsOpen、errorTypes、theme、client、onClose均能正确转发到底层实例方法; - 默认值:
initialIsOpen缺省为false、errorTypes缺省为[]、theme缺省为'system'、onClose缺省为 no-op; - 动态响应:挂载后修改 signal 值,转发仍生效;
- 生命周期:组件卸载时调用底层
unmount; - 样式合并(Panel):默认高度 500px、可被
style覆盖; - 生产环境:
isDev === false时组件渲染null。
八、结语
通过@tanstack/solid-query-devtools的 CHANGELOG 我们可以清晰地看到:一个成熟的调试工具包,其价值既来自上游共享核心的持续迭代(theme 支持、文档对齐、类型修复),也来自适配层对细节的反复打磨(client prop、onClose 类型、构建产物与类型泄漏)。对于使用者而言,记住三点即可从容应对:
- 只写两行代码接入:
<SolidQueryDevtools />(浮动)或<SolidQueryDevtoolsPanel />(嵌入式),生产构建自动剔除; - 九个可用选项:
initialIsOpen、buttonPosition、position、client、errorTypes、styleNonce、shadowDOMTarget、hideDisabledQueries、theme(Panel 另加style与onClose); - 版本跟随上游:升级时让
@tanstack/solid-query-devtools、@tanstack/solid-query与@tanstack/query-devtools保持同版本同步。
【免费下载链接】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),仅供参考