SuperAPI AI 工具集

tanstack-devtools-utils-devtools-framework-adapters

编程与开发

查看项目

更新于 10-16 09:23

技能介绍

用途

本技能介绍如何使用 @tanstack/devtools-utils 的工厂函数,为不同前端框架创建 devtools 插件适配器。每个框架都有对应的子路径导出(/react、/vue、/solid、/preact),每个子路径提供两类工厂函数,用于把自定义组件或基于类的 devtools 核心接入 TanStack Devtools。

主要能力

插件工厂

每个 createXPlugin 返回 readonly [Plugin, NoOpPlugin] 元组:

  • Plugin:返回带元数据的插件对象,其 render 函数渲染你的组件。
  • NoOpPlugin:返回相同元数据但渲染空片段的插件对象。

面板工厂

每个 createXPanel 返回 readonly [Panel, NoOpPanel] 元组:

  • Panel:框架组件,创建 <div style="height:100%">,实例化核心类,在挂载时调用 core.mount(el, theme),在清理时调用 core.unmount()。
  • NoOpPanel:渲染空片段。

DevtoolsPanelProps

React、Solid、Preact:

interface DevtoolsPanelProps {
  theme?: 'light' | 'dark'
}

Vue(注意包含 'system'):

interface DevtoolsPanelProps {
  theme?: 'dark' | 'light' | 'system'
}

从框架子路径导入类型:

import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/react'
import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/vue'
import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/solid'
import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/preact'

使用方式

React 示例

import { createReactPlugin } from '@tanstack/devtools-utils/react'

function MyStorePanel({ theme }: { theme?: 'light' | 'dark' }) {
  return <div className={theme}>My Store Devtools</div>
}

const [MyPlugin, NoOpPlugin] = createReactPlugin({
  name: 'My Store',
  id: 'my-store',
  defaultOpen: false,
  Component: MyStorePanel,
})

// Tree-shaking: use NoOp in production
const ActivePlugin =
  process.env.NODE_ENV === 'development' ? MyPlugin : NoOpPlugin

配合基于类的面板

import {
  createReactPanel,
  createReactPlugin,
} from '@tanstack/devtools-utils/react'

class MyDevtoolsCore {
  mount(el: HTMLElement, theme: 'light' | 'dark') {
    /* render into el */
  }
  unmount() {
    /* cleanup */
  }
}

const [MyPanel, NoOpPanel] = createReactPanel(MyDevtoolsCore)

const [MyPlugin, NoOpPlugin] = createReactPlugin({
  name: 'My Store',
  Component: MyPanel,
})

各框架 API 差异

React 与 Preact 使用选项对象:

createReactPlugin({ name, id?, defaultOpen?, Component })  // => [Plugin, NoOpPlugin]
createPreactPlugin({ name, id?, defaultOpen?, Component }) // => [Plugin, NoOpPlugin]

Component 接收 DevtoolsPanelProps(含 theme)。Plugin() 返回 { name, id?, defaultOpen?, render(el, theme) }。Preact 与 React 相同,但使用 Preact JSX 类型和 preact/hooks。

Vue 使用位置参数,而非选项对象:

createVuePlugin(name: string, component: DefineComponent) // => [Plugin, NoOpPlugin]

以 (name, component) 作为独立参数传入。Plugin(props) 返回 { name, component, props },透传 props。NoOpPlugin(props) 返回 { name, component: Fragment, props }。Vue 的 DevtoolsPanelProps.theme 还接受 'system'。

Solid 与 React 的 API 相同,但内部实现不同:

createSolidPlugin({ name, id?, defaultOpen?, Component }) // => [Plugin, NoOpPlugin]

Component 必须是 Solid 组件函数 (props: DevtoolsPanelProps) => JSX.Element。render 函数内部返回 <Component theme={theme} />,由 Solid 处理响应式。Solid 还从 @tanstack/devtools-utils/solid/class 导出 constructCoreClass,用于构建懒加载的 devtools 核心。

常见错误

在 Vue 适配器中使用 React JSX 模式(严重)

Vue 使用位置参数 (name, component),不是选项对象。

// WRONG -- will fail at compile time or produce garbage at runtime
const [MyPlugin, NoOpPlugin] = createVuePlugin({
  name: 'My Plugin',
  Component: MyPanel,
})

// CORRECT
const [MyPlugin, NoOpPlugin] = createVuePlugin('My Plugin', MyPanel)

Vue 插件在调用时也不同,需要传入 props:

// WRONG -- calling Plugin() with no args (React pattern)
const plugin = MyPlugin()

// CORRECT -- Vue Plugin takes props
const plugin = MyPlugin({ theme: 'dark' })

Solid 渲染 prop 未包装为函数(严重)

使用 Solid 组件时,Component 必须是函数引用,而非原始 JSX。

// WRONG -- evaluates immediately, breaks Solid reactivity
createSolidPlugin({
  name: 'My Store',
  Component: <MyPanel />, // This is JSX.Element, not a component function
})

// CORRECT -- pass the component function itself
createSolidPlugin({
  name: 'My Store',
  Component: (props) => <MyPanel theme={props.theme} />,
})

// ALSO CORRECT -- pass the component reference directly
createSolidPlugin({
  name: 'My Store',
  Component: MyPanel,
})

忽略生产环境的 NoOp 变体(高)

工厂返回 [Plugin, NoOpPlugin],两者都必须解构使用才能正确 tree-shaking。

// WRONG -- NoOp variant discarded, devtools code ships to production
const [MyPlugin] = createReactPlugin({ name: 'Store', Component: MyPanel })

// CORRECT -- conditionally use NoOp in production
const [MyPlugin, NoOpPlugin] = createReactPlugin({
  name: 'Store',
  Component: MyPanel,
})
const ActivePlugin =
  process.env.NODE_ENV === 'development' ? MyPlugin : NoOpPlugin

未向面板组件传递 theme prop(中)

DevtoolsPanelProps 包含 theme。devtools 外壳会传入它,以便面板匹配明暗模式。若组件忽略它,面板将无法适应主题变化。

// WRONG -- theme is ignored
const Component = () => <div>My Panel</div>

// CORRECT -- use theme for styling
const Component = ({ theme }: DevtoolsPanelProps) => (
  <div className={theme === 'dark' ? 'dark-mode' : 'light-mode'}>My Panel</div>
)

设计张力

核心架构与框架无关,但每个框架有不同习惯:

  • React/Preact 使用选项对象,Component 为 JSX 函数组件。
  • Vue 使用位置参数,传入 DefineComponent 并透传 props。
  • Solid 使用与 React 相同的选项 API,但采用 Solid 的 JSX 与响应式模型。

基于 React 模式训练的智能体容易把 Vue 写错。始终检查导入路径以确定使用哪个工厂 API。

适用场景

适用于需要为 TanStack Devtools 编写自定义插件或面板,并希望同时支持多个前端框架的开发者。通过工厂函数可以复用同一套 devtools 核心逻辑,并为每个框架生成对应的适配器,同时利用 NoOp 变体在生产构建中剔除 devtools 代码。

限制

资料未提供具体的安装命令、版本要求、收费或价格信息。各框架的完整 API 细节可参考 references/react.md、references/vue.md、references/solid.md、references/preact.md。