路由段与 Feature 模块对齐 — 每个业务域一棵小树
你要产出的,是「以业务域为中心」的一整套 Feature 模块,而不是「以技术细节」碎片堆叠。第一步,就是让路由结构和 Feature 结构对齐:一个业务域 = 一棵小路由树 + 一整个 Feature 目录。
1. 拆出一个业务域 Feature 目录
以 posts 为例,在 src/features/posts 下建出一个最小结构:
src/
features/
posts/
routes/
postsRoute.tsx
postDetailRoute.tsx
api/
postsApi.ts
queries/
postsKeys.ts
usePostsQuery.ts
usePostQuery.ts
components/
PostsList.tsx
PostDetail.tsx
ui/
PostsFallback.tsx
README.md
含义:
routes/:只关心 URL 结构、路由树、入口组件api/:只关心 和服务端打交道的函数(server functions / HTTP 封装)queries/:只关心 React Query/TanStack Query 的 key 和 hookscomponents/:和该业务域强绑定的 UI 组件ui/:错误、加载、空状态等跨页面可共享 UIREADME.md:简单写清这棵树怎么长、约定是啥
2. 让路由树长在 Feature 里面
在 TanStack Start(或 TanStack Router)里,你通常会有一个「路由注册点」,比如 src/routes/__root.tsx。
我们希望:posts 的子路由由 features/posts/routes 负责声明,而不是在 root 里手写一堆 /posts/*。
features/posts/routes/postsRoute.tsx 示例(伪代码,按你项目的实际 API 调整):
// src/features/posts/routes/postsRoute.tsx
import { createFileRoute } from "@tanstack/react-router"
import { PostsList } from "../components/PostsList"
import { PostsFallback } from "../ui/PostsFallback"
export const postsRoute = createFileRoute("/posts")({
component: PostsList,
pendingComponent: () => <PostsFallback variant="loading" />,
errorComponent: () => <PostsFallback variant="error" />,
})
postDetailRoute:
// src/features/posts/routes/postDetailRoute.tsx
import { createFileRoute } from "@tanstack/react-router"
import { PostDetail } from "../components/PostDetail"
import { PostsFallback } from "../ui/PostsFallback"
export const postDetailRoute = createFileRoute("/posts/$postId")({
component: PostDetail,
pendingComponent: () => <PostsFallback variant="loading" />,
errorComponent: () => <PostsFallback variant="error" />,
})
然后在集中注册的地方(例如 src/routes/index.ts 或 root route 配置),只做「拼树」:
import { postsRoute } from "../features/posts/routes/postsRoute"
import { postDetailRoute } from "../features/posts/routes/postDetailRoute"
export const routeTree = rootRoute.addChildren([
postsRoute,
postDetailRoute,
])
关键点:
- 路由的「分叉设计」发生在 Feature 内部
- 根部只做「挂树」,不关心业务细节
- 以后加
posts下面的任何新路由,只动features/posts/routes/*
3. 用一张小图看「每个业务域一棵小树」
Rendering diagram…
posts、users、settings每一个都对齐到src/features/{domain}- 你只要看到 URL 前缀
/posts,就知道「去features/posts找」
想象你的路由是森林,每个业务域是一棵树;路由文件、API、Query hooks 都长在同一棵树上,找问题和扩展功能都会更快。
1 / 4