文档
CodeRabbit
Cloudflare
AG Grid
Netlify
Neon
WorkOS
Clerk
Convex
Electric
PowerSync
Sentry
Railway
Prisma
Strapi
Unkey
CodeRabbit
Cloudflare
AG Grid
Netlify
Neon
WorkOS
Clerk
Convex
Electric
PowerSync
Sentry
Railway
Prisma
Strapi
Unkey
类引用
函数引用
接口引用
类型别名引用
变量引用
指南

Tree-Shaking

树摇与包优化

TanStack AI 从一开始就设计为最大程度地支持树摇。整个系统——从活动函数到适配器——都使用了一种功能化、模块化的架构,确保您只打包实际使用的代码。

设计理念

TanStack AI 不提供包含所有内容的一体化 API,而是提供

  • 独立的活动函数 - 只导入您需要的活动 (chat, summarize 等)
  • 独立的适配器函数 - 只导入您需要的适配器 (openaiText, openaiSummarize 等)
  • 函数式 API 设计 - 纯函数,可以被打包器轻松消除
  • 独立的模块 - 每个活动和适配器都位于自己的模块中

这意味着,如果您只使用 chat 与 OpenAI,您不会打包用于摘要、图像生成或其他提供商的代码。

活动函数

每个 AI 活动都作为从 @tanstack/ai 导出的独立函数

ts
// Import only the activities you need
import { chat } from '@tanstack/ai'              // Chat/text generation
import { summarize } from '@tanstack/ai'          // Summarization
import { generateImage } from '@tanstack/ai'      // Image generation
import { generateSpeech } from '@tanstack/ai'     // Text-to-speech
import { generateTranscription } from '@tanstack/ai' // Audio transcription
import { generateVideo } from '@tanstack/ai'       // Video generation

示例:仅聊天

如果您只需要聊天功能

ts
// Only chat code is bundled
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

const stream = chat({
  adapter: openaiText('gpt-5.2'),
  messages: [{ role: 'user', content: 'Hello!' }],
})

您的包将包含

  • 摘要逻辑
  • 图像生成逻辑
  • 其他活动实现

适配器函数

每个提供商包为每种活动类型导出独立的适配器函数

OpenAI

ts
import {
  openaiText,       // Chat/text generation
  openaiSummarize,  // Summarization
  openaiImage,      // Image generation
  openaiSpeech,     // Text-to-speech
  openaiTranscription, // Audio transcription
  openaiVideo,      // Video generation
} from '@tanstack/ai-openai'

Anthropic

ts
import {
  anthropicText,       // Chat/text generation
  anthropicSummarize,  // Summarization
} from '@tanstack/ai-anthropic'

Gemini

ts
import {
  geminiText,       // Chat/text generation
  geminiSummarize,  // Summarization
  geminiImage,      // Image generation
  geminiSpeech,     // Text-to-speech (experimental)
} from '@tanstack/ai-gemini'

Ollama

ts
import {
  ollamaText,       // Chat/text generation
  ollamaSummarize,  // Summarization
} from '@tanstack/ai-ollama'

完整示例

以下是树摇设计在实践中的工作方式

ts
// Only import what you need
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

// Chat generation - returns AsyncIterable<StreamChunk>
const chatResult = chat({
  adapter: openaiText('gpt-5.2'),
  messages: [{ role: 'user', content: 'Hello!' }],
})

for await (const chunk of chatResult) {
  console.log(chunk)
}

将打包的内容

  • chat 函数及其依赖项
  • openaiText 适配器及其依赖项
  • ✅ 聊天特定的流式传输和工具处理逻辑

不会打包的内容

  • summarize 函数
  • generateImage 函数
  • ❌ 其他适配器实现 (Anthropic, Gemini 等)
  • ❌ 其他活动实现

使用多个活动

如果您需要多个活动,只需导入您需要的

ts
import { chat, summarize } from '@tanstack/ai'
import {
  openaiText,
  openaiSummarize
} from '@tanstack/ai-openai'

// Each activity is independent
const chatResult = chat({
  adapter: openaiText('gpt-5.2'),
  messages: [{ role: 'user', content: 'Hello!' }],
})

const summarizeResult = await summarize({
  adapter: openaiSummarize('gpt-5-mini'),
  text: 'Long text to summarize...',
})

每个活动都位于自己的模块中,因此打包器可以消除未使用的活动。

类型安全

树摇设计不会牺牲类型安全。每个适配器为其支持的模型提供完整的类型安全

ts
import { openaiText, type OpenAIChatModel } from '@tanstack/ai-openai'

const adapter = openaiText()

// TypeScript knows the exact models supported
const model: OpenAIChatModel = 'gpt-5.2' // ✓ Valid
const model2: OpenAIChatModel = 'invalid' // ✗ Type error

创建选项函数

create___Options 函数也支持树摇

ts
import {
  createChatOptions,
  createImageOptions
} from '@tanstack/ai'

// Only import what you need
const chatOptions = createChatOptions({
  adapter: openaiText('gpt-5.2'),
})

包大小优势

功能化、模块化的设计提供了显著的包大小优势

导入所有内容(效率较低)

ts
// ❌ Importing more than needed
import * as ai from '@tanstack/ai'
import * as openai from '@tanstack/ai-openai'

// This bundles all exports from both packages
ts
// ✅ Only what you use gets bundled
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

// You only get:
// - Chat activity implementation
// - OpenAI text adapter
// - Chat-specific dependencies

实际影响

对于典型的聊天应用程序

  • 单体方法:~200KB+ (所有活动 + 所有适配器)
  • 树摇方法:~50KB (仅聊天 + 一个适配器)

这对于大多数应用程序来说是 75% 的减小

工作原理

树摇是通过以下方式实现的

  1. ES 模块导出 - 每个函数都是命名导出,而不是默认导出
  2. 独立的模块 - 每个活动和适配器都位于自己的文件中
  3. 没有副作用 - 函数是纯函数,没有模块级别的副作用
  4. 函数式组合 - 函数组合在一起,允许消除死代码
  5. 仅类型导入 - 类型导入会在构建时被剥离

现代打包器 (Vite, Webpack, Rollup, esbuild) 可以轻松消除未使用的代码,因为

  • 函数是静态可分析的
  • 没有未使用的代码的动态导入
  • 没有模块级别的副作用
  • 清晰的依赖关系图

最佳实践

  1. 仅导入您需要的内容 - 不要导入整个命名空间
  2. 使用特定的适配器函数 - 导入 openaiText 而不是 openai
  3. 按路由分隔活动 - 不同的 API 路由可以使用不同的活动
  4. 尽可能延迟加载 - 为代码拆分路由使用动态导入
ts
// ✅ Good - Only imports chat
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

// ❌ Bad - Imports everything
import * as ai from '@tanstack/ai'
import * as openai from '@tanstack/ai-openai'

适配器类型

每个适配器类型都实现特定的接口

  • ChatAdapter - 提供 chatStream() 方法,用于流式传输聊天响应
  • SummarizeAdapter - 提供 summarize() 方法,用于文本摘要
  • ImageAdapter - 提供 generateImage() 方法,用于图像生成
  • TTSAdapter - 提供 generateSpeech() 方法,用于文本到语音
  • TranscriptionAdapter - 提供 generateTranscription() 方法,用于音频转录
  • VideoAdapter - 提供 generateVideo() 方法,用于视频生成

所有适配器都有一个 kind 属性,指示它们的类型

ts
const chatAdapter = openaiText()
console.log(chatAdapter.kind) // 'text'

const summarizeAdapter = openaiSummarize()
console.log(summarizeAdapter.kind) // 'summarize'

总结

TanStack AI 的树摇设计意味着

  • 更小的包 - 只包含您实际使用的代码
  • 更快的加载时间 - 更少的 JavaScript 需要下载和解析
  • 更好的性能 - 更少的代码意味着更快的执行
  • 类型安全 - 完整的 TypeScript 支持,没有运行时开销
  • 灵活性 - 随需组合活动和适配器

功能化、模块化的架构确保了现代打包器可以有效地消除未使用的代码,从而为您的应用程序实现最佳的包大小。