ByteNoteByteNote

字节笔记本

2026年5月3日

TanStack Start - Environment Functions 环境函数

API中转
¥120

环境函数是用于定义和控制函数基于运行时环境执行的实用工具,无论代码是在客户端还是服务端运行。

什么是环境函数

TanStack Start 提供三个核心环境函数:

函数用途
createIsomorphicFn组合适应客户端和服务端环境的单个函数
createServerOnlyFn创建仅在服务端运行的函数
createClientOnlyFn创建仅在客户端运行的函数

同构函数

使用 createIsomorphicFn() 定义根据调用在客户端还是服务端而表现不同的函数。

完整实现

tsx
import { createIsomorphicFn } from '@tanstack/react-start'

const getEnv = createIsomorphicFn()
  .server(() => 'server')
  .client(() => 'client')

const env = getEnv()
// 在服务端,返回 'server'
// 在客户端,返回 'client'

部分实现(仅服务端)

tsx
const serverImplementationOnly = createIsomorphicFn().server(() => 'server')

const server = serverImplementationOnly()
// 在服务端,返回 'server'
// 在客户端,是 no-op(返回 undefined)

环境专属函数

createServerOnlyFncreateClientOnlyFn 助手强制严格的环境边界执行。

createServerOnlyFn

tsx
import { createServerOnlyFn } from '@tanstack/react-start'

const foo = createServerOnlyFn(() => 'bar')

foo() // ✅ 在服务端: 返回 "bar"
// ❌ 在客户端: 抛出错误

createClientOnlyFn

tsx
import { createClientOnlyFn } from '@tanstack/react-start'

const foo = createClientOnlyFn(() => 'bar')

foo() // ✅ 在客户端: 返回 "bar"
// ❌ 在服务端: 抛出错误

Tree Shaking

环境函数基于每个生成的 bundle 的环境进行 tree-shaking:

  • .client() 内的所有代码不包含在服务端 bundle 中
  • .server() 内的所有代码不包含在客户端 bundle 中

实际应用示例

跨环境存储

tsx
const getStorage = createIsomorphicFn()
  .server((key: string) => {
    const fs = require('node:fs')
    const cache = JSON.parse(fs.readFileSync('.cache', 'utf-8'))
    return cache[key]
  })
  .client((key: string) => {
    return JSON.parse(localStorage.getItem(key) || 'null')
  })

const value = getStorage('user-preferences')

设备信息检测

tsx
const getDeviceInfo = createIsomorphicFn()
  .server(() => ({
    type: 'server',
    platform: process.platform,
    arch: process.arch,
    nodeVersion: process.version,
  }))
  .client(() => ({
    type: 'client',
    userAgent: navigator.userAgent,
    language: navigator.language,
    screenWidth: window.screen.width,
  }))

仅服务端操作

tsx
const getDatabaseUrl = createServerOnlyFn(() => {
  return process.env.DATABASE_URL
})

// ✅ 在服务端安全使用
const dbUrl = getDatabaseUrl()
// ❌ 在客户端会抛出错误,防止意外暴露

仅客户端操作

tsx
const saveToLocalStorage = createClientOnlyFn((key: string, value: any) => {
  localStorage.setItem(key, JSON.stringify(value))
})

// ✅ 在客户端安全使用
saveToLocalStorage('user', { name: 'John' })
// ❌ 在服务端会抛出错误

功能对比

特性createIsomorphicFncreateServerOnlyFncreateClientOnlyFn
服务端实现✅ 支持✅ 必需❌ 无
客户端实现✅ 支持❌ 无✅ 必需
跨环境工作
错误时No-op抛出错误抛出错误
Tree-shaking

选择决策树

text
需要跨环境使用?
├─ 是 → createIsomorphicFn
│   ├─ 需要两种实现?
│   │   ├─ 是 → .server() + .client()
│   │   └─ 否 → 仅需要的环境方法
│   └─ 返回 undefined 在另一环境
└─ 否 → 需要哪个环境?
    ├─ 服务端 → createServerOnlyFn
    └─ 客户端 → createClientOnlyFn
分享: