首页
/ Strapi 源码仓库指南:从 CLAUDE.md 读懂 Strapi Monorepo 的架构、开发流程与测试体系

Strapi 源码仓库指南:从 CLAUDE.md 读懂 Strapi Monorepo 的架构、开发流程与测试体系

2026-09-03 15:27:23作者:郜逊炳

Strapi 开源仓库根目录下的 CLAUDE.md 只有一行内容 @AGENTS.md,它把真正的指南指向了 AGENTS.md。这份"Agent 指南"是理解 Strapi 代码库最精炼的入口:它概括了 Yarn workspaces + Nx 驱动的 monorepo 组织方式、Strapi 类的生命周期与依赖注入模型、Document Service 与内容类型的核心机制,以及完整的开发、构建、测试与质量门禁命令。读完本文,你能独立完成仓库初始化、跑起开发沙箱、按分层策略运行各类测试,并理解从 PR 提交到 CI 校验的完整质量链路。

仓库基本约定与目录结构

指南开篇给出三条硬性约定,这也是所有贡献者(包括 AI Agent)必须先知道的:

  • 技术栈为 Yarn workspaces + Nx monorepo,运行环境要求 Node ≥22 ≤26、Yarn 4;
  • 目标分支是 develop(不是 main),所有 PR 都必须指向 develop
  • 仓库结构按职责划分为若干顶层目录:
packages/core/       # 框架本体: strapi, admin, database, content-manager, types, utils…
packages/plugins/    # 官方插件: users-permissions, i18n, graphql, documentation…
packages/providers/  # 邮件与上传 provider 实现
packages/utils/      # 共享工具: logger, eslint-config, tsconfig, vitest-config
packages/cli/        # CLI 工具: create-strapi-app, cloud-cli
examples/            # 仅用于开发的沙箱 — 不发布、不用于生产修复
docs/                # 贡献者文档
tests/               # 集成、E2E 与 CLI 测试基础设施

指南列出的核心包及其职责(非穷举,可用 yarn workspaces list 查看完整集合):

职责
@strapi/strapi 主框架入口(Koa 服务器)
@strapi/admin React 18 管理后台
@strapi/core 核心业务逻辑
@strapi/database 数据库抽象层(MySQL、PostgreSQL、MariaDB、SQLite)
@strapi/content-manager 内容管理 UI
@strapi/types 共享 TypeScript 类型定义
@strapi/permissions RBAC 权限引擎
@strapi/plugin-users-permissions JWT 认证

一个容易被忽略的细节是 skills 目录机制.ai/skills/ 是仓库内唯一被提交(committed)的技能源,每个含 SKILL.md 的子目录即为一个技能;而 .agents/skills/.claude/skills/.cursor/skills/ 三个目录是 AI 工具链的"well-known locations",它们只是由 yarn ai:sync 维护的符号链接目标。对应实现在 scripts/ai-tooling/index.ts,在根 package.json 中可以看到三个脚本的定义:

yarn ai:sync    # 幂等 —— 在三个工具目录中创建/清理 .ai 链接
yarn ai:unlink  # 仅移除 .ai 来源的链接(保留 brain 链接)
yarn ai:status  # 只读报告: linked / missing / conflict / stale

注意链接仅在本地生效(目标目录被 gitignore),只有 .ai/skills/ 的内容会被提交。指南还特别提示:在 Windows 上 CLI 会创建目录 junction(无需额外配置),而创建目录符号链接则需要开启开发者模式或使用提权 shell。

核心架构:Strapi 类、双入口与 Document Service

AGENTS 指南的 Architecture 一节是整个仓库的架构浓缩,值得逐条对照源码理解。

Strapi 类:DI 容器与生命周期

Strapi 类既是依赖注入容器也是整个系统的中枢。在 packages/core/core/src/Strapi.ts 中可以确认其定义为 class Strapi extends Container implements Core.Strapi,并依次实现了 start()load()register()bootstrap()destroy() 等异步方法,与指南描述的生命周期 Register → Bootstrap → Start → Destroy 对应——其中 start() 内部会调用 load()load() 再串联执行 register 与 bootstrap。

指南强调的依赖注入模式:strapi 实例通过工厂模式注入(例如 createService(strapi)),严禁使用 global.strapi,应始终通过 DI 获取 strapi.documentsstrapi.dbstrapi.log 等能力。

Server / Admin 双入口

Koa.js HTTP 服务器(@strapi/strapi)与 React/Redux 管理端(@strapi/admin)是两套独立关注点。凡同时包含两者的包都导出双入口:strapi-server(Node.js 逻辑)与 strapi-admin(UI 组件)。插件体系同理——插件通过相同的 strapi-server / strapi-admin 双结构注册路由、控制器、服务、内容类型与中间件,官方插件统一放在 packages/plugins/ 下。

Document Service 与内容类型

  • Document Servicestrapi.documents)是读写内容的首选高层 API,取代了已弃用的 Entity Service。指南明确:除正在 @strapi/database 内部工作外,永远不要写裸 DB 查询。
  • 内容类型采用基于 JSON 的记法(并非 JSON Schema 规范),每个内容类型有一个 schema.json,数据库层会据此自动生成表结构——因此也绝不手写针对内容类型变更的 raw migration。
  • 多态(morph*)关系的存储与查询机制(getDeepPopulate、关系遍历如何与 morphToOne 及 join-based morph 交互)在 AGENTS.md 中指向了 docs/docs/01-core/database/01-relations/ 下的贡献者文档,可作为进阶阅读。

此外还有两点设计约束:部分功能属于企业版(EE),在运行时按开关门控(对应下文测试章节的 IS_EE / RUN_EE 环境变量);@strapi/types 是共享类型的唯一事实来源,应扩展它而不是在本地重复定义。

仓库初始化与本地开发

首次搭建

# 克隆后执行一次
yarn install
yarn setup        # clean + 构建全部包;若链接缺失会提示执行 ai:sync
yarn ai:sync      # 将 .ai/skills 链接到 .agents/ .claude/ .cursor/

对照根 package.jsonsetup 脚本的实际定义为 yarn && yarn clean && yarn build --skip-nx-cache && tsx scripts/ai-tooling/post-setup.ts,即"安装 → 清理 → 全量构建 → 收尾检查"四步。指南还给出了 git worktree 场景的引导流程:新建 worktree 后检查 .claude/skills/git-conventions 是否能解析到仓库的 .ai/skills/git-conventions,若链接缺失或过期则运行 yarn setup:worktree(即 yarn install && yarn build && yarn ai:sync)。

开发沙箱与数据库

指南推荐的开发方式是在 examples/getstarted 沙箱中运行:

# 运行开发沙箱
cd examples/getstarted
yarn develop                  # 默认 SQLite

# 启动非内存数据库 (postgres/mysql)
docker-compose -f docker-compose.dev.yml up -d
DB=postgres yarn develop      # PostgreSQL
DB=mysql yarn develop         # MySQL

# 两个终端: 监听全部包 + 带 admin watch 的沙箱
yarn watch                                          # 终端 1, 仓库根目录
cd examples/getstarted && yarn develop --watch-admin # 终端 2

根目录的 docker-compose.dev.yml 即用于本地拉起 PostgreSQL/MySQL 实例。yarn watch 对应 package.json 中的 nx watch --all -- 'nx run-many --targets build:code,build:types --projects $NX_PROJECT_NAME',即监听所有包变更并增量重建。

构建与测试体系

构建

yarn build              # 全部包(代码 + 类型)
yarn build:code         # 更快 —— 跳过 .d.ts 生成
yarn nx build @strapi/admin   # 单个包

package.json 中的实现印证了这一分层:build 通过 nx run-many --targets build:code,build:types 同时构建代码与类型,build:code 只跑前者,故更快。

单元测试(最快,优先运行)

单测文件位于各包内部的 __tests__/ 子目录:

yarn test:unit
yarn test:unit:watch
yarn test:unit:update         # 更新快照

前端测试(管理后台)

前端测试同样在各包的 __tests__/ 中,关键是 EE 门控开关

yarn test:front              # 以 IS_EE=true 运行(启用 EE 功能)
yarn test:front:ce           # 以 IS_EE=false 运行(仅社区版)
yarn test:front:update       # 更新快照(EE)
yarn test:front:update:ce    # 更新快照(CE)

在 package.json 中可以看到 test:front 的定义为 cross-env IS_EE=true nx run-many --target=test:front ...,即通过环境变量在构建测试时就注入企业版特性,这正是架构一节所说"EE 功能在运行时门控"在测试层的体现。

类型检查

yarn test:ts                 # 全部包 + 前端 + 后端

API 集成测试

集成测试位于 tests/api/。指南特别提醒:测试应用是自动生成的,务必用 yarn test:generate-app 重新生成,不要复用旧的(过期应用会导致误导性失败)。

yarn test:api                # SQLite
yarn test:api --db=postgres
yarn test:api --db=mysql
yarn test:api -u             # 更新快照

CLI 测试与 E2E 测试

CLI 测试位于 tests/cli/

yarn test:cli
yarn test:cli:debug          # 带调试输出
yarn test:cli:update         # 更新快照

E2E 测试基于 Playwright,位于 tests/e2e/tests/,按领域(admincontent-manageri18n 等)组织:

yarn playwright install                          # 一次性安装浏览器
yarn test:e2e --setup --concurrency=1            # 顺序运行全部领域
yarn test:e2e --domains content-manager admin    # 只运行指定领域
yarn test:e2e --concurrency=3                    # 3 个领域并行

其入口脚本是 tests/scripts/run-e2e-tests.js,package.json 中还有 test:e2e:ce / test:e2e:ee 变体(通过 STRAPI_E2E_EDITION 切换版本),与指南提到的 RUN_EE=true(在 E2E 中启用企业特性)开关配套。

Pre-PR 检查清单

合入前必须至少通过以下组合:

yarn test:unit && yarn test:front && yarn test:ts && yarn lint && yarn prettier:check

E2E(yarn test:e2e)按 CONTRIBUTING.md 要求是必须的但较慢,CI 会在每个 PR 上强制执行。指南还给出了"何时加测试"的判断标准:bug 修复必须(先复现 bug 再写测试);功能开发只测试有意义的行为,不为了凑覆盖率;修改现有行为时同步更新受影响的测试。

质量门禁:提交规范、TypeScript 与格式化

Conventional Commits

提交必须遵循 Conventional Commits 规范,由 Husky 的 commit-msg 钩子与 CI 的 commitlint 双重强制:

<type>(<optional-scope>): <description>

合法 type 包括:featfixchorecidocsenhancementtestrevertsecurityfuturerelease。指南给出的示例:

feat(content-manager): add bulk delete action
fix(database): preserve relation order during publish
chore(admin): migrate data-fetching to react-query

交互式提交用 yarn commit;只要动过任何 package.json,就要跑 yarn version:check(其实现为 node scripts/check-package-versions.mjs && syncpack lint,校验各包版本一致性)。

TypeScript 与格式化规则

  • 类型一律从 @strapi/types 导入,优先扩展它而不是本地重复;
  • 存在或可合理定义类型时禁止 any,否则优先 unknown;推送前跑 yarn test:ts
  • 格式化命令:
yarn lint           # 全仓 ESLint
yarn lint:fix       # 自动修复
yarn format         # Prettier (2 空格缩进, 单引号, 分号, 尾逗号, 箭头参数括号, 100 字符宽, LF)
yarn prettier:check # 仅检查

安全红线与 PR 规范

指南的 Security 一节是五条不可妥协的红线:

  1. 绝不提交密钥、凭据或 API key;
  2. 绝不禁用或弱化认证/授权检查;
  3. 使用参数化查询——绝不把用户输入插值进裸 SQL 或数据库查询;
  4. 在 controller/service 边界验证并清洗所有用户输入;
  5. 处理 EE 门控功能时不得绕过 license 检查。

PR 规范要求:从 develop 拉分支、目标 develop——永不碰 main;描述中关联所修复的 issue;所有测试通过;PR 描述必须遵循 .github/PULL_REQUEST_TEMPLATE.md 模板,不得自造章节。

给 Agent(与贡献者)的补充说明

AGENTS.md 最后的 "Notes for Agents" 给出了四条对自动化 Agent 尤为重要的仓库潜规则,人工贡献者同样适用:

  1. examples/ 只是沙箱——仅用于复现与验证修复,除非被明确要求,不要向其中提交改动。例外examples/complex迁移测试夹具(schema、种子数据、validate-migration.js、DB 工具),CI 通过 tests/migration/migration_v5 运行迁移校验,它未来可能迁入 tests/migration/
  2. workspace 依赖使用锁定 semver——packages/ 内部包之间互相引用时用的是固定版本号(如 "5.42.0"),而非 workspace:*;后者仅用于 examples/ 应用和部分根 devDependencies。
  3. Entity Service 已弃用——内容操作一律使用 Document Service(strapi.documents)。
  4. 生命周期约束——访问任何服务前 strapi.isLoaded 必须为 true;插件与数据库在 load() 阶段完成前不可用。

小结

CLAUDE.mdAGENTS.md 虽名为 Agent 指南,实则是 Strapi monorepo 的架构速写与工程手册:它用不到 300 行文字回答了"这个仓库怎么组织(packages 分层 + 双入口 + 生命周期)、怎么跑起来(setup/develop 命令)、怎么验证(单测→前端→类型→集成→CLI→E2E 的分层测试)、怎么合入(Conventional Commits + 质量门禁)"四个核心问题。结合 packages/core/core/src/Strapi.ts 中的生命周期实现与根 package.json 中的脚本定义对照阅读,可以从指南进一步下沉到具体源码,这也是理解 Strapi 框架源码的最高效路径。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
980
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384