关于 expo-project-structure
expo-project-structure 为尚无既定目录结构的新 Expo 应用提供布局指南,说明如何组织路由、可复用 UI、屏幕、服务器代码、平台专属文件、测试和配置;不要求迁移现有项目。
主要功能
- 01将应用代码放在 src/ 下
- 02让 src/app/ 仅包含路由
- 03组织可复用组件与屏幕
- 04分离服务器路由和辅助代码
- 05平台专属文件的组织指南
- 06样式与测试就近放置建议
适用场景
- 01搭建新的 Expo 应用结构
- 02决定路由和屏幕代码的存放位置
- 03组织 API 路由与服务器辅助代码
- 04安排平台变体文件和测试
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ expo/ skills --skill expo-project-structure安装后在 Claude Code 中输入/expo-project-structure确认已加载。
附带文件agents/openai.yaml
详细介绍
Expo 项目结构
适用于全新 Expo 应用的起始骨架——尚未提交文件夹结构的应用。
仅适用于新项目。 如果应用已有布局,请遵循现有约定,并将文件留在原处——这只是一个起始默认方案,绝不是需要强制采用或迁移到的标准。如果不确定项目是否为新项目,请先询问,再移动任何内容。
根据以下规则整理出的完整布局:
├── assets/
├── scripts/
├── src/
│ ├── app/ # Expo Router routes ONLY — every file is a route
│ │ ├── api/ # server API routes, grouped here
│ │ │ ├── user+api.ts
│ │ │ └── settings+api.ts
│ │ ├── _layout.tsx
│ │ ├── _layout.web.tsx # platform-specific layout
│ │ ├── index.tsx
│ │ └── settings.tsx
│ ├── components/ # reusable UI: button, card, table…
│ │ ├── table/ # complex component → folder + index.tsx
│ │ │ ├── cell.tsx
│ │ │ └── index.tsx
│ │ ├── bar-chart.tsx
│ │ ├── bar-chart.web.tsx # platform-specific variant
│ │ └── button.tsx
│ ├── screens/ # screen bodies that route files render
│ │ ├── home/
│ │ │ ├── card.tsx # used only by Home — not shared
│ │ │ └── index.tsx # rendered by src/app/index.tsx
│ │ └── settings.tsx
│ ├── server/ # server-only helpers used by app/api
│ │ ├── auth.ts
│ │ └── db.ts
│ ├── utils/ # standalone helpers + colocated tests
│ │ ├── format-date.ts
│ │ └── format-date.test.ts
│ ├── hooks/ # reusable hooks: use-theme.ts…
│ ├── constants.ts
│ └── theme.ts
├── app.json
├── eas.json
└── package.json
src/ 和 src/app
将应用代码放在 src/ 下,与配置文件分开。Expo Router 开箱即支持 app/ 和 src/app/——要切换,只需移动文件夹并重启打包程序。默认模板会在 tsconfig.json 中将 @/* 别名指向 ./src/*。
src/app 仅用于路由:其中的每个文件都会成为路由,因此不能放入其他内容。以下所有内容都放在同级文件夹中。
components/ — 可复用 UI
通用、可复用的 UI(按钮、卡片、表格),每个文件仅包含一个具名导出。文件名使用 kebab-case(bar-chart.tsx),与默认的 create-expo-app 模板保持一致。当组件变得复杂时,为其创建独立文件夹,将根文件放在 index.tsx 中,并将其私有子组件就近放置在旁边——导入路径(@/components/table)保持不变。
screens/ — 屏幕主体
由于 app/ 中的文件必须是路由,复杂且不可复用的屏幕 UI 无法放在那里。一旦屏幕变得足够复杂,需要拆分为独立组件,就将其放到 screens/ 中,并让每个路由只负责渲染对应屏幕:
import { Home } from "@/screens/home";
export default function HomeScreen() {
// route-specific concerns only — e.g. read url params here
return <Home />;
}
将屏幕的私有组件就近放置在其文件夹中(screens/home/components/)。额外好处是:同一屏幕可以在多个路由下渲染。
server/ + app/api/ — 分离服务端代码
在 app/ 中的文件名后添加 +api,即可将其设为服务端 API 路由。服务端代码不同于前端代码——它运行在类似 Node 的服务端环境中(通过 EAS Hosting 或第三方服务部署),并且可以读取机密环境变量(process.env.X,而不仅仅是 EXPO_PUBLIC_*)。将其分开放置:
- 将所有路由归入
app/api/→/api/user、/api/settings。这样可以将它们集中放置,并避免冲突(例如/user屏幕和/user路由)。 - 将共用的仅服务端辅助代码放在
src/server/中。 - 可以考虑使用 ESLint 规则,将
+api文件和server/与仅适用于前端的检查隔离开来。
平台特定代码
较小的差异:使用 Platform.select / Platform.OS。较大的差异则拆分为平台文件,而不是写内联 if/else——bar-chart.tsx + bar-chart.web.tsx,导入时省略扩展名(@/components/bar-chart);Metro 会根据目标平台选取正确的文件。
- 各变体的 Props 必须相同。
- 始终需要一个默认文件(不带平台扩展名)——如果组件只适用于单个平台,则将其设为空操作。
- 支持的扩展名:
.ios、.android、.native、.web。
将样式和测试就近放置
- 样式: 将
StyleSheet.create({ ... })对象放在组件文件底部,而不是单独放在.styles文件中。 - 测试: 将
format-date.test.ts放在format-date.ts旁边(优先于单独的__tests__/文件夹),方便一眼看出哪些文件经过了测试。
AI 和配置文件
Agent 指令放在仓库根目录——AGENTS.md / CLAUDE.md,项目技能放在 .claude/ 下。其他配置和资源放在 src/ 之外:app.json / app.config.ts、eas.json、package.json、assets/ 和 scripts/。
本文基于 Kadi Kraman 撰写的 Expo 应用文件夹结构最佳实践。有关 src/ 优先级和别名机制,请参阅 Expo 文档。
提交反馈
如果你发现此技能中存在错误、误导性信息或过时信息,请提交报告,以便 Expo 改进:
npx --yes @expo/agent-cli@latest feedback --category skills --subject "expo-project-structure" "<actionable feedback>"
只有在有具体且可执行的内容需要报告时才提交。请尽可能提供相关背景信息。
如果 Agent 反复无法完成 Expo 任务,或用户不得不介入,请使用 --category evals,并将相关的 Expo 包或命令作为 --subject,简要报告任务、预期结果以及出现的问题。