Understand-Anything 的 Next.js 框架附录:文件角色表、边缘模式与框架自动检测机制
【免费下载链接】Understand-AnythingGraphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.项目地址: https://gitcode.com/GitHub_Trending/un/Understand-Anything
本文以 Understand-Anything 仓库中的 Next.js 框架附录 为核心,完整解读这份框架专属提示词(Framework Addendum)的设计:它如何定义 Next.js 项目的标准文件角色、需要捕捉的边缘模式(Edge Patterns)、六层架构划分,以及写入languageLesson的关键模式;并结合仓库源码,说明该附录何时被检测、何时被注入到file-analyzer与architecture-analyzer的提示词中。读完后你可以掌握这套"检测 → 注入 → 分析"的完整链路,并能参照它为自己的技术栈编写同类附录。
一、Framework Addendum 是什么:一份只能"追加"、不能独立的提示词片段
nextjs.md的文件头明确声明了它的使用方式:
Injected into file-analyzer and architecture-analyzer prompts when Next.js is detected. Do NOT use as a standalone prompt — always appended to the base prompt template.
也就是说,它不是一份可独立运行的提示词,而是一份条件注入的附录:只有当 Understand-Anything 分析的项目被检测出使用了 Next.js 时,它的全文才会被追加到基础分析模板之后。这一机制在 SKILL.md 的"Framework addendum injection"步骤中有明确定义:
对 Phase 1(项目扫描阶段)检测出的每个框架(例如
Django),读取./frameworks/<framework-id-lowercase>.md(例如./frameworks/django.md)并将其全文内容追加在语言上下文之后;若该框架对应的文件不存在,则静默跳过并继续。
同一 SKILL.md 中还规定了注入顺序:先追加语言上下文(./languages/<language-id>.md),再追加框架附录,最后(在输出语言非英文时)追加本地化指引。框架附录文件就存放在skills/understand/目录下与 SKILL.md 同级的frameworks/子目录中。
被注入的两个分析代理分别是:
- file-analyzer.md:负责逐批读取源文件,通过"结构提取脚本 + LLM 语义分析"两阶段流程生成知识图谱的节点(nodes)与边(edges)。附录中的文件角色表和边缘模式主要服务于它——比如如何给
app/api/**/route.ts打api-handler标签、如何为布局嵌套创建contains边; - architecture-analyzer.md:负责识别 3–10 个逻辑架构层,并把每个文件节点恰好分配到其中一层。附录中的架构层定义直接约束它的层划分。该代理要求层 ID 统一使用
layer:<kebab-case>格式,且输出 JSON 中每层必须包含id、name、description、nodeIds四个字段——这与附录中给出的layer:ui、layer:api等 ID 完全对齐。
二、Next.js 是如何被检测出来的
附录注入的前提是"检测到 Next.js"。仓库中这条检测链路由三个文件构成:
1. 框架配置:nextjs.ts
export const nextjsConfig = { id: "nextjs", displayName: "Next.js", languages: ["typescript", "javascript"], detectionKeywords: ["\"next\":", "@next/font", "@next/image"], manifestFiles: ["package.json"], promptSnippetPath: "./frameworks/nextjs.md", entryPoints: [ "src/app/layout.tsx", "pages/_app.tsx", "src/pages/_app.tsx", ], layerHints: { app: "ui", pages: "ui", api: "api", components: "ui", lib: "service", middleware: "middleware", }, } satisfies FrameworkConfig;各字段的作用:
| 字段 | 取值 | 含义 |
|---|---|---|
id/displayName | nextjs/Next.js | 注册表主键与展示名;附录文件名由id小写化而来(./frameworks/nextjs.md) |
languages | typescript,javascript | 该框架关联的语言 ID,用于按语言反查框架 |
detectionKeywords | "next":、@next/font、@next/image | 在清单文件内容中做大小写不敏感的关键词匹配 |
manifestFiles | package.json | 只在这类清单文件中查找关键词(支持任意子目录下的同名文件) |
promptSnippetPath | ./frameworks/nextjs.md | 指向要注入的附录文件,即本文主体 |
entryPoints | src/app/layout.tsx等 3 项 | 覆盖 App Router(app/layout.tsx)与 Pages Router(pages/_app.tsx)两套入口约定 |
layerHints | 6 组目录 → 层映射 | 顶层目录名到架构层的提示:app/pages/components归ui,api归api,lib归service,middleware归middleware |
该配置随其他 9 个内置框架(Django、FastAPI、Flask、React、Express、Vue、Spring、Rails、Gin)一起注册进 builtinFrameworkConfigs。字段合法性由 Zod 模式 FrameworkConfigSchema 强制校验:languages、detectionKeywords、manifestFiles、promptSnippetPath均必填且非空,entryPoints与layerHints可选。
2. 检测算法:framework-registry.ts
FrameworkRegistry维护两个索引——byId(按框架 ID)与byLanguage(按语言 ID,一个语言可对应多个框架)。核心的detectFrameworks(manifests)方法逻辑是:
- 遍历注册表中的每个框架配置;
- 对该配置的每个
manifestFile,在传入的"文件名 → 文件内容"映射中做文件名基名匹配(精确相等或路径以/<manifestFile>结尾,因此子包目录下的package.json也能命中); - 将匹配到的内容转小写,检查任一
detectionKeyword是否出现;命中即返回该框架,且同一框架只会被记录一次。
这套算法有对应的测试佐证(framework-registry.test.ts):从requirements.txt检测 Django、从package.json检测 React、检测大小写不敏感、重复清单不产生重复结果、空清单返回空数组。测试还验证了createDefault()恰好注册 10 个内置框架,以及同一框架配置重复注册不会造成重复。FrameworkConfigSchema的专项测试(config-schema.test.ts)则断言了"每个内置框架的promptSnippetPath都必须非空",并会拒绝空字符串——保证每个被检测出的框架都有可注入的附录路径。
3. 触发点
Phase 1 的项目扫描(见 project-scanner.md 与 scan-project.mjs)产出frameworks结论后,SKILL.md 的提示词组装步骤便依据检测结论读取./frameworks/nextjs.md并追加进两个分析代理的提示词。
三、Canonical File Roles:标准文件角色表
附录的第一部分是分析 Next.js 项目时的"标准文件角色"约定——它在基础分析规则之上追加,告诉分析代理每种 Next.js 约定文件应该被理解成什么角色、打上哪些标签。完整继承原表如下:
| 文件 / 模式 | 角色 | 标签(Tags) |
|---|---|---|
app/layout.tsx | 根布局——包裹所有页面,定义 HTML 外壳与全局 Provider | entry-point,config,ui |
app/page.tsx | 根页面组件——渲染在/ | ui,routing |
app/**/page.tsx | 路由页面组件——文件路径决定 URL | ui,routing |
app/**/layout.tsx | 嵌套布局——以共享 UI 包裹子路由 | ui,config |
app/**/loading.tsx | 加载 UI——路由切换期间作为 Suspense 回退显示 | ui |
app/**/error.tsx | 错误边界——捕获路由段内的错误 | ui |
app/**/not-found.tsx | 404 UI——调用notFound()时显示 | ui |
app/api/**/route.ts | API 路由处理器——无服务器端点函数(GET、POST 等) | api-handler |
middleware.ts | 边缘中间件——在请求到达路由前拦截 | middleware |
lib/*.ts、lib/**/*.ts | 共享的服务端工具、数据访问与业务逻辑 | service |
components/*.tsx、components/**/*.tsx | 可复用 UI 组件 | ui |
next.config.js、next.config.mjs、next.config.ts | Next.js 配置——重定向、重写、环境变量、webpack 覆盖 | config |
actions/*.ts、app/**/actions.ts | Server Actions——可从客户端调用的服务端变更函数 | service,api-handler |
这些标签并非凭空而来,而是与 file-analyzer.md 中定义的通用标签体系(entry-point、api-handler、middleware、service、config等)一一对应。file-analyzer 要求每个文件节点携带 3–5 个小写连字符标签,附录则把"通用标签库"收窄为"Next.js 语境下的正确用法":例如app/layout.tsx之所以同时是entry-point和config,正因为它既包裹全应用又定义 HTML 外壳——这与框架配置中entryPoints首选src/app/layout.tsx的设定互为印证。
四、Edge Patterns to Look For:五种需要捕捉的边缘模式
第二部分指导分析代理在 Next.js 项目中额外创建哪些边(Edge 是图谱中节点间关系的表示,类型与权重由 file-analyzer.md 的边类型表统一定义)。附录列出五个 Next.js 特有的模式:
1. Layout nesting(布局嵌套)
当app/foo/layout.tsx同时包裹app/foo/page.tsx与app/foo/bar/page.tsx时,应从布局指向它所包裹的页面创建contains边。布局通过文件系统层级自底向上组合。
2. API route handlers(API 路由处理器)
当route.ts文件导出命名函数(GET、POST、PUT、DELETE)时,应基于 fetch 调用,从消费它的组件或 Server Action 指向该路由处理器创建边。
3. Server/Client component boundary(服务端/客户端组件边界)
文件顶部带"use client"指令的是 Client Component;app/目录中其余组件默认是 Server Component。凡跨越这条边界的depends_on边都要显式创建,并在边描述中标注"这里发生了渲染边界跨越"——这是 Next.js App Router 项目中最容易被普通 import 分析遗漏的关系。
4. Parallel routes(并行路由)
当出现app/@slot/page.tsx这类模式时,应从父布局指向每个并行插槽创建contains边;这些插槽在同一布局内同时渲染。
5. Route groups(路由组)
用括号包裹的目录(group)只用于组织路由,不影响 URL 路径;分析时应把这一点记入节点描述(description),避免下游读者误以为(group)会出现在 URL 中。
这五条模式覆盖了 App Router 的五类结构性事实(嵌套组合、端点消费、渲染边界、并行渲染、纯组织性目录),每条都给出了明确的"何时创建、创建什么类型、指向哪里"的判定规则,可直接作为 file-analyzer 语义分析阶段的补充指令执行。
五、Architectural Layers:Next.js 的六层划分
第三部分规定"检测到 Next.js 时,把节点分配到以下层":
| 层 ID | 层名 | 归属内容 |
|---|---|---|
layer:ui | UI Layer | app/**/page.tsx、app/**/layout.tsx、components/、loading/error 边界 |
layer:api | API Layer | app/api/**/route.ts、API 路由处理器 |
layer:service | Service Layer | lib/、Server Actions、数据获取工具 |
layer:middleware | Middleware Layer | middleware.ts、边缘函数 |
layer:config | Config Layer | next.config.*、根布局、tailwind.config.*、环境配置 |
layer:test | Test Layer | __tests__/、*.test.tsx、*.spec.tsx、e2e/ |
这套层定义与两处源码约定相互咬合:
- ID 格式:architecture-analyzer.md 要求层 ID 统一为
layer:<kebab-case>,附录给出的六个 ID 完全符合; - 层数约束:同一代理要求整个项目产出 3–10 个层且每个文件恰好归入一层,Next.js 附录给出的 6 层正好落在该区间,可以直接作为大模型的"推荐答案骨架";
- 目录提示:nextjs.ts 中的
layerHints(app/pages/components→ui,api→api,lib→service,middleware→middleware)是附录层表的"程序化缩影"——前者给确定性脚本用,后者给 LLM 语义分析用,两者对顶层目录的归属判断保持一致。architecture-analyzer 的两阶段流程(先跑结构分析脚本计算目录分组、组间导入频率、模式匹配,再做语义分层)中,lib被脚本归入service模式、middleware归入middleware模式的规则,与layerHints和附录层表三方一致。
值得注意的是分层中的两个设计取舍:根布局app/layout.tsx被划入layer:config而非layer:ui(呼应角色表中它携带config标签的定位——它更像应用外壳声明);Server Actions 划入layer:service(呼应角色表中service+api-handler双标签,强调其"服务端变更函数"属性而非纯 UI 属性)。
六、Notable Patterns to Capture in languageLesson:五条值得写进知识图谱的教学要点
第四部分要求把以下模式写入languageLesson(面向读者的语言/框架教学注记):
- Server Components by default(默认服务端组件):
app/目录中的组件都是 Server Components——除非声明"use client",否则不会有任何 JavaScript 发送到客户端; - Server Actions for mutations(用 Server Actions 做变更操作):标记
"use server"的函数可以直接被客户端组件调用,替代传统 API 路由来承担表单提交与数据变更; - App Router file conventions(App Router 文件约定):特殊文件(
page、layout、loading、error、not-found、route)通过"命名即行为"的文件系统路由约定定义各自行为; - ISR and static generation(ISR 与静态生成):
generateStaticParams在构建时预渲染页面,revalidation 策略控制缓存新鲜度; - Parallel and intercepting routes(并行路由与拦截路由):
@slot目录实现并行渲染;(.)前缀目录实现路由拦截,常用于模态框(modal)模式。
languageLesson在 Understand-Anything 的下游产物中有明确落点:tour-builder.md 允许每个导览步骤携带可选的languageLesson字符串("仅当确实有教学价值时添加"),knowledge-graph-guide.md 同样把languageLesson列为步骤的可选字段。附录这五条模式恰好给出了"什么才算有教学价值"的 Next.js 具体答案——它们是框架级概念而非文件级细节,适合作为导览步骤的旁注,帮助不熟悉 Next.js 的读者理解图中节点的语义。
七、把三者串起来:一条 Next.js 项目的分析链路
综合以上证据,一个 Next.js 项目在 Understand-Anything 中的完整处理链路是:
- 检测:项目扫描读取
package.json,FrameworkRegistry.detectFrameworks以关键词("next":等)命中 nextjsConfig,产出frameworks: ["Next.js"]; - 注入:按 SKILL.md 的注入顺序,nextjs.md 全文被追加到 file-analyzer 与 architecture-analyzer 的提示词尾部(此前还追加了
languages/typescript.md等语言上下文); - 分析:file-analyzer 依据"文件角色表"给
app/api/**/route.ts打api-handler标签、依据"边缘模式"创建布局contains边与跨 Server/Client 边界的depends_on边;architecture-analyzer 依据"层表"与 nextjs.ts 的layerHints把节点划分进 6 层,输出符合layer:<kebab-case>格式的 JSON 层数组; - 教学:tour-builder 等下游代理把附录指定的五条模式写入导览步骤的
languageLesson,让交互式知识图谱"教人"而不只是"展示"。
八、小结与参照价值
nextjs.md篇幅不长,却示范了 Understand-Anything 框架附录的完整范式:一个可检测的框架配置(nextjs.ts)+ 一份只追加不独立的提示词附录(nextjs.md)+ 清晰的注入时机(SKILL.md)+ 与下游代理输出契约(层 ID 格式、标签体系、languageLesson字段)的逐一对齐。其三大内容块——文件角色表解决"节点是什么"、边缘模式解决"节点之间有什么关系"、层划分解决"节点属于哪一层"——分别对应知识图谱的节点属性、边语义与架构视图三个维度。若你希望让这套分析流程理解自己的技术栈,可参照packages/core/src/languages/frameworks/下的既有配置新增一个FrameworkConfig,并在skills/understand/frameworks/下提供同名附录;FrameworkConfigSchema会强制保证必填字段完整,config-schema.test.ts 中的"所有内置框架 promptSnippetPath 非空"断言则是这一约定最直接的回归保障。
【免费下载链接】Understand-AnythingGraphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.项目地址: https://gitcode.com/GitHub_Trending/un/Understand-Anything
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考