名称: tanstack-start 描述: TanStack Start (RC) 全栈 React 带有服务器函数、SSR、Cloudflare Workers。用于 Next.js 迁移、边缘渲染或遇到水合、认证、数据模式错误。 许可证: MIT 允许工具: [Bash, Read, Write, Edit] 元数据: 版本: 1.0.0-rc.1 作者: Claude Skills Maintainers 最后验证: 2025-12-09 生产测试: false 状态: rc 关键词: - tanstack start - tanstack react start - 全栈 react - 选择性 ssr - spa 模式 - 静态预渲染 - 服务器函数 - 服务器路由
- cloudflare workers
- 边缘渲染
- 水合错误
- next.js 迁移
TanStack Start (React) — RC-Ready Playbook
TanStack Router 上的全栈 React,具有每路由 SSR/CSR、文件式路由、服务器函数和一流的 Cloudflare Workers 支持。
使用此技能时
- 构建需要路由级 SSR/CSR/SSG 开关的绿地 React 应用。
- 从 Next.js/React Router 迁移,同时保持文件式路由 + API 路由。
- 部署到边缘运行时(Workers),带有类型化服务器函数和绑定。
- 您想要可预测的路由,具有类型安全参数/搜索 + 内置预加载。
内容包含
- 参考资料: 快速入门/布局、渲染模式、服务器函数、Cloudflare 托管、执行/认证,以及新的路由/数据/导航/开发工具指南。
- 脚本:
scripts/bootstrap-cloudflare-start.sh <app>脚手架 Start + Workers + 绑定类型。 - 故障排除: 水合、API 路由、绑定、导航/预加载失败。
快速入门 (React)
npm create @tanstack/start@latest my-app
cd my-app
npm run dev
手动安装(支持所有捆绑目标):按照官方安装指南,添加 @tanstack/react-router + @tanstack/react-start 与您的捆绑器插件(vite、webpack 或 esbuild)。
核心布局提醒
app/routes/**文件式路由 → 路由器树,自动代码分割 + 数据预加载。app/entry.client.tsx水合<StartClient />;app/entry.server.tsx包装createServerEntry。app/config.ts或app/start.ts设置defaultSsr、spaMode、中间件和上下文。
路由 + 数据最佳实践
- 类型安全参数 & 搜索:
createFileRoute()推断路径参数;添加validateSearch(zod) 来解析和强制搜索参数。 - 路由匹配顺序是确定性的(索引 → 静态 → 动态 → 通配符);在添加捕获所有时依赖此。
- 加载器每次位置更改运行一次;返回纯数据,抛出
redirect()/notFound()用于控制流。 - 数据突变: 共置
action/服务器函数;保持加载器只读,并在突变后通过router.invalidate()失效。 - TanStack Query 桥接: 在路由器上下文中创建
QueryClient,并在加载器内部使用ensureQueryData来去重获取。 - 延迟/外部数据: 流式传输部分数据或从外部加载器读取;优先使用 Suspense 友好的响应。
- 头部管理: 每路由设置
head用于<title>/元数据;从加载器数据派生以保持 SEO 一致。 - 未找到/认证: 在加载器/中间件中抛出
notFound()或redirect();使用错误边界用于 UX。
示例路由(类型化搜索 + 仅数据 SSR):
// app/routes/posts.$postId.tsx
import { createFileRoute, redirect } from '@tanstack/react-router'
import { z } from 'zod'
export const Route = createFileRoute('/posts/$postId')({
validateSearch: z.object({ preview: z.boolean().optional() }),
ssr: 'data-only',
loader: async ({ params, search, context }) => {
const post = await context.queryClient.ensureQueryData(['post', params.postId], () =>
fetch(`/api/posts/${params.postId}?preview=${!!search.preview}`).then(r => r.json())
)
if (!post.published && !search.preview) throw redirect({ to: '/drafts' })
return { post }
},
})
导航、预加载和用户体验
- 链接预取默认:
<Link preload="intent">(悬停/聚焦)预加载路由数据/代码;对于首屏路由使用preload="render"。 - 编程预加载:
router.preloadRoute({ to, search })在导航前预热缓存(例如,在可见性时)。 - 路由掩码: 保持规范 URL,同时显示用户友好的掩码(例如,
/products?slug=abc掩码为/p/abc)。 - 导航阻止: 使用
router.navigate({ to, replace, from })阻止器或useBlocker保护未保存的表单。 - 滚动恢复: 启用
scrollRestoration以在后退/前进时恢复位置;在使用长列表时每路由自定义。 - 搜索参数序列化: 自定义解析/字符串化以保持数字/日期稳定,避免字符串化布尔值。
渲染与性能
- 每路由 SSR: 在路由上设置
ssr: true | false | 'data-only';defaultSsr配置设置基线。 - 代码分割: 文件式路由自动分割;在代码式路由上添加
lazy/load用于手动块。 - 预加载策略: 配对
preload="intent"链接与defaultPreloadStaleTime以避免过度获取。 - 渲染优化: 保持加载器纯净,记忆化重型组件,并对 CSR 路由使用
pendingComponent以避免布局偏移。
开发工具、代码检查和 LLM 支持
- 在开发期间添加
<RouterDevtools />以检查匹配、加载器状态和预加载。 - 启用 ESLint 插件
@tanstack/eslint-plugin-router与推荐配置,以强制执行推理敏感属性顺序(例如,beforeLoad在loader之前)。 - LLM 感知路由: 路由器向 LLM 代理公开结构化路由元数据;在
Route元数据中保持描述简洁以改善 AI 导航。
部署说明(Cloudflare 友好)
- 将
cloudflare({ viteEnvironment: { name: 'ssr' } })放在 Vite 插件首位,以便绑定到达服务器入口。 - 更改后重新生成绑定:
npm run cf-typegen。 - 对于静态重的站点,启用预渲染以将 HTML 发送到 Workers 资产/页面;排除参数路由或添加显式
pages。
发布清单
- [ ] 路由加载无水合警告(对于非确定性 UI,优先使用
ssr: 'data-only')。 - [ ] 搜索参数已验证
validateSearch和自定义序列化器(如需要)。 - [ ] 链接预加载配置用于高流量路由;阻止器添加用于未保存表单。
- [ ] ESLint 插件启用(
create-route-property-order规则)且npm run check通过。 - [ ] 开发工具本地验证;
router.matches状态看起来正确。 - [ ] Cloudflare 绑定类型化(
cf-typegen)并通过curl -N测试流式传输。