SuperAPI AI 工具集

file-organization-v1

编程与开发

查看项目

更新于 10-27 16:22

技能介绍

用途

该技能用于规范 TypeScript ESM 项目中相关实现文件的组织方式,核心是“文件夹加索引”的分组策略。它帮助开发者判断何时应将文件放入文件夹、何时使用 index.ts 作为公共 API、如何命名入口文件,以及需要避免哪些反模式。

适用范围包括:应用与包内相关实现文件的分组、index.ts 公共 API 设计、导入路径、文件夹命名。不覆盖:Next.js lucide 风格包导入优化、Fastify 路由结构、Drizzle schema 设计。

前提假设

  • TypeScript ESM,导入说明符使用 .js 扩展名
  • 目录名使用 kebab-case
  • 应用本地分组索引使用具名再导出;包子路径在文件夹是已发布模块边界时可以使用 export *

主要原则

  • 一个文件夹用于分组同一关注点的 2 个及以上实现文件
  • 当所有导出共享同一运行时,index.ts 是该分组的公共 API
  • 在文件夹内部去掉文件夹名前缀(oauth-google.ts → oauth/google.ts)
  • 文件夹外部导入分组(.../feature/index.js);文件夹内部直接导入同级文件
  • 单文件模块保持为文件;测试与实现放在一起
  • 混合运行时 → 使用带具名入口文件的文件夹,不设统一索引

约束

必须:

  • 使用 kebab-case 文件夹名
  • 在应用本地分组索引中使用具名再导出(避免 export * 巨型 barrel)
  • 创建文件夹前解决基名冲突(auth.ts 与 auth/)

禁止:

  • 添加父级巨型 barrel(lib/index.ts、components/ui/index.ts)
  • 创建 foo/foo.ts 加一个薄再导出索引
  • 在 Fastify 自动加载树(routes/、plugins/)中添加 index.ts
  • 当服务端与客户端模块使用不同运行时时,将其统一到一个索引中

应当:

  • 保持分组索引小而内聚(一个功能域)
  • 当再导出会造成导入循环时,使用具名入口文件
  • 优先使用已有的包子路径,而非新建根 barrel

与其他技能的交互

  • 与 next-v16 互补(barrel 导入优化 ≠ 功能分组索引)
  • 与 typescript-v6 互补(ESM 路径、具名导出)
  • 当仓库规则指定例外时(catalogs mapper、Drizzle schema index),仓库规则优先于本技能

模式示例

分组索引(同一运行时):

oauth/ shared.ts google.ts index.ts # 仅具名再导出

消费者:import { getOAuthAllowedCallbackUrls } from '../lib/oauth/index.js'

拆分运行时(无统一索引):

logger/ server.ts client.ts

无 index.ts

消费者直接导入具名入口文件(logger/server、logger/client)。

具名入口(避免循环):

catalogs/ index.ts # 仅字典 mapper.ts # 从 ./index.js 导入——不再导出

反模式

  • 单层前缀汤:难以导航;应使用文件夹
  • lib/index.ts 再导出一切:巨型 barrel;拖慢构建并模糊边界
  • auth.ts 与 auth/ 并存:模块解析陷阱
  • 用 cookies + document 统一索引:破坏服务端/客户端边界