关于 remix-v2-routing-review
用于审查 Remix v2 路由代码的 Agent Skill,面向检查 `app/routes/` 与根路由模块的开发者。它结合路由命名、布局、资源路由和迁移适配器等上下文规则,减少误报。
主要功能
- 01检查路由文件命名与路径段
- 02检查布局与 Outlet 用法
- 03检查资源路由导出和链接
- 04检查 v1 遗留模式与导入
- 05按版本和上下文应用规则
适用场景
- 01审查 Remix v2 路由变更
- 02排查嵌套路由布局问题
- 03检查资源路由的链接方式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ existential-birds/ beagle --skill remix-v2-routing-review安装后在 Claude Code 中输入/remix-v2-routing-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/layouts-outlets.mdresource-routes.mdroot-shell.mdroute-files.mdv1-holdovers.md详细介绍
Remix v2 路由代码审查
由 review-remix-v2(总入口)加载,用于标记 app/routes/ 模块中的路由反模式。规范模式请参阅 remix-v2-routing。
快速参考
| 问题类型 | 参考 |
|---|---|
文件名问题(index.tsx、__auth、转义错误、非路由文件) | references/route-files.md |
缺少 <Outlet />、孤立的点分隔片段、重复的布局逻辑 | references/layouts-outlets.md |
资源路由使用默认导出、<Link> 未设置 reloadDocument、splat 参数 | references/resource-routes.md |
导入 react-router-dom、__double 文件夹、v1-adapter 回退 | references/v1-holdovers.md |
缺少 <Meta />/<Links />/<Scripts />/<ScrollRestoration />、Vite 与 Classic 模式下的 <LiveReload /> 区别、ErrorBoundary 根组件缺少文档外壳 | references/root-shell.md |
范围
此技能会标记以下问题:
app/routes/下的文件(文件名、导出、导入、JSX 结构)app/root.tsx(文档外壳、根<Outlet />)remix.config.js(会更改路由发现的配置项:routes()、ignoredRouteFiles、@remix-run/v1-route-convention)- 链接到资源路由的任何模块(
<Link>用法)
不在范围内:loader/action 数据约定(由 remix-v2-data-flow-review 检查)、表单行为(由 remix-v2-forms-review 检查)、meta/headers(由 remix-v2-meta-sessions-review 检查)。
审查清单
- 索引路由应命名为
_index.tsx,而非index.tsx - 无路径布局使用单下划线(
_auth.tsx),而非双下划线(__auth/) - 点分隔的子路由(
users.profile.tsx)应有父模块,或使用尾随下划线(users_.profile.tsx) - 父路由模块应渲染
<Outlet /> - Splat 片段应读取
params["*"],绝不能读取params.splat/params.rest - 字面句点/特殊字符应使用方括号转义(
sitemap[.]xml.tsx) - 资源路由不得有
default导出 - 指向资源路由的
<Link>应使用reloadDocument(或改用普通<a>) - 导入应来自
@remix-run/react,而非react-router-dom - 非路由文件(CSS、辅助文件、测试)应放在包含
route.tsx的文件夹中,或列入ignoredRouteFiles - 仅当确实存在要跳过的父布局时,才使用尾随下划线退出布局
- 可选片段
($lang)应在 loader 中缩窄params.lang的类型(参见 references/route-files.md)
有效模式(不要标记)
- 没有 default 导出的资源路由——这正是将其作为资源路由的约定。绝不要标记。
- 任何以
_开头且没有<Outlet />的无路径布局文件,只要该模块有意作为仅渲染固定 UI 的包装器。请检查子项确认:如果不存在*.{segment}.tsx同级文件,这种仅作包装器的结构就是有意为之。 - URL 中不可见的
_前缀文件——无路径布局和_index本来就应从 URL 中隐藏。 - 在
remix.config.js中配置了@remix-run/v1-route-convention——这是合法的迁移适配器,本身不是问题。只有在未安装适配器的情况下出现 v1 风格文件时才标记。 useLoaderData<typeof loader>()——这是类型注解,不是类型断言。- Splat 路由使用方括号语法访问
params["*"]——这是唯一正确的访问方式。 - 包含
route.tsx以及同级.server.ts、.css、组件文件的app/routes/dashboard/文件夹——这是文档所述的就近放置模式。 - 存在同级
concerts.tsx布局时使用尾随下划线(concerts_.mine.tsx),且该 URL 有意跳过此布局。
上下文相关规则
只有在适用的具体上下文中,才标记以下问题:
| 问题 | 仅当以下条件成立时标记 |
|---|---|
app/routes/ 下的 index.tsx | 项目为 v2,且 remix.config.js 中未接入 @remix-run/v1-route-convention |
未包含 <Outlet /> 的父模块 | app/routes/ 中存在同级的点号子路由(parent.*.tsx) |
__double 双下划线文件夹 | 未安装 v1 约定适配器 |
| 以下划线结尾的路由段 | 不存在对应的父布局(没有可退出的布局) |
| 返回非 HTML 内容的模块使用默认导出 | loader/action 实际返回原始 Response(PDF、JSON、RSS) |
指向资源路由的 <Link> | 目标路由没有 default 导出,且 <Link> 未使用 reloadDocument |
硬性关卡(撰写问题报告前)
按顺序执行。在以下各项都通过之前,不要起草面向用户的问题报告;这些关卡适用于你即将报告的这一批问题。
-
位置证据 — 通过条件: 每个问题都列出仓库路径(
app/routes/下的文件或remix.config.js),并提供行号范围或你读取的文件中的简短原文引用。仅凭文件名判断的问题必须引用实际文件名。 -
豁免检查 — 通过条件: 对每个问题,用一行说明为何它不属于 有效模式(不要标记) 的豁免范围。标记资源路由问题时,必须提供明确证据,证明存在
default导出或<Link>未使用reloadDocument。 -
版本检查 — 通过条件: 确认项目使用 Remix v2(检查
package.json中是否有@remix-run/react^2,或检查app/routes/的其他位置是否存在 v2 扁平路由文件名)。如果remix.config.js中接入了@remix-run/v1-route-convention,则 v1 文件名(__auth/、index.tsx)是有意为之的——不要将其标记为问题。 -
协议 — 通过条件: 按照 review-verification-protocol 完成本次审查的审查前验证清单。
何时加载参考资料
- 审查
app/routes/下的文件名 → references/route-files.md - 审查父模块和共享界面元素 → references/layouts-outlets.md
- 审查返回非 HTML 内容的模块,或指向此类模块的任何
<Link>→ references/resource-routes.md - 审查看起来像 v1 的导入或文件名 → references/v1-holdovers.md
- 审查
app/root.tsx(文档外壳、<Meta />/<Links />/<Scripts />/<ScrollRestoration />、Vite 与 Classic Compiler 下的<LiveReload />、根ErrorBoundary)→ references/root-shell.md
审查问题
- 每个父路由是否都渲染了
<Outlet />,或者它是否是有意设计的纯包装器? - 文件名是否符合 v2 语法(无路径段使用单个
_,索引使用_index,转义使用[...])? - 资源路由是否没有
default导出,且所有指向它们的<Link>是否都使用了reloadDocument? - 所有路由器导入是否都来自
@remix-run/react(服务器端辅助函数是否来自@remix-run/node)? - 如果存在 v1 文件名,是否接入了
@remix-run/v1-route-convention,还是这些文件名是意外遗留的?
补充文档
- 路由文件命名问题:references/route-files.md —
index.tsx、__double文件夹、错误的转义语法、点号与下划线混淆、app/routes/下的非路由文件。 - 布局和 outlet:references/layouts-outlets.md — 无路径段布局误用、缺少
<Outlet />、无父路由的点号子路由、重复的布局逻辑。 - 资源路由:references/resource-routes.md — 意外的默认导出、未使用
reloadDocument的<Link>、splatparams["*"]访问。 - v1 遗留项:references/v1-holdovers.md —
react-router-dom导入、__auth文件夹、@remix-run/v1-route-convention是有意使用还是意外遗留的判断依据。