为什么用 TanStack 能更快发布
TanStack Start 如何缩短全栈 React 应用从想法到生产环境的时间。
每个 SaaS 项目一开始都很相似:先花两周把和产品本身无关的东西接起来。认证、数据库、支付、文件存储、邮件、部署,这些都不是你的核心差异,但你必须先让它们正常工作,才能测试真正关心的东西。
TanStarter 的核心想法是:这些重复又基础的部分,应该被一次性解决,并且解决得足够好。下面是它在实践中的样子。
TanStack Start:不会挡路的全栈 framework
TanStack Start 基于 TanStack Router、TanStack Query 和 TanStack Server Functions 构建。不同于 Next.js 引入自己的 router 和数据获取模式,TanStack Start 拥抱你已经熟悉、经过验证的 TanStack 生态。你不需要学习一套专有数据层。
如果你曾经被 Next.js App Router 的 breaking changes 影响过,TanStack Start 会像一次重置:一个建立在你能掌控的工具之上的 framework。
TanStack Router:零配置文件路由
路由由 TanStack Router 驱动。Routes 以文件形式存在,route params 会自动获得类型,嵌套 layouts 通过带括号的分组目录处理。添加新页面时,你不需要更新 router config,route tree 会自动重新生成。
src/routes/
├── (auth)/login.tsx
├── (auth)/signup.tsx
├── (dashboard)/settings.tsx
└── _index.tsx # /
所有内容都会端到端类型检查。如果你重命名 route param,所有使用它的组件都会在编译时报错,而不是等到运行时才发现。
TanStack Server Functions:没有样板代码的类型安全 API
TanStack Start 通过 createServerFn() 暴露 server logic。server function 放在 src/api/ 中,并且可以在浏览器端以完整类型安全的方式调用。输入校验使用 Zod。
const uploadFile = createServerFn({ method: 'POST' })
.inputValidator(z.object({
fileName: z.string().max(255),
data: z.instanceof(Uint8Array),
}))
.handler(async ({ input }) => {
// input 在这里拥有完整类型
});
Server functions 支持 middleware chains,可用于 auth checks、rate limiting,或任何 cross-cutting concern。
TanStack Query:自然工作的 Server State
所有 server data,包括用户信息、文件列表、订阅状态,都会通过 TanStack Query 流动。Query keys 集中在 factory 中,cache invalidation 明确,mutations 会返回更新后的状态。
const { data: user } = useQuery({
queryKey: queryKeys.users.detail(userId),
queryFn: api.users.getUser,
});
使用 query key factory pattern 后,只要 invalidate queryClient.utils.users.all(),所有展示用户数据的组件都会自动刷新。
一个类型系统,贯穿端到端
TypeScript types 会从 schema definitions 流向 server functions,再到 client components。你不需要在不同类型系统之间转换,也不需要维护重复 interfaces。
TanStarter 展示了一个由厌倦重复解决同类问题的人设计出来的全栈 React framework 应该是什么样子。克隆它,配置环境变量,然后第一天就开始写产品代码。